基于OpenCV的混凝土裂纹检测
前言
这是我发的第一次博客,有什么建议大家可以给我留言,感激不尽!
接下来,我们进入正题。
一、使用函数库
numpy, opencv, heapq, skimage.morphology
二、使用步骤
1.初步预处理
初步预处理包括:灰度阈值处理,高斯滤波平滑处理,滤波除燥。代码如下:
import cv2
import numpy as np
Type = 0 # 阈值处理方式
Value = 0 # 使用的阈值
T = 0
V = 0
def onType(a):
Type = cv2.getTrackbarPos(tType, windowName)
Value = cv2.getTrackbarPos(tValue, windowName)
ret, dst = cv2.threshold(o, Value, 255, Type)
cv2.imshow(windowName, dst)
global T
T = Type
def onValue(a):
Type = cv2.getTrackbarPos(tType, windowName)
Value = cv2.getTrackbarPos(tValue, windowName)
ret, dst = cv2.threshold(o, Value, 255, Type)
cv2.imshow(windowName, dst)
global V
V = Value
o = cv2.imread(r'E:\database\CrackForest-dataset-master\image\001.jpg')
# 灰度转换
gray = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
# cv2.imshow('gray', gray)
windowName = 'output'
cv2.namedWindow(windowName)
cv2.imshow(windowName, gray)
# 构建滚动条
tType = 'Type'
tValue = 'tValue'
cv2.createTrackbar(tType, windowName, 0, 4, onType)
cv2.createTrackbar(tValue, windowName, 0, 255, onValue)
while 1:
k = 0xFF & cv2.waitKey(1)
if k == 27:
break
elif k == ord('s'):
realType = T
realValue = V
retval, img = cv2.threshold(gray, realValue, 255, realType)
cv2.imshow('output.jpg', img)
cv2.imwrite('output.jpg', img)
output = cv2.imread('E:/bishe/daima/output.jpg')
print(output.shape)
# 高斯滤波平滑处理
gauss = cv2.GaussianBlur(output, (3, 3), 0, 0)
# cv2.imshow('gauss',gauss)
# 滤波除噪
k = np.ones((5, 5), np.uint8)
_open = cv2.morphologyEx(gauss, cv2.MORPH_OPEN, k)
_close = cv2.morphologyEx(_open, cv2.MORPH_CLOSE, k)
cv2.imshow('_close', _close)
cv2.imwrite('output2.jpg', _close)
cv2.destroyAllWindows()
直接运行代码后,会出现一个窗口。拖动Type,Value滚动条,将图片进行阈值处理,其中Type是阈值处理方式,Value是阈值,如下图
原始图像:处理后(Type=1:处理方式为cv2.THRESH_BINARY_INV;Value=53:可以根据不同的照片自行调整参数,直到自己满意为止。)
2.提取最大连通域
代码如下:
import cv2
import numpy as np
import heapq
o = cv2.imread('E:/bishe/daima/output2.jpg')
gray = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('original', o)
n = len(contours)
area = []
for i in range(n):
area.append(cv2.contourArea(contours[i]))
max_num_index_list = map(area.index, heapq.nlargest(1, area))
Max = list(max_num_index_list)[0]
print(Max)
contoursImg = np.zeros(o.shape, np.uint8)
contoursImg = cv2.drawContours(contoursImg, contours, Max, (255, 255, 255), -1)
cv2.imshow('the crack', contoursImg)
cv2.imwrite('the crack.jpg', contoursImg)
cv2.waitKey()
cv2.destroyAllWindows()
效果如图:
3.提取裂纹骨架
代码如下:
import cv2
from skimage import morphology
import numpy as np
img = cv2.imread(r'E:\bishe\daima\the crack.jpg', 0)
kernel = np.ones((3, 3), np.uint8)
dilation = cv2.dilate(img, kernel)
cv2.imshow('dilation', dilation)
erosion = cv2.erode(dilation, kernel, iterations=4)
cv2.imshow('erosion',erosion)
dst = cv2.bitwise_not(erosion)
_, binary = cv2.threshold(dst, 100, 255, cv2.THRESH_BINARY_INV)
# cv2.imwrite("binary.png",binary)
binary[binary == 255] = 1
skeleton0 = morphology.skeletonize(binary)
skeleton = skeleton0.astype(np.uint8)*255
cv2.imshow('bone', skeleton)
cv2.imwrite('bone.jpg', skeleton)
cv2.waitKey()
cv2.destroyAllWindows()
效果如图:
总结
最后想说几句,为了更好的学习,所以来这里分享我的学习成果,更好地发现自己的不足之处,还希望看到这篇文章的大佬们有什么建议还请给我留言,感激不尽!!!