大家好,之前发过一篇文章是知识星球上问题,选择了几个经典的二值图像分析问题,从思路到代码实现给大家分析一波,最近又总结收录了知识星球上的提问,实现了从思路分析到代码实现的完整,下面我们就来看看这几个案例思路分析、运行效果、实现的相关API说明等。
No.1
案例一
需求:检测下图中三个圆
思路分析:
很多人看到这个图像的第一印象其实感觉就是可以用霍夫变换检测得到圆,如果你是这么想的,估计你应该很难做好,原因在于这个里面其实是有一系列的同心圆,而且图像梯度干扰非常厉害。我们的做法是,先通过边缘检测,得到最小的圆轮廓,也就是里面的白色的圆,然后通过轮廓拟合半径,结果非常好,然后对图像进行大半径的高斯模糊,这里我用的模糊半径=15,模糊之后再通过两次调用霍夫圆检测,每次给予不同的半径参数制约。要特别注意霍夫变换的最大与最小的半径两个参数设置。
最终代码实现运行如下:
No.2
案例二
需求:截取图像的ROI区域,去掉扫描文本的空白区域,截取ROI区域
思路分析:
主要是通过全局二值化结合图像形态学操作,实现ROI区域的提取,然后通过轮廓发现,绘制ROI区域的mask、得到mask之后。
最终代码实现运行如下:
No.3
案例三
需求:答题卡位置定位
思路分析:
图像二值分析,通过全局阈值化,得到二值图像,然后通过面积过滤得到无噪声与干扰的干净二值图像、通过形态学闭操作合并字符、然后再进行轮廓分析,最终定位得到每行、每列的有效信息准确位置BOX
最终代码实现运行如下:
No.4
案例四
需求:计算提取红色光线的中心位置
思路分析:
看到图像,提取红色区域首先想到是色彩空间转换,HSV色彩空间对红色区分度比较好,通过inRange函数得到mask区域,会发现中心有一个白色的洞、那个就是红色光线的中心,通过轮廓分析,拟合圆得到中心位置,计算坐标,即可得到光线的中心位置。
最终代码实现运行如下:
No.5
案例五
需求:寻找与获取最大的轮廓
思路分析:
看到图像,就知道是一个新手提问,其实做这步以后,只需要通过findContour之后对每个轮廓计算面积,然后得到面积最大的轮廓,即是要找的最大轮廓。代码实现如下:
代码语言:javascript复制import cv2 as cv
import numpy as np
src = cv.imread("D:/images/zsxq/zsxq_13.png")
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
m_max = -10000
mindex = -1;
for cnt in range(len(contours)):
area = cv.contourArea(contours[cnt])
if area > m_max:
m_max = area
mindex = cnt
cv.drawContours(src, contours, mindex, (0, 0, 255), 2, 8)
cv.imshow("find-max", src)
cv.imwrite("D:/find_max.png", src)
cv.waitKey(0)
cv.destroyAllWindows()
最终代码实现运行如下:
No.6
案例六
需求:找到这个线圈的外部轮廓与内部轮廓,特别是内部轮廓,明显有很多干扰,不是那么容易找到的。
思路分析:
图像质量比较好,这个时候有两个思路,一个是通过图像分割,得到背景,然后对前景mask做分析,找出外部与内部轮廓,第二个是直接二值化(二值化是最简单的图像分割)、然后通过形态学操作,对内部进行膨胀,得到内部区域,这个时候形态学操作选择闭操作、另外一个需要注意的最好先进行高斯模糊,需要很强的高斯模型,有利于去掉边缘不规则影响。
最终代码实现运行如下: