0

I am trying to detect edges on a welding image. On one side of the image i can easily detect the edge by using simple thresholding in open cv with the threshold value that matched in this area, but this threshold value is too low for the other side. Is it possible to distinguish between grayscale value and therefore use different threshold to detect the edges?

original picture

wanted edges

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

def region_of_interest(img, vertices):
    mask = np.zeros_like(img)
    #channel_count = img.shape[2] # for RGB image
    match_mask_color = (255,) # * channel_count # only if you want RGB image
    cv.fillPoly(mask, vertices, match_mask_color)
    masked_img = cv.bitwise_and(img, mask)
    return masked_img


path = "resources/weld_6.PNG"
img = cv.imread(path)
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

start_x = 615
end_x = 900
start_y = 510
end_y = 560

gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
img_blur = cv.GaussianBlur(gray_img, (5, 5), 8)

roi_test = region_of_interest(img_blur,
                              np.array([region_of_interest_vertices], np.int32))

canny_img = cv.Canny(roi_test, 10, 35)

ret, img_binary1 = cv.threshold(roi_test, 225, 255, 0)

img_cropped = img_binary1[530:540, 625:890]
img_canny = cv.Canny(img_cropped, 150, 200)

# Sum down the columns
columnTotals = np.sum(img_canny, axis=0)

# Now look for non-zero (non-black) entries
nz = np.nonzero(columnTotals)

# Now get left and right edges of white parts of image
left, right = nz[0][0], nz[0][-1]

the last part gives me the leftmost white pixel and the rightmost one and with the difference I am be able to detect the distance between the edges.

  • Apply kmeans filtering with n=3 or 4 or 5 to delineate your region. – fmw42 Sep 15 '20 at 17:14
  • This would help to detect the edges on both sides? – Thomas Müller Sep 15 '20 at 19:46
  • It might from the contour of the appropriate color region using cv2.inRange(). – fmw42 Sep 15 '20 at 20:13
  • You could also just use cv2.inRange() without the kmeans. inRange allows both lower and upper threshold values. – fmw42 Sep 15 '20 at 21:07
  • Check out the [tutorial for thresholding](https://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html). It has most of the important techniques in there. In your call to `cv.threshold`, the second parameter set to 255 is very high and should probably be quite a bit lower (maybe 180?). You can preview simple thresholding in a photo edit program (like [The Gimp](https://www.gimp.org/)) – bfris Sep 16 '20 at 03:17
  • Can you explain in simple words what distinguishes these particular edges from others ? There are several of them of similar contrast. –  Sep 16 '20 at 15:44
  • These shown edges are basically the edges of the weld bead, and by detecting these edges I would be able to detect the width of this weld bead. – Thomas Müller Sep 16 '20 at 16:37
  • @ThomasMüller: no, I mean when you look at the image, how do you know which ones to take ? Seen from here, your choice is random. –  Sep 16 '20 at 18:25
  • No, my choice is exactly under the electrode. Yes it seems randomly, but it should be the edges next to the electrode. – Thomas Müller Sep 17 '20 at 20:28

1 Answers1

0

Your question:

Is it possible to distinguish between grayscale value and therefore use different threshold to detect the edges

is not particularly clear.

In your particular image, it looks like your threshold value is 255,255,0 so you are looking for saturation in Red and Green channels.

Looking at your sample image you could use 200,200,200 to get both edges.

Techniquab
  • 843
  • 7
  • 22
  • Yes but if I convert it into a grayscale image I have on the right side of the region of interest a threshold value of 225 but on the left side a value of 240. But how would it look like if you convert the image into 200,200,200? – Thomas Müller Sep 15 '20 at 17:49