栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

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

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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算法资讯。

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342101.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号