Opencv学习之查找并绘制轮廓

Opencv学习之查找并绘制轮廓

寻找轮廓–findContours函数

一个轮廓一般对应一系列的点,也就是图像中的一条曲线。
void findContours(inputArray,outputArray,outputArray hierarchy,int mode,int method, Point offset=Point())
*第一个参数,输入图像,需为8位单通道图像,可以使用compare()、inrange()、threshold()、adaptivethreshold()、canny()等函数由灰度图或彩色图创建二进制图像创建二进制图像。此函数会提取图像轮廓的同时修改图像的内容。
*第二个参数,每个轮廓存储为一个点向量,即用point类型的vector表示。
*第三个参数,可选的输出向量,包含图像的拓扑信息。其作为轮廓数量的表示,包含了许多元素。每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果没有对应项,对应的hierarchy[i]值设置为负数。
*第四个参数,轮廓检索模式。
(1)RETR_EXTERNAL:表示只检测最外层轮廓。对所有轮廓,设置hierarchy[i][2]=hierarchy[i][3]=-1。
(2)RETR_LIST:提取所有轮廓,并且放置在list中。检测的轮廓不建立等级关系。
(3)RETR_CCOMP:提取所有轮廓,并且将其组织为双层结构(two-level hierarchy:顶层为连通域的外围边界,次层为孔的内层边界)。
(4)RETR_TREE:提取所有轮廓,并重新建立网状的轮廓结构。
*第五个参数,轮廓的近似办法。
(1)CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2)),abs(y2-y1)==1
(2)CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息。
(3)CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS:使用Teh_Chinl链逼近算法中的一个。
*第六个参数,每个轮廓点的可选偏移量,默认值Point()。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数便可派上用场。

绘制轮廓–drawContours函数

void drawContours(inputoutputArray,inputArrayOfArray,int contourIdx,const Scalar& color,int thickness=1,int lineType=8,inputArray hierarchy=noArray(),int maxLevel=INT_MAX,Point offset=Point())
*第一个参数,目标图像。
*第二个参数,所有的输入轮廓,每个轮廓存储为一个点向量,即用point类型的vector表示。
*第三个参数,轮廓绘制的指示变量。如果其为负值,则绘制所有轮廓。
*第四个参数,轮廓的颜色。
*第五个参数,轮廓线条的粗细度,有默认值1.如果其为负值(如thickness=cv_filled),便会绘制在轮廓的内部。可选为CV_FILLED宏。
*第六个参数,线条的类型,默认值为8。
(1)8:8连通型
(2)4:4连通型
(3)LINE_AA/CV_AA:抗锯齿线型
*第七个参数,可选的层次结构信息,默认值noArray()。
*第八个参数,表示用于绘制轮廓的最大等级,默认值INT_MAX。
*第九个参数,可选的轮廓偏移参数,用指定的偏移量offset=(dx,dy)偏移需要绘制的轮廓,有默认值Point()。

#include
#include
#include

using namespace cv;
using namespace std;

//全局变量声明
Mat g_srcImage,g_grayImage,g_cannyOutput;
int g_nThresh=80;
int g_nThresh_max=255;
vector<vector>g_vContours;//轮廓
vectorg_vHierarchy;//层次结构信息
RNG  g_rng(12345);

//全局函数声明
void on_ThreshChange(int ,void *);

//主函数
int main()
{
    //载入源图像
    g_srcImage=imread("/Users/new/Desktop/3.jpg");
    if(!g_srcImage.data){printf("读取源图像srcImage错误~!\n");return false;}

    //转成灰度并降噪(平滑)
    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
    blur(g_grayImage, g_grayImage, Size(3,3));

    //创建窗口和阈值滑动条并初始化
    namedWindow("image[origin]");
    imshow("image[origin]", g_srcImage);
    createTrackbar("threshold of canny", "image[origin]", &g_nThresh, g_nThresh_max,on_ThreshChange);
    on_ThreshChange(0, 0);

    waitKey(0);
    return 0;

}

//回调函数定义
void on_ThreshChange(int ,void *)
{
    //Canny算子进行边缘检测
    Canny(g_grayImage, g_cannyOutput, g_nThresh, g_nThresh*2,3);
    //寻找轮廓
    findContours(g_cannyOutput, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE,Point(0,0));
    //绘制轮廓
    Mat drwaing=Mat::zeros(g_cannyOutput.size(), CV_8UC3);
    for(int i=0;i0,255),g_rng.uniform(0, 255),g_rng.uniform(0, 255));
        drawContours(drwaing, g_vContours, i, color,2,8,g_vHierarchy,0,Point());

    }
    imshow("image[contours]",drwaing);

}

Opencv学习之查找并绘制轮廓_第1张图片
Opencv学习之查找并绘制轮廓_第2张图片
Opencv学习之查找并绘制轮廓_第3张图片

Opencv技巧

(1)灰度值阈值:srcimage=srcimage>119,srcimage取大于阈值119的那部分。
(2)RNG g_rng(12345):RNG rng((int)time(0)),RNG类用于生成随机类,next可以取出下一个随机数,uniform函数可以返回指定范围的随机数,gaussian函数返回一个高斯随机数,fill则用随机数填充矩阵。

你可能感兴趣的:(编程学习)