0

Hi I am a newbie in computer vision. I am working on crack detection on material surface using canny. Here, I will have to find out area occupied by cracks (pixels and mm), number of cracks, max crack area or length (pixels and mm), area of each crack and percentage of crack area in the following image. Original Image

I have used following code to detect the edges where I used cv2.dilate to fill the area inside the cracks.

image = cv2.imread('./crack_img.jpg')

image_height = image.shape[0]

image_width = image.shape[1]

resized_image_area = (image_height * image_width)

#Convert img to gray
img_gray  = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

img_blur = cv2.GaussianBlur(img_gray,(11,11),5)

edged = cv2.Canny(img_blur, 50, 200, 1)

kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (16, 16))

edged = cv2.morphologyEx((cv2.dilate(edged,kernel1,1)),cv2.MORPH_CLOSE, kernel1) # for bigger cracks

# or

kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))

edged = cv2.morphologyEx((cv2.dilate(edged,kernel2,1)),cv2.MORPH_CLOSE, kernel2) # for smaller cracks

# find contours

cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# loop over the contours individually to find largest contours
canny_contrd_area = []

for c in cnts:

    canny_area = cv2.contourArea(c)

    canny_contrd_area.append(canny_area)

    # print('Canny Contrd Area is:', canny_contrd_area)

if range(len(canny_contrd_area)) == 0:
 
    max_crack_length == 0 

elif range(len(canny_contrd_area)) != 0:

    max_crack_length =  int(max(canny_contrd_area, default=0))

print('Max Canny_Cont_Area is:', max_crack_length)

# find all the contours
canny_contrd_area = 0

for c in cnts:

    canny_contrd_area = cv2.contourArea(c) 

      if canny_contrd_area > 10:

         peri=cv2.arcLength(c,True)

         approx=cv2.approxPolyDP(c, 0.009 * peri, True)

         image_contours1= cv2.drawContours(image.copy(), cnts, -1, 
         (0,255,0), 2)

image_contours = cv2.drawContours(image, cnts, -1, (0,255,0), 3)
    
# calcualte the metrics to find ozone crack%
canny_number_of_cracks = len(cnts)

print('Canny Detected Cracks', canny_number_of_cracks)

canny_nonzero = round(cv2.countNonZero(edged),3)

canny_percent_area = round(((canny_nonzero)/(image_area))*100,3) 


cv2.putText(image, str(canny_number_of_cracks),(50,30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)

cv2.putText(image, str(canny_nonzero),(50,50),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)

cv2.putText(image, str("%s%%"%canny_percent_area),(50,70),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)

cv2.imshow('Edged', edged)

cv2.imshow('Final Image', image)

The problem is that if I use large kernel, then it fills up the big crack, but at the same time it includes the small crack as a part of a big crack as shown in the following image. Big Kernel extracting larger area

On the other hand, if I use small kernels, then it considers one big cracks as multiple cracks as it detects multiple edges as shown in the following image. Small Kernel extracting smaller area

I have looked into different sources and tried different image processing techniques, but it seems that the algorithm is not giving me accurate representation of number of cracks, area of each crack and max crack length because of the having both small and big cracks in the same image.

dpsm
  • 39
  • 5
  • @CrisLuengo done. – dpsm Sep 19 '22 at 15:11
  • @CrisLuengo could you please help? – dpsm Sep 19 '22 at 17:37
  • Edge detection is not the right tool to detect these cracks. The example image looks very binary, a simple threshold should give you the detection. If typical images are more difficult, you could use, for example, the Frangi Vesselness Filter. – Cris Luengo Sep 19 '22 at 19:45
  • If you want more help than that, post a representative image. – Cris Luengo Sep 19 '22 at 19:45
  • @Cris Luengo I have updated the images. – dpsm Sep 19 '22 at 21:56
  • Have you tried the [Stroke Width Transform (SWT)](https://stackoverflow.com/a/19971599/1714410)? it might be able to provide width information for the different cracks. – Shai Sep 20 '22 at 05:28
  • @Shai9 I have not tried SWT. As it is mostly used for text detection, I ma not sure if it not gonna beneficial for me. However, I found a similar problem here https://stackoverflow.com/questions/60643378/best-way-to-separate-rock-fragments-in-image. And it seems no one could give any concrete solution for that as well. – dpsm Sep 20 '22 at 15:24
  • What is a crack, what is not. Show a fully annotated image. –  Sep 20 '22 at 19:28
  • The SWT can be used for other purposes that text detection. It is a good suggestion. –  Oct 13 '22 at 14:28

0 Answers0