》》点赞,收藏+关注,理财&技术不迷路《《
目录:
14.1 轮廓发现介绍
轮廓发现基于二值图像,二值图像通过边缘提取(canny)来得到。
轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果。
我们通过阈值分割提取到图像中的目标物体后,我们就需要通过边缘检测来提取目标物体的轮廓,使用这两种方法基本能够确定物体的边缘或者前景。接下来,我们通常需要做的是拟合这些边缘的前景,如拟合出包含前景或者边缘像素点的最小外包矩形、圆、凸包等几何形状,为计算它们的面积或者模板匹配等操作打下坚实的基础。
操作步骤:
输入图像转为灰度图像
使用Canny进行边缘提取,得到二值图像
使用findContours寻找轮廓
使用drawContours绘制轮廓
14.2 API介绍与举例
相关API:
findContours发现轮廓
drawContours绘制轮廓
findContours( InputOutputArray image, OutputArrayOfArrays contours,OutputArray hierarchy, int mode,int method, Point offset=Point());
opencv2返回两个值:contours:hierarchy。注:opencv3会返回三个值,分别是img, countours, hierarchy
参数:
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
cv2.RETR_EXTERNAL表示只检测外轮廓
cv2.RETR_LIST检测的轮廓不建立等级关系
cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE建立一个等级树结构的轮廓。
第三个参数method为轮廓的近似办法
cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
返回值:
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
findcontours 可以接受两种图像,二值图像和梯度图像。所以看情况而定我们是用梯度还是二值,看看哪个效果更好
14.2.1 轮廓发现与降噪(梯度图像方法)
运行后会发现二值化图中有一些小的噪点(虽然难得看出来),但是在第三幅图中明显可以看出硬币中的噪点。
为了消除这些噪点,我们先用一个 3*3 的高斯模糊滑一下。
先通过高斯模糊后,可以看得出来噪点少了很多。
想完全除去硬币中噪点,可以换成EXTERNAL。
14.2.2 轮廓填充
14.2.3 二值化方法(canny)
所以说contours 可以用两种方法,梯度图像和二值化图像,明显在这个例子中梯度图像要优于二值化图像。
14.3 对象测量
我们找到了轮廓,然后我们怎么测量面积?弧长?周长?
图像计算出来的弧长和面积都是像素为单位的,需要换算一下变成度量单位。
数字里面 1 是最容易找到的。