# Using openCV python to detect concrete cracks

Could anyone have an idea how i can isolate just the cracks from the image of a concrete surface. My input image is something like this:

I am expecting my output to be something like this:

I have tried canny edge detector but that gives me a broken contour. I tried dilation followed by erosion but that increases the width of crack segment in the binary image and that will be a problem as the width should not be changed. I need a closed contour of the crack without change in width. Can anyone point me in the right direction ?

edit retag close merge delete

Sort by » oldest newest most voted

Hi,

an easy approach could be:

1) remove the inhomogeneous background illumination

apply a big gaussian bluring and substract the original image from the blured one.

2) Apply e.g. e Sobel edge detection and a morphological close

3) remove the noise using blob analysis (e.g. remove regions with small areas)

Best

Edit: In principle you have to convert the image between 0 and 1 before GaussianBlur. Additionally to get better results you also can apply a non-maximal suppression after sobel.

For a copy paste solution here we go:

import cv2
import math
import numpy as np
import scipy.ndimage

def orientated_non_max_suppression(mag, ang):
ang_quant = np.round(ang / (np.pi/4)) % 4
winE = np.array([[0, 0, 0],[1, 1, 1], [0, 0, 0]])
winSE = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
winS = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]])
winSW = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])

magE = non_max_suppression(mag, winE)
magSE = non_max_suppression(mag, winSE)
magS = non_max_suppression(mag, winS)
magSW = non_max_suppression(mag, winSW)

mag[ang_quant == 0] = magE[ang_quant == 0]
mag[ang_quant == 1] = magSE[ang_quant == 1]
mag[ang_quant == 2] = magS[ang_quant == 2]
mag[ang_quant == 3] = magSW[ang_quant == 3]
return mag

def non_max_suppression(data, win):
data_max = scipy.ndimage.filters.maximum_filter(data, footprint=win, mode='constant')
data_max[data != data_max] = 0
return data_max

# start calulcation
gray_image = cv2.imread(r'path ... ', 0)

with_nmsup = True #apply non-maximal suppression
fudgefactor = 1.3 #with this threshold you can play a little bit
sigma = 21 #for Gaussian Kernel
kernel = 2*math.ceil(2*sigma)+1 #Kernel size

gray_image = gray_image/255.0
blur = cv2.GaussianBlur(gray_image, (kernel, kernel), sigma)
gray_image = cv2.subtract(gray_image, blur)

# compute sobel response
sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)
mag = np.hypot(sobelx, sobely)
ang = np.arctan2(sobely, sobelx)

# threshold
threshold = 4 * fudgefactor * np.mean(mag)
mag[mag < threshold] = 0

#either get edges directly
if with_nmsup is False:
mag = cv2.normalize(mag, 0, 255, cv2.NORM_MINMAX)
kernel = np.ones((5,5),np.uint8)
result = cv2.morphologyEx(mag, cv2.MORPH_CLOSE, kernel)
cv2.imshow('im', result)
cv2.waitKey()

#or apply a non-maximal suppression
else:

# non-maximal suppression
mag = orientated_non_max_suppression(mag, ang)
mag[mag > 0] = 255
mag = mag.astype(np.uint8)

kernel = np.ones((5,5),np.uint8)
result = cv2.morphologyEx(mag, cv2.MORPH_CLOSE, kernel)

cv2.imshow('im', result)
cv2.waitKey()

more

I do not get the same crack width if i do this. My crack width is highly exaggerated after i apply the sobel operator. I need to have my crack width preserved.

My code:

blur = cv2.GaussianBlur(img, (75,75), 0)
sub = cv2.subtract(blur,img)
sobelx = cv2.Sobel(sub, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(sub, cv2.CV_64F, 0, 1, ksize=3)
outim = np.sqrt(sobelx ** 2 + sobely ** 2)
cv2.imshow('Output', outim)

( 2018-12-17 19:40:39 -0500 )edit

I am trying to implement crack detection using openCV and python. I followed this tutorial and I have been able to identify the crack. However, it also detects edges and adds to false positives.

The original image is: Original Image

and the crack identified is: link text

I need to subtract the edges and just keep the crack highlighted.

( 2019-05-13 14:48:11 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Seen: 3,543 times

Last updated: Dec 18 '18