图像或视频分析时,物体检测通常要将其轮廓提取出来,以便后续的处理,在opencv中有一套组合拳比较固定,也是很常用的。包括轮廓的面积、最小包围、形状信息等都可以容易得到。opencv例程中有例子,这里主要是把过程重新清晰下,也是自己正在使用的处理方法。
大体步奏:1、图像灰度化。2、图像二值化处理。3、寻找轮廓
例:
IplImage *original;
original=cvLoadImage("Lena.bmp",1);
IplImage *gray;
gray=cvCreateImage(cvGetSize(original), 8, 1);
cvCvtColor(original,gray,CV_BGR2GRAY);
cvThreshold(gray,gray,CV_THRESH_OTSU);//这里以OTSU阈值化方法为例
CvMemStorage *storage;
storage=cvCreateMemStorage(0);
CvSeq *contour=0;
cvFindContour(gray,storage,&contour,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));//这里是自己多使用的查找外边缘
//定义过滤条件
double Min_Area=20;
double Max_Area=100;
CvRect rect_tmp;
CvRect rect_bound;
int area_tmp=0;
for(;contour!=0;contour=contour->h_next)
{
double area=cvContourArea(contour);
if((fabs(area)>Min_Area)&&(fabs(area<Max_Area))
{
rect_tmp=cvBoundingRect(contour);
//这里只是加强限制
if((rect_tmp.x>ROI.x)&&(rect_tmp.y<ROI.y))
{
if((rect_tmp.width<ROI.width)&&(rect_tmp.height<ROI.height))
{
if(area_tmp<area)
{
area_tmp=area;
rect_bound=rect_tmp;
}
}
}
}
}
cvRectangle(original,cvPoint(rect_bound.x,rect_bound.y),cvPoint(rect_bound.x+rect_bound.width,rect_bound.y+rect_bound.hight),CV_RGB(255,0,0),1);
cvReleaseMemStorage(&storage);
整个过程是比较清晰的,借助opencv的现有函数,实现起来还是很方便的,并可以根据自己的实际应用来进行自由扩展。