如何使用python3检测缺陷bean

时间:2017-05-28 09:05:38

标签: python opencv

normal bean sample

defect bean sample-1

我想判断豆是正常还是缺陷。 我试图使用Canny方法(寻找边缘)等等......但我失败了。 我只是用形状来解决它。(破碎的豆和未成形的豆......) 请给我一些解决它的想法。

对不起我的英语,这不是我的第一语言。

1 个答案:

答案 0 :(得分:1)

填补裂缝的最广泛使用的方法之一"在图像中是扩张侵蚀。简单地说,你制作二进制图像"成长"在边缘,所以裂缝被填满,然后你扭转过程并使其“收缩”#34;在边缘 - 但是,当裂缝已经填满时,图像中没有关于它们的信息,所以它们保持填充。也许,你可以使用它,然后看看你的原始图像和扩张后的图像之间的差异:如果几乎没有裂缝,几乎没有差别,如果有大量的裂缝,那么差别很大。

例如。让我们将图像转换为二进制黑白掩码:

def get_th_binary_mask(img):
    gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gs, 0, 255, cv2.THRESH_BINARY)
    mask = np.zeros(thresh.shape, np.uint8)
    mask[thresh == 255] = 0
    mask[thresh == 0] = 1
    return mask

现在,只需对矩阵的元素求和,它给出了白色像素的数量,扩张侵蚀,再次求和,减去总和:

def get_de_difference(binary_image):
    s_before = np.sum(binary_image)
    kernel = np.ones((17, 17), np.uint8)
    d = cv2.dilate(binary_image, kernel, 1)
    d = cv2.erode(d, kernel, 1)
    s_after = np.sum(d)
    return abs(s_after - s_before)

对于"好"它为72个像素提供了不同的,对于"坏"一个给它1158。

可以通过使用更复杂的阈值函数进一步改进,例如,基于Otsu和Grab cut:

def get_gc_binary_mask(img):
    gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gs, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    mask = np.zeros(thresh.shape, np.uint8)
    mask[thresh == 255] = cv2.GC_PR_BGD
    mask[thresh == 0] = cv2.GC_FGD

    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)

    cv2.grabCut(img, mask, (0, 0, 1365, 767), bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)

    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    return mask2

使用它而不是前一个只能为"好"提供1个像素差异。豆子(尽管有一个不幸的神器 - 见下文),而对于"坏"它给了741.或者,如果你可以改变图片的背景,只需在那里放一些亮绿色/蓝色的纸张,然后再拍照并使用色度键控。

这是它的外观,从左到右:原始图像(第1列),基本阈值,扩张,侵蚀,otsu /抓取阈值,扩张,侵蚀。第2列和第4列之间以及第5列和第7列之间的区别是重要的。 enter image description here