函数FindContours()从二值图像中寻找轮廓,其处理的图像可以是从Canny()函数得到有边缘像素的图像,或者是从Threshold()得到的图像,这时的边缘是正和负区域之间的边界。
函数及其参数说明:
findContours(
InputOutputArray binImg, //输入8bit图像(二值图像)
OutputArrayOfArrays contours, //输出找到的轮廓对象
OutputArray, hierachy // 图像的拓扑结构
int mode, //轮廓返回的模式(RETR_TREE等)
int method, //发现方法(CHAIN_APPROX_SIMPLE等)
Point offset=Point() //轮廓像素的位移(默认没有位移(0, 0))
)
(1)在输入图像中查找轮廓时,FindContours()函数会对输入图像进行修改,建议输入原图的拷贝图像。
(2)contours这个参数就是内存存储器,函数找到的轮廓就记录在此内存里。
(3) mode参数表面返回的轮廓的“连接方法”,
一个经常使用的功能是在屏幕上绘制检测到的轮廓。绘制可以使用drawContours()函数完成;
drawContours(
InputOutputArray binImg, // 输出图像
OutputArrayOfArrays contours, //找到的全部轮廓对象
Int contourIdx, //轮廓索引号
const Scalar & color, //绘制颜色
int thickness, //绘制线宽
int lineType, //线的类型(默认8)
InputArray hierarchy, //拓扑结构图
int maxlevel, //最大层数(0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓)
Point offset=Point(), //轮廓位移
预处理目的是为轮廓查找提供高质量的输入源图像。
预处理的主要步骤包括:
灰度化:使用cv::cvtColor()
图像去噪:使用高斯滤波cv::Gaussian()
二值化:使用cv::Threshold()
形态学处理:cv::morphologyEx()
其中灰度化可以将3通道图像转化为单通道图像,以便进行二值化门限分割;去噪可以有效剔除图像中的异常独立噪点;二值化是为轮廓查找函数提供单通道图像;形态学的某些处理通常可以剔除细小轮廓,联通断裂的轮廓。
实例:
Mat ImgA=imread("你的图片路径");
Mat ImgB=imread("你的图片路径");
Mat DisImg, DisImgGray, ImgGrayA, ImgGrayB;
Mat Thresh01;
absdiff(ImgA, ImgB, DisImg);
vector<vector<Point> > Contours;
vector<Vec4i> hierarchy;
cvtColor(DisImg, DisImgGray, CV_BGR2GRAY);
cvtColor(ImgA, ImgGrayA, CV_BGR2GRAY);
cvtColor(ImgB, ImgGrayB, CV_BGR2GRAY);
threshold(DisImgGray, Thresh01, 0, 255, CV_THRESH_OTSU);
namedWindow("example", (800, 600));
imshow("example", Thresh01);
findContours(Thresh01, Contours, hierarchy,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
for (int i = 0; i < Contours.size(); i++)
{
drawContours(ImgA, Contours,i,Scalar(255,0,0),4,8,hierarchy,0,Point(0,0));
}
namedWindow("example1", (800, 600));
imshow("example1", ImgA);
waitKey(0);
return 0;