Opencv进行连通域标注

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/图像预处理函数,输入单通道灰度图像
IplImage * ImagePreProcess( IplImage* grayFrame )
{

IplImage *Binary_grayFrame = cvCreateImage(cvGetSize(grayFrame),8,1);
//二值化图像
cvThreshold(grayFrame,Binary_grayFrame,220,255,CV_THRESH_BINARY);

IplImage *Open_grayFrame = cvCreateImage(cvGetSize(grayFrame),8,1);

//闭运算模板
IplConvKernel * Templete_CLOSE = cvCreateStructuringElementEx(7,7,4,4,CV_SHAPE_ELLIPSE);
IplConvKernel* Templete_CLOSE1 = lhStructuringElementMap(Templete_CLOSE);

//闭运算 以连接由于图像分割产生的区域分离
cvDilate(Binary_grayFrame,Open_grayFrame,Templete_CLOSE,1);
cvErode(Open_grayFrame,grayFrame,Templete_CLOSE1,1);



//3*3大小窗口中值滤波 滤除鼓励噪声点
//cvSmooth(grayFrame,grayFrame,CV_GAUSSIAN,3);
cvSmooth(grayFrame,grayFrame,CV_MEDIAN,3);
//cvSaveImage("E:\\黄坤\\游戏枪数据\\中山实验数据\\拍摄视频\\连续问题帧中11-297.jpg",grayFrame);


////观察窗口 正式使用时注释
/*cvNamedWindow("ImagePreProcessWindow",CV_WINDOW_AUTOSIZE);
cvShowImage("ImagePreProcessWindow",grayFrame);*/
//cvWaitKey(0);

// 释放内存
cvReleaseImage(&Binary_grayFrame);
cvReleaseImage(&Open_grayFrame);
cvReleaseStructuringElement(&Templete_CLOSE);
cvReleaseStructuringElement(&Templete_CLOSE1);

return grayFrame;
}

//寻找得到LED中心点位置
//寻找得到LED中心点位置
int FindCenter(IplImage *Frame, CvMat *intrinsic, CvMat * distortion)
{
CvMemStorage* Storage;
CvSeq* First_contour;
//定义非固定元素序列,CvSeq是所有opencv动态数据结构的基础

//存储轮廓数据
Storage = cvCreateMemStorage(0);
//存储各个的轮廓指针的队列
First_contour = cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),Storage);

int nNumberOfContour = 0;
// 找到所有轮廓 提取二值图像的轮廓
nNumberOfContour = cvFindContours( Frame, Storage, &First_contour, sizeof(CvContour),
CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

int Num = 0;//计数
//求取LED中心点
unsigned long sumx = 0;
unsigned long sumy = 0;
CvPoint UndistortPoints;
bool IsLEDPoint;

if ( nNumberOfContour < 5 ) // 检测到点小于5个时 图像中心点已经在屏幕外侧
{
cvReleaseMemStorage(&Storage);
return 0;
}

if ( nNumberOfContour < 11 )
{
for(CvSeq* Contour = First_contour; Contour!= NULL; Contour= Contour->h_next)
{
if (fabs( cvContourArea(Contour,CV_WHOLE_SEQ)) < LEDMaxArea )
{

IsLEDPoint = true;
for (int i = 0;itotal;i++)
{
if ( Contour->total < 4)
{
IsLEDPoint = false;
break;
}
CvPoint *p = CV_GET_SEQ_ELEM(CvPoint,Contour,i);
sumx += p->x;
sumy += p->y;
}
sumx /= Contour->total;
sumy /= Contour->total;

if (IsLEDPoint)
{
// 得到畸变矫正后坐标
UndistortPo

ints = GetUndistortLaserPoints(cvPoint(sumx,sumy),intrinsic,distortion);
//UndistortPoints = cvPoint(sumx,sumy);
/*if ( UndistortPoints.x < 0 || UndistortPoints.y < 0
|| UndistortPoints.x >640 || UndistortPoints.y > 480)
{
continue;
}*/
LEDPoint[Num].PointLocation = UndistortPoints;
sumx = 0;
sumy = 0;
Num++;

}
else
{
sumx = 0;
sumy = 0;
}

}
}

cvReleaseMemStorage(&Storage);
return Num;
}

if( nNumberOfContour > 10 )
{
double TempArea;
double AreaCompare[200][2];
//Seq排序程序
//取每一连通域面积
for(CvSeq* Contour = First_contour; Contour!= NULL; Contour= Contour->h_next)
{
AreaCompare[Num][0]= fabs(cvContourArea(Contour,CV_WHOLE_SEQ));
AreaCompare[Num][1] = Num;
Num++;
}

//连通域面积由大到小排序
for ( int i = 0;i < nNumberOfContour - 1; i++ )
for ( int j = i + 1; j < nNumberOfContour; j++ )
{
if ( AreaCompare[ i ][ 0 ] < AreaCompare[ j ][ 0 ] )
{
TempArea = AreaCompare[i][0];
Num =(int) AreaCompare[i][1];
AreaCompare[i][0] = AreaCompare[j][0];
AreaCompare[i][1] = AreaCompare[j][1];
AreaCompare[j][0] = TempArea;
AreaCompare[j][1] = Num;
}
}

// 将面积大于LEDMaxArea的连通域剔除

int EfffectNum = 0;
Num = 0;
for (int i = 0; i < nNumberOfContour; i++ )
{
if (AreaCompare[i][0] > LEDMaxArea)
{
Num++;
}
}

if ( nNumberOfContour - Num > 10)
{
EfffectNum = 10;
}
else
{
if (nNumberOfContour - Num < 10 )
{
EfffectNum = nNumberOfContour - Num;
}
}



//面积符合要求EffectNum内将连通域编号由小到大排序
int TempNum;
for ( int i = Num; i < EfffectNum-1; i++ )
for ( int j = i + 1; j < EfffectNum; j ++ )
{
if (AreaCompare[ i ][ 1 ] > AreaCompare[ j ][ 1 ] )
{
TempArea = AreaCompare[i][0];
TempNum =(int) AreaCompare[i][1];
AreaCompare[i][0] = AreaCompare[j][0];
AreaCompare[i][1] = AreaCompare[j][1];
AreaCompare[j][0] = TempArea;
AreaCompare[j][1] = TempNum;
}
}


TempNum = 0;//用以计数已遍历有效轮廓个数
nNumberOfContour = 0;//已遍历轮廓
for(CvSeq* Contour = First_contour; Contour!= NULL && TempNum < EfffectNum; Contour= Contour->h_next)
{
if(nNumberOfContour == AreaCompare[Num][1])
{

IsLEDPoint = true;
for (int i = 0;itotal;i++)
{
if ( Contour->total < 4)
{
IsLEDPoint = false;
break;
}
CvPoint *p = CV_GET_SEQ_ELEM(CvPoint,Contour,i);
sumx += p->x;
sumy += p->y;
}
sumx /= Contour->total;
sumy /= Contour->total;

if (IsLEDPoint)
{
// 得到畸变矫正后坐标
UndistortPoints = GetUndistortLaserPoints(cvPoint(sumx,sum

y),intrinsic,distortion);
//UndistortPoints = cvPoint(sumx,sumy);
/*if ( UndistortPoints.x < 0 || UndistortPoints.y < 0
|| UndistortPoints.x >640 || UndistortPoints.y > 480)
{
continue;
}*/
LEDPoint[Num].PointLocation = UndistortPoints;
sumx = 0;
sumy = 0;
Num++;

}
else
{
sumx = 0;
sumy = 0;
}
}
nNumberOfContour++;
}

cvReleaseMemStorage(&Storage);
return EfffectNum;
}
}

相关文档
最新文档