这是一篇按步骤可以初步实现轮廓检测的OpenCV入门教程,自己总结用,写错的地方欢迎指正。
#include //图像解编码(读取、保存)
#include //图像处理模块
#include //GUI模块
string path;//图像路径
Mat img = imread(path);
//彩色图转换为灰度图
cvtColor(img, imgGray, COLOR_BGR2GRAY);
contour detection主要通过 findContours
和drawContours
函数实现。
findContours
函数定义(两个重载版本):void findContours(InputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
//overload
void findContours(InputArray image, OutputArrayOfArrays contours,
int mode, int method, Point offset = Point());
参数:
imgCanny (InputArray image)
:
输入图像应当是经过边缘检测处理的二值化图像,使用canny detector实现边缘检测如下:
//先将灰度图进行高斯模糊处理
GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0);//形参:输入图,输出图,核尺寸,x向sigma,y向sigma
//canny边缘检测
Canny(imgBlur, imgCanny, 25, 75);//25, 75是二值化阈值,一般来说阈值越小,边缘越突出
contours
:
contour可以看作图片中一个object的边缘上的点集合,图片上可能有多个object,因此contours
应当是一个包含点集的集合,故可以定义为:
vector> contours;
hierarchy
:
轮廓层级,理解可以参考一篇博文hierarchy轮廓层级详解,hierarchy可以定义为:
vector hierarchy;
mode
:
这里可以用RETR_EXTERNAL
(有些OpenCV版本里可能写作CV_RETR_EXTERNAL
),表示检测所有轮廓。
method
:
轮廓逼近方法:
CHAIN_APPROX_NONE//获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
CHAIN_APPROX_SIMPLE//压缩水平方向、垂直方向、对角线方向的元素,仅保留该方向的终点坐标
Point offset = Point()
:
轮廓偏移量,有默认参数。
findContours
函数定义void drawContours(InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );
image
:需要是三通道图像
contours
:同findContours
contourIdx
:需要绘制的contour索引,-1表示全部绘制
color
:颜色,Scalar(B, G, R)
thickness
:绘制contours线条的宽度
lineType
:绘制contours的线型(线的连通性),可以参考这篇博文的评论区lineType
hierarchy
:同findContours
maxLevel
:绘制轮廓的最大层级,若为0,则仅仅绘制指定的轮廓,若为1,则绘制该轮廓及其内嵌轮廓。
offset
:同findContours
至此已经可以绘制出图像中objects的轮廓,下次更新多边形逼近、通过面积筛选contours。