OpenCV学习(63)
图像轮廓与图像分隔修复(1):查找并绘制轮廓
一,寻找轮廓: findContours()函数;
二,绘制轮廓: drawContours(函数;
三,基础示例程序:轮廓查找;
一,寻找轮廓: findContours()函数
第一个参数,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[i]值设置为负数。
第四个参数,int类型的mode,轮廓检索模式,取值如表8.1所示。
第五个参数,int类型的method,为轮廓的近似办法,取值如表8.2所示。
第六个参数,Point类型的 offset,每个轮廓点的可选偏移量,有默认值Point()。对 ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数便可排上用场。
findContours经常与drawContours配合使用—使用用findContours()函数检测到图像的轮廓后,便可以用drawContours()函数将检测到的轮廓绘制出来。接下来,让我们一起看看drawContours()函数的用法。
下面是一个调用小示例。
二,绘制轮廓: drawContours()函数
第一个参数,InputArray类型的image,目标图像,填Mat类的对象即可。
第二个参数,InputArrayOfArrays类型的contours,所有的输入轮廓。每个轮廓存储为一个点向量,即用point类型的vector表示。
第三个参数,int类型的contourIdx,轮廓绘制的指示变量。如果其为负值,则绘制所有轮廓。
第四个参数,const Scalar&类型的color,轮廓的颜色。
第五个参数,int thickness,轮廓线条的粗细度,有默认值1。如果其为负值(如 thickness= cv_filled),便会绘制在轮廓的内部。可选为FILLED宏(OpenCV2版为CV_FILLED)。
第六个参数,int 类型的 lineType,线条的类型,有默认值8。取值类型如表8.3所示。
第七个参数,InputArray类型的 hierarchy,可选的层次结构信息,有默认值noArray()。
第八个参数,int类型的 maxLevel,表示用于绘制轮廓的最大等级,有默认值INT_MAX
第九个参数,Point类型的offset,可选的轮廓偏移参数,用指定的偏移量offset= (dx,dy)偏移需要绘制的轮廓,有默认值Point().
三,基础示例程序:轮廓查找
代码如下:
#include <opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/utils/logger.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat srcImage, dstImage;
cv::utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);//控制台不在输出日志文件
//【1】载入原始图,且必须以二值图模式载入
srcImage = imread("E:/pictures/2.jpg", 0);
imshow("【原始图】", srcImage);
//【2】初始化结果图
dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
//【3】srcImage取大于阈值150的部分
srcImage = srcImage > 150;
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);
}
//显示最后的轮廓图
imshow("【轮廓图】", dstImage);
waitKey(0);
return 0;
}
运行结果: