opencv图像处理6--网球检测

来源:互联网 发布:游族网络官网充值折扣 编辑:程序博客网 时间:2024/04/30 21:32
void CBallsampleDlg::OnOK() 
{
// TODO: Add extra validation here





//CDialog::OnOK();
IplImage*frame = NULL;  //定义帧,每帧就是一张图  
IplImage* B_part = NULL;
IplImage* G_part = NULL;
IplImage* R_part = NULL;//三个通道下的灰度图
IplImage* biImage = NULL;//调试用,G通道二值化后的灰度图
IplImage* biImage_B = NULL;//B通道下进行阈值分割后的图片。
IplImage* dst = NULL; 



CvMemStorage* storage = cvCreateMemStorage(0);
CvMemStorage* circleStorage = cvCreateMemStorage(0);
CvSeq* contour = 0;
 
//轮廓矩形
CvRect contourRect = cvRect(0,0,0,0);


CvCapture * pCapture = cvCreateFileCapture("x1.avi");
// CvCapture* pCapture = cvCreateCameraCapture(-1); //创建摄像头抓取  


cvNamedWindow("Camera",CV_WINDOW_AUTOSIZE);  //设置窗口  
    cvNamedWindow("contours",1);
cvNamedWindow("B_channel",1);
cvNamedWindow("G_channel",1);
cvNamedWindow("R_channel",1);
    cvNamedWindow("circle",1);
    cvNamedWindow("biImage",1);
cvNamedWindow("biImage_B",1);





int count = 1;
while (frame = cvQueryFrame(pCapture))      
{    
if(count ==1)
{
//读取第一帧图片后,初始化各个图片
B_part = cvCreateImage(cvGetSize(frame),frame->depth,1);
G_part = cvCreateImage(cvGetSize(frame),frame->depth,1);
R_part = cvCreateImage(cvGetSize(frame),frame->depth,1);
    biImage = cvCreateImage(cvGetSize(frame),frame->depth,1);
biImage_B = cvCreateImage(cvGetSize(frame),frame->depth,1);
dst = cvCreateImage( cvGetSize(frame), 8, 3 );
}
else{
//开始进行图像处理
cvSplit(frame , B_part,G_part, R_part,0);//抽取单个通道
// cvFlip(G_part,G_part,0);//沿X轴翻转一次
CvSeq* circles = cvHoughCircles( G_part, circleStorage, CV_HOUGH_GRADIENT, 2, G_part->height/4, 200, 100 );
//circles存储找到的圆形物体,本打算采用形状的方式找到网球,但是由于干扰物种存在圆形物体,因此干扰很严重
//并且,由于光线的不均匀,网球的一部分灰度值比较低,因此采用形状判别,效果不佳~
//最终才用的是在两个通道下分别去掉一部分干扰物,两个二值图再进行与操作。


//绘制找到的圆,测试表明总是会找到干扰圆,而不是要找的网球。
for(int i = 0; i < circles->total; i++ )
{
float* p = (float*)cvGetSeqElem( circles, i );
cvCircle( frame, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 );
cvCircle( frame, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
}




//阈值分割
//在G通道下去掉地板
//在B通道下去掉白色的物体
//两个分割后的二值图进行与操作,确定网球
cvThreshold(G_part,G_part, 190, 255,CV_THRESH_BINARY);
cvCopy(G_part,biImage,NULL);//测试中间结果
cvThreshold(B_part, B_part,145,255,CV_THRESH_BINARY_INV);
 


    




//获取并绘制轮廓
//将两个阈值分割的图片进行与操作,赋值给G通道
cvAnd(G_part, B_part,G_part,NULL);


//对分割得到的网球进行适当腐蚀和膨胀
cvErode(G_part, G_part,NULL,1);
cvDilate(G_part,G_part,NULL,9);

//找到轮廓并绘制
cvFindContours( G_part, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
cvZero( dst );
for( ; contour != 0; contour = contour->h_next)
{


contourRect = cvBoundingRect(contour,0);


if((contourRect.width > 60) &&(contourRect.height >60)){
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );//每次都随机颜色显示
/* 用1替代 CV_FILLED  所指示的轮廓外形 */
cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );

//绘制找到的轮廓的矩形框
cvRectangle(dst ,cvPoint(contourRect.x, contourRect.y),
cvPoint(contourRect.x + contourRect.width, contourRect.y + contourRect.height),
CV_RGB(255,0,0),
1,
8,
0);
}
 
}
  
   //显示各个计算出的图像,包括中间运算结果
cvShowImage("Camera", frame);  
cvShowImage( "contours", dst );
cvShowImage("B_channel",B_part);
cvShowImage("G_channel", G_part);
cvShowImage("R_channel",R_part);
cvShowImage("biImage",biImage);
cvShowImage("biImage_B",biImage_B);




int key1;
key1 = cvWaitKey (300);
if (key1 == 'q' || key1 == 'Q')  
break;  



}
count++;
}   




cvReleaseCapture(&pCapture);    //销毁摄像头  



cvReleaseImage(&dst);
cvReleaseImage(&B_part);
cvReleaseImage(&G_part);
cvReleaseImage(&R_part);
cvReleaseImage(&biImage);
cvReleaseImage(&biImage_B);


cvDestroyWindow("Camera");  //销毁窗口 
cvDestroyWindow("contours");
cvDestroyWindow("B_channel");
cvDestroyWindow("G_channel");
cvDestroyWindow("R_channel");
cvDestroyWindow("circle");
cvDestroyWindow("biImage");
cvDestroyWindow("biImage_B");
}



原创粉丝点击