注意:转载请注明出处!
图像处理中的边缘检测是根据像素间的差异检测出轮廓边缘的像素,但它没有将轮廓作为一个整体。将这些轮廓边缘像素组装成一个整体(轮廓),就要进行轮廓检测.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
#include
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;
}
原图如下: