我想判断豆是正常还是缺陷。 我试图使用Canny方法(寻找边缘)等等......但我失败了。 我只是用形状来解决它。(破碎的豆和未成形的豆......) 请给我一些解决它的想法。
对不起我的英语,这不是我的第一语言。
答案 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列之间的区别是重要的。