Opencv查找轮廓并绘制

版权声明:转载请注明文章出处,否则不得转载! https://blog.csdn.net/hanxiaoyong_/article/details/83309856

注意:转载请注明出处! 

图像处理中的边缘检测是根据像素间的差异检测出轮廓边缘的像素,但它没有将轮廓作为一个整体。将这些轮廓边缘像素组装成一个整体(轮廓),就要进行轮廓检测.opencv提供了轮廓检测的函数cvFindContours,函数参数如下:

 cvFindContours(CvArr *图像,CvMemStorage *存储,CvSeq ** first_contour,
                            int header_size CV_DEFAULT(sizeof(CvContour)),
                            int模式CV_DEFAULT(CV_RETR_LIST),
                            int方法CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
                            CvPoint偏移量CV_DEFAULT(cvPoint(0,0)) );

具体参数含义如下:

图片

8比特单通道的源二值图像。非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny

存储

返回轮廓的容器。

first_contour

输出参数,用于存储指向第一个外接轮廓。

header_size

header sequence列的尺寸。如果选择方法= CV_CHAIN_CODE,则header_size> = sizeof(CvChain);其他,则

header_size> = sizeof(CvContour)。

模式

CV_RETR_EXTERNAL:只检索最外面的轮廓;

CV_RETR_LIST:检索所有的轮廓,并将其放入列表中;

CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;

CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。

                                                                  

蓝色表示v_next,绿色表示h_next

方法

边缘近似方法(除了CV_RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)可取值如下:

CV_CHAIN_CODE:以弗里曼链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。

CV_CHAIN_APPROX_NONE:将所有的连码点,转换成点。

CV_CHAIN_APPROX_SIMPLE:压缩水平的,垂直的和斜的部分,也就是,函数只保留他们的终点部分。

CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用Teh-Chin链的味道近似算法

的一种。

CV_LINK_RUNS:通过连接水平段的1,使用完全不同的边缘提取算法使用CV_RETR_LIST检索模式能使用此方法。

抵消

偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。

绘制检测轮廓的函数为:

 cvDrawContours(CvArr * img,CvSeq * contour,
                             CvScalar external_color,CvScalar hole_color,
                             int max_level,int thickness CV_DEFAULT(1),
                             int line_type CV_DEFAULT(8),
                             CvPoint offset CV_DEFAULT(cvPoint(0,0)));

轮廓检测例子代码如下:

#include <cv.h>
#include <highgui.h>
using namespace cv;
using namespace std;
IplImage *g_image = NULL;
IplImage *g_gray = NULL;
int g_thresh = 10;
int g_Mathresh = 255;
CvMemStorage *g_storage = NULL;
void on_trackbar(int)
{
    if (g_storage == NULL)
    {
        g_gray = cvCreateImage(cvGetSize(g_image),8,1);
        g_storage = cvCreateMemStorage(0);
    }
    else
    {
        cvClearMemStorage(g_storage);
    }
    CvSeq *contours = NULL;
    cvCvtColor(g_image,g_gray,CV_RGB2GRAY);
    cvThreshold(g_gray,g_gray,g_thresh,255,CV_THRESH_BINARY);
    cvFindContours(g_gray,g_storage,&contours);
    cvZero(g_gray);
    if (contours)
    {
        cvDrawContours(g_gray,contours,cvScalarAll(255),cvScalarAll(255),100);
    }
    cvShowImage("Contours",g_gray);
}
int main()
{
    g_image=cvLoadImage("C:/Users/Administrator/Desktop/0.jpg");
    cvNamedWindow("Contours",1);
    cvCreateTrackbar("Threshold","Contours",&g_thresh,g_Mathresh,on_trackbar);
    on_trackbar(0);
    cvWaitKey();
    return 0;
}

原图如下:

检测效果如下:

猜你喜欢

转载自blog.csdn.net/hanxiaoyong_/article/details/83309856