查找一个轮廓一般对应一系列的点,也就是图像中的一条曲线。其表示方法可能根据不同的情况而有所不同。在OpenCV中,可以用findContours()函数从二值图像中查找轮廓
findContours()函数用于在二值图像中寻找轮廓。
C++: void findcontours (InputoutputArray image, OutputArrayofArrays contours, OutputArray hierarchy, int mode, int method, Pointoffset=Point ()
第一个参数, InputArray类型的image,输入图像,即源图像,填Mat类的对象即可,且需为8位单通道图像。图像的非零像素被视为1,0像素值被保留为0,所以图像为二进制。我们可以使用compare()、 inrange()、threshold(), adaptivethreshold()、 canny()等函数由灰度图或彩色图创建二进制图像。此函数会在提取图像轮廓的同时修改图像的内容。
第二个参数, OutputArrayOfArrays类型的contours、检测到的轮廓、函数调用后的运算结果存在这里。每个轮廓存储为一个点向量,即用point类型的vector表示。
第三个参数, OutputArray类型的hierarchy,可选的输出向量,包含图像的拓扑信息。其作为轮廓数量的表示,包含了许多元素。每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][ 0]~hierarchy[i][ 3],分别表示后个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果没有对应项,对应的hierarchy[j]值设置为负数。
第六个参数, Point类型的offset,每个轮廓点的可选偏移量,有默认值Point()。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数便可排上用场。
findContours经常与drawContours配合使用-使用用findContours()函数检测到图像的轮廓后,便可以用drawContours()函数将检测到的轮廓绘制出来。接下来,让我们一起看看drawContours()函数的用法。
drawContours()函数用于在图像中绘制外部或内部轮廓
C++: void drawContours (InputoutputArray image, InputArrayofArrays contours, int contourldx, const scalar& color, int thickness=1, int ineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Pointoffset=Point () )
第一个参数, InputArray类型的image, 目标图像,填Mat类的对象即可。
第二个参数, InputArrayOfArrays类型的contours,所有的输入轮廓。每个轮廓存储为一个点向量,即用point类型的vector表示。
第三个参数, int类型的contourldx,轮廓绘制的指示变量。如果其为负值,则绘制所有轮廓。
第四个参数, const Scalar&类型的color,轮廓的颜色。
第五个参数, int thickness,轮廓线条的粗细度,有默认值1,如果其为负值(如thickness= cv_filled),便会绘制在轮廓的内部。可选为FILLED宏
第七个参数, InputArray类型的hierarchy,可选的层次结构信息,有默认值noArray)
第八个参数, int类型的maxLevel,表示用于绘制轮廓的最大等级,有默认值INTMAX
第九个参数, Point类型的offset,可选的轮廓偏移参数,用指定的偏移量offset= (dx, dy)偏移需要绘制的轮廓,有默认值Point()。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
// 【1】载入原始图,且必须以二值图模式载入
Mat srcImage = imread("F:\\CV\\LearnCV\\files\\Zelda_Build.jpg",0);
imshow("原始图", srcImage);
//【2】初始化结果图
Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
//【3】srcImage取大于阈值119的那部分
srcImage = srcImage > 119;
imshow("取阈值后的原始图", srcImage);
//【4】定义轮廓和层次结构
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
//【5】查找轮廓
findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
// 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
int index = 0;
for (; index >= 0; index = hierarchy[index][0])
{
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
}
//【7】显示最后的轮廓图
imshow("轮廓图", dstImage);
waitKey(0);
}