如何使用传统图像处理方法进行石头检测

本文通过OpenCV库介绍了如何使用传统图像处理方法进行多石头检测和分割。步骤包括二值化、去燥、腐蚀、膨胀、查找轮廓以及面积过滤。通过这些操作,能够有效地分割出石头的轮廓,并通过面积过滤减少误检。最后,文章总结了这种方法的简单应用,并指出仍有优化空间。
摘要由CSDN通过智能技术生成

1 引言

最近有小伙伴咨询如何用传统方法进行多个石头检测分割算法, 原文如下所示:
在这里插入图片描述
嗯嗯,碰巧让我这个问题,然而我碰巧学过图像处理的一些简单知识.
我们都知道使用opencv可以快速进行图像的基本操作,那么我们就来尝试解决这个问题吧.

2 解决方法

2.1 二值化

传统图像分割,一般就是采用阈值分割的方法来区分前景物体和背景,这里使用全局阈值分割的方法来进行处理,方法如下:

img_file = "./sample.jpeg"
img1 = cv2.imread(img_file)
img  = cv2.resize(img1,(640,400))
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
retval, bin_img = cv2.threshold(gray_img, 120, 255, cv2.THRESH_BINARY )

运行后的效果如下:
请添加图片描述
上图中,左侧为原图,右侧为二值化后的结果图.

2.2 去燥

观测上图,可以发现二值化后的图像还有很多噪声,这里采用3X3中值滤波的方法进行去燥,代码如下:

img_median = cv2.medianBlur(bin_img, 3)

运行效果如下:
请添加图片描述
左侧为3X3去燥前的二值图,右侧为使用3X3模板去燥后的结果图,可以看出很多零散的孤立点都被滤除.

2.3 腐蚀

二值图像的腐蚀操作为将图像中的前景物体白色部分进行缩减细化,其运行结果图比原图的高亮区域更小,我们这里选用3X3的十字形kernel进行腐蚀操作.

代码如下:

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
erosion_img = cv2.erode(img_median, kernel, iterations=2)

结果如下:
请添加图片描述
上图中左侧为 iterations=1的腐蚀结果图,表示只进行1次腐蚀操作;右侧为iterations=2的腐蚀结果图,表示连续进行2次腐蚀操作. 可以看出经过腐蚀操作后,前景物体分割的更开了.

2.4 膨胀

图像膨胀是腐蚀操作的逆操作,类似于“领域扩张”,将图像中的高亮区域或白色部分进行扩张,其运行结果图比原图的高亮区域更大,线条变粗了.
我们观察腐蚀后的图像,发现很多区域内会有一些空洞点,这时我们需要膨胀操作,来消除这些空洞点,
代码如下:

dilatation_type = cv2.MORPH_ELLIPSE    
dilatation_size = 1
element = cv2.getStructuringElement(dilatation_type, 
           (2 * dilatation_size + 1, 2 * dilatation_size + 1),
           (dilatation_size, dilatation_size))
dilate_img = cv2.dilate(erosion_img, element,iterations=3)

运行结果如下:
请添加图片描述
上图为 采用3X3椭圆kernel进行3次膨胀后的结果图

2.5 查找轮廓

观察膨胀后的图像,可以看出石头已经被我们分成一个个连续的独立的封闭区域,这时我们可以使用opencv的findContours函数来寻找对应区域的外轮廓,代码如下:

contours, hierarchy = cv2.findContours(dilate_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
out_img = img.copy()
for contour in contours:
    cv2.drawContours(out_img, [contour, ], -1, (255 ,0, 255), 2)  # pink

结果如下:
请添加图片描述

2.6 面积过滤

观察上图,我们的输出会有一些错检,我们可以添加一些过滤条件,来进行过滤,有很多面积很小的区域被错分割出来,这里采用面积来滤除部分错检,代码如下:

for contour in contours:
    area = cv2.contourArea(contour)
    k = cv2.isContourConvex(contour)
    if  area>150:
        cv2.drawContours(img, [contour, ], -1, (0, 0, 255), 2)  # red

结果如下:
请添加图片描述

左侧为滤除前的结果图,右侧为使用面积过滤后的结果图.

3 总结

本文采用传统图像处理方法,对石头图像进行了简单图像处理,可以得到分割出来的多个石头的外轮廓和面积,最终效果如下:
请添加图片描述

虽然还有一些错检和漏检,但是本文主要用于探讨传统图像处理的一些常用方法,
上述方案仅供学习交流使用,如有更好的策略,欢迎随时交流.




关注公众号《AI算法之道》,获取更多AI算法资讯。
在这里插入图片描述

注: 关注公众号,后台回复 石头 , 可获取完整代码

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值