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");
}