前言
转载请注明本文出处。
最近一段时间一直在看粘连分割,网上也有很多demo,找了一个大米的图像做测试。以下是本篇文章正文内容,下面案例可供参考。
1.分割流程图
分割总流程图如下图所示:
2.图像预处理
图像预处理包括图像二值化+形态学运算。
2.1 改进二值化算法
此处二值化思想参考本博客上一篇文章《OTSU改进算法-python》,
输入原图:
输入图像水印已经去除,方便大家测试。
二值化对比:
1.直接采用二值化算法进行二值化,
_, mask = cv.threshold(image_gray, 115, 255, cv.THRESH_BINARY)
直接采用二值化效果图:
2.采用adaptive_otsu思想进行二值化,效果如下图所示:
可以看出二值化效果有了非常大的提升,为后续分割处理打下了基础。
2.2 形态学运算
此处采用3x3的核对图像开运算
kernel = np.ones((3, 3), np.uint8)
image_bin = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel)
3.提取轮廓
根据以上二值化的图像提取轮廓,如下图所示。
_, contours, hierarchy = cv.findContours(image_bin, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
根据以上轮廓,看出有多个大米粘连的情况,下面采用凸包检测。
4.凸包检测
凸包检测为了找到图中粘连的大米,从图中可以看出共有三处大米粘连,下图黄色框部分:
求取凸包数量:
for i in range(len(contours)):
cnt = contours[i]
hull = cv.convexHull(cnt, returnPoints=False)
此处给定阈值T1(阈值根据自己实际情况设定),判断凸包数量是否进入下一步,检测缺陷点。
if len(hull) > T1:
defects = cv.convexityDefects(cnt, hull)
如果defects数量>1符合条件将缺陷点连线,如下图所示:
cv.line(mask, defects_point[0], defects_point[1],0)
5.标记大米
消除粘连后画出所有轮廓外接矩,及中心点,最终结果如下图所示:
cv.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0)) # 绘制外接矩
cv.circle(image, (cx, cy), 1, (0, 0, 255), -1) # 用圆点绘制目标重心