轮廓
虽然Canny之类的边缘检测算法可以根据像素之间的差异检测出轮廓边界的像素,但是并没有将轮廓作为一个整体来处理
cv::findContours() 将边缘像素合成轮廓
轮廓查找
在opencv中,轮廓用标准模板库STL向量vector<>表示
轮廓层次
轮廓树,区分内部边界和外部边界,每条轮廓用四元数组表示
四个元素分别为:同级的下一条轮廓,同级的上一条轮廓,下级的第一条子节点,上级的父节点
使用cv::findContours()查找轮廓
轮廓提取方式:
cv::RETR_EXTERNAL 只检索最外层轮廓
cv::RETR_LIST 检索所有轮廓并保存在表(List中)
cv::RETR_CCOMP 检索所有的轮廓,并将它们组织成双层结构;顶层边界是所有成分的外部边界,第二层边界是孔的边界
cv::RETR_TREE 检索所有轮廓并重新建立网状轮廓结构(名为树实为网)
轮廓如何被表达:
cv::CHAIN_APPROX_NONE 将轮廓编码中的所有点转换为点,会产生大量的点
cv::CHAIN_APPROX_SIMPLE 压缩水平,垂直,斜的部分,只保留最后一个点,大大减少返回的点数
cv::CHAIN_APPROX_TC89_L1 or cv::CHAIN_APPROX_TC89_KCOC 使用Tec-Chin链逼近算法的一个,用于减少返回的点数
绘制轮廓
获取轮廓后,使用cv::drawContours()在屏幕上绘制检测到的轮廓
快速连通区域分析
采用阙值化等方法分割一张图像后,我们可以采用连通区域分析来有效对返回图像逐张分离和处理
opencv中的连通图像算法,要求输入时一张二值(黑白)图像,输出是一张像素标记图,其中属于同一连通区域的非零像素都是同一定值
先调用cv::findContours()函数再调用cv::drawContours() 这种方法很慢,要为轮廓创建vector,填充多条轮廓包围的区域需要排序
cv::connectedComponents() 和 cv::connectedComponentsWithStats() 代替上述复杂操作
cv::connectedComponents() 简单生成了标记图,cv::connectedComponentsWithStats() 也生成标记图,同时返回每块连通区域的一些重要信息,比如包围框,面积,质心等
深入分析轮廓
对轮廓的处理:描述轮廓,简化或拟合轮廓,匹配轮廓到模板等等
多边形逼近
使用多边形逼近一个轮廓,使顶点数变少
cv::approxPolyDP() 进行多边形逼近
Douglas-Peucker算法:首先从轮廓上挑出两个最远的点,将两点相连。然后再原来的轮廓上寻找一个离线短距离最远的点,将该点加入逼近后的轮廓中。然后进行迭代,找到原轮廓上离已有的点围成的多边形上最近一边距离最远的点,加入多边形
几何及特性概括
计算一些轮廓变化的概括特性,包括长度或其他一些反应轮廓整体大小的量度
另一个有用的特性是轮廓矩(contour moment)可以用来概括轮廓的总形状特性
用cv::arcLength() 获得长度
用cv::boundingRect() 获得矩形包围框
用cv::minAreaRect() 获得最小矩形框(包围)
用cv::minEnclosingCircle() 获得最小包围圆
用cv::fitEllipse() 获得椭圆边框(最佳拟合)
用cv::fitLine() 获得轮廓的最佳拟合线(直线)
用cv::convexHull() 获得图像的凸包
几何学测试
再处理外包围框或其他类型的轮廓多边形时,常需要做一些简单的几何学检测,如多边形重叠检测或外包围框重叠快速检测
用cv::pointPolygonTest() 检测点是否落在多边形内
用cv::isContourConvex() 测试轮廓是否为凸
匹配轮廓与图像
如何匹配多条轮廓
矩
比较两条轮廓最简洁的方法之一是比较他们的轮廓矩
用cv::moments()计算矩
再论矩
上述方法对形状相同但大小不同,或者存在相互位移或旋转的两条轮廓,会有不同的值
中心矩的位移不变性
归一化中心矩的缩放不变性
Hu不变矩的旋转不变性
Hu不变矩是归一化中心矩的线性组合。通过组合不同的归一化中心矩,可以得到一个反应图像不同特征的不变函数(不随尺度,旋转,镜面映射而变化)
用cv::HuMoments() 计算Hu不变矩
使用Hu矩进行匹配
使用Hu矩比较两个物体,并判定它们是否相似
cv::matchShapes()允许简单提供两个物体,然后计算他们的矩,根据我们提供的标准进行比较
利用形状场景方法比较轮廓(不太熟)
opencv 3中有一个专有模块shape,可以实现一些算法(形状场景算法)
形状模块的结构
形状模块围绕一个抽象概念cv::ShapeDistanceExtractor构成
仿函数:衡量形状之间差值的“距离”度量标准的函数
形状场景距离提取
cv::ShapeContextDistanceExtractor方法在函数实现中采用了形状变换和直方图代价提取仿函数