Python 基于OpenCV的裂纹检测前背景纹理模式去除

Python 基于OpenCV的裂纹检测前背景纹理模式去除,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,我想检测移动传送带上的裂缝。以下是一个例子: 对于上面的图像,我可以使用GaussianBlur和Canny,然后findContour来检测裂缝。然而,在其他情况下,我需要检测带重图案的皮带上的裂纹。例如,下面是没有裂缝的“重型”皮带。(很抱歉,我找不到这种皮带有裂缝的) 我的旧方法对这种皮带不太管用。如果我对GaussianBlur使用一个更大的内核,我可以删除皮带模式。但它也能减少/消除裂纹 更新:这里是另一个水滴型裂纹图像 我尝试用SimpleBlobDetector检测它。但在厚

我想检测移动传送带上的裂缝。以下是一个例子:

对于上面的图像,我可以使用GaussianBlur和Canny,然后findContour来检测裂缝。然而,在其他情况下,我需要检测带重图案的皮带上的裂纹。例如,下面是没有裂缝的“重型”皮带。(很抱歉,我找不到这种皮带有裂缝的)

我的旧方法对这种皮带不太管用。如果我对GaussianBlur使用一个更大的内核,我可以删除皮带模式。但它也能减少/消除裂纹

更新:这里是另一个水滴型裂纹图像

我尝试用SimpleBlobDetector检测它。但在厚重的花纹带上,它会给出很多假阳性。有没有关于如何检测图案腰带上的斑点的建议

更新2:

我遵循@Nathance关于双边过滤器的建议:

min_area = 400
blur = cv2.bilateralFilter(gray, 11, 125, 125)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,2)
canny = cv2.Canny(thresh, 120, 255, 1)
放大后的图像如下所示


对于这些特定的图片,我可以用“min_area=400”来区分裂缝和图案。然而,较大的内核模糊也会将部分裂缝连同图案一起擦掉。因此,我认为min_区域选择在更复杂的真实环境中(即不同的光照条件等)不会非常稳定。我有一个问题,因为模式总是+-45度。是否有任何过滤器可以帮助去除这些方向的图案

这里有一个潜在的解决方案

  • 将图像转换为灰度和中值模糊
  • 自适应阈值
  • Canny边缘检测
  • 去除噪声的形态学变换
  • 扩张以增强轮廓
  • 寻找轮廓
  • 迭代通过轮廓并使用最小阈值区域进行过滤

这是结果

一个潜在的预处理步骤是在检测裂缝之前去除暗部分,因为它会破坏中值模糊和自适应阈值。例如,如果您能够删除最后一张图像上的黑色部分,您将获得此结果

潜在的优化是使用中间模糊,因为这有助于平滑皮带上的图案。您还可以调整最小阈值区域以控制检测到的裂纹的大小

import cv2
import numpy as np

image = cv2.imread('1.png')

blur = cv2.medianBlur(image, 7)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,3)

canny = cv2.Canny(thresh, 120, 255, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
opening = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
dilate = cv2.dilate(opening, kernel, iterations=2)

cnts = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

min_area = 3000
for c in cnts:
    area = cv2.contourArea(c)
    if area > min_area:
        cv2.drawContours(image, [c], -1, (36, 255, 12), 2)

cv2.imshow('image', image)
cv2.imwrite('image.png', image)
cv2.waitKey(0)

裂缝是一条水平线,因此您可以使用梯度过滤器来查找水平图片,然后使用Hough变换来查找其上的所有线条,并使用最小的线条angle@lhgiang149谢谢你的快速回复。示例图片中的裂缝是水平的。然而,我想检测现实生活中所有可能的裂缝,可能是任何方向的。它在第一张和第三张图像(光图案带上的裂缝)上效果很好。但我在第二张图片上看到了类似的东西。请你解释一下如何去除第二张图像上的重图案好吗?你可以尝试增加模糊度或尝试其他模糊过滤器,比如保持边缘锐利。第二张图像很难显示,因为裂纹与图案混合在一起