【问题标题】:python opencv detect differences between images of products with surface defectspython opencv检测具有表面缺陷的产品图像之间的差异
【发布时间】:2021-08-03 13:41:49
【问题描述】:

我正在研究表面缺陷检测问题。 我有一种塑料材料,它可能有不同类型的缺陷:划痕、小破损、与物体颜色非常相似的斑点、黑点。 问题是我无法训练 ML 模型,因为有缺陷的产品太少了。

我曾考虑编写一个代码来查找 ok 和 ko 产品之间的差异,但我无法正确检测所有差异。例如,我找不到亮点。也许我的方法是错误的。您能告诉我检测这些缺陷的最佳方法是什么吗?

这是我尝试过的两个代码。对于这两个代码,我使用良好的图像和有缺陷的图像。在使用它们之前,我会扭曲它们以获得相同的尺寸和位置。 我还附上了两张示例图片。

CODE1

before = cv2.imread('img1.jpg')
after = cv2.imread('img2.jpg')

# Convert images to grayscale
before_gray = cv2.cvtColor(before, cv2.COLOR_BGR2GRAY)
after_gray = cv2.cvtColor(after, cv2.COLOR_BGR2GRAY)

# Compute SSIM between two images
(score, diff) = compare_ssim(before_gray, after_gray, full=True)
print("Image similarity", score)

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1] 
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")

# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

mask = np.zeros(before.shape, dtype='uint8')
filled_after = after.copy()

for c in contours:
    area = cv2.contourArea(c)
    if area > 40:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(before, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.rectangle(after, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.drawContours(mask, [c], 0, (0,255,0), -1)
        cv2.drawContours(filled_after, [c], 0, (0,255,0), -1)

代码 2

difference = cv2.subtract(img1, img_2)
plt.imshow(difference)
plt.show()

# color the mask red
Conv_hsv_Gray = cv2.cvtColor(difference, cv2.COLOR_BGR2GRAY)
plt.imshow(Conv_hsv_Gray)
plt.show()

# RGB_img1 = cv2.cvtColor(Conv_hsv_Gray,cv2.COLOR_BGR2RGB)
# plt.imshow(RGB_img1)
# plt.show()


ret, mask = cv2.threshold(Conv_hsv_Gray, 0, 255, cv2.THRESH_BINARY_INV |cv2.THRESH_OTSU)
print(ret)
print(mask)
plt.imshow(mask)
plt.show()
RGB_img1 = cv2.cvtColor(mask,cv2.COLOR_BGR2RGB)
plt.imshow(RGB_img1)
plt.show()


print(difference)
difference[mask != 255] = [0, 0, 255]
print(difference)
# add the red mask to the images to make the differences obvious
img1[mask != 255] = [0, 0, 255]
#img2[mask != 255] = [0, 0, 255]

【问题讨论】:

    标签: python python-3.x image opencv computer-vision


    【解决方案1】:

    一种可能的方法是在您的 OK 产品上训练一个模型,然后在检测时为检测百分比设置一个阈值

    【讨论】:

    • '对不起,我手头没有任何代码可以给你看,但你可以简单地对每个像素的偏差求和,然后对结果进行归一化,但这种方法会对环境(照明,对象到捕获的偏移量,...)第二种方法是通过深度学习(使用 tensorflow 的示例)并通过几个产品学习一个通用模型,然后使用在您的脚本中学习的这个模型结果很可能已经标准化。这种方法更复杂但更有效。
    • 好的。我对第二种方法很感兴趣。我以前使用过深度学习和 tensorflow,但是我不太明白仅在 OK 产品上训练模型是什么意思……你有什么网站/视频可以看吗?谢谢
    • 在tensorflow的github上有一个信息的金矿,在tensorflow hub上面我给你放了一些链接
    • 目标是让模型准备好重新训练。一旦模型被重新训练,就足以将其用于检测和处理结果的分数,
    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多