opencv 识别网球 ,或者绿色的小球 输出重心坐标

来源:互联网 发布:小沢健二 知乎 编辑:程序博客网 时间:2024/05/15 02:39
void image_process(IplImage *image) {  int iLowH =26;    int iHighH = 69;    int iLowS = 42;     int iHighS = 206;      int iLowV = 0;    int iHighV = 198;   CvMemStorage* storage2 = cvCreateMemStorage();   CvSeq* contour3 = NULL;   CvMoments moments;    CvMat *region;    CvPoint pt1,pt2;   double m00 = 0, m10, m01, mu20, mu11, mu02, inv_m00;    double a, b, c;    int xc, yc;     CvMemStorage* storage = cvCreateMemStorage(); CvSeq * circles=NULL;   // Circle cir[6];    CvPoint P0;    CvPoint CenterPoint;   // cvNamedWindow("win1"); //cvShowImage("win1",image);//cvNamedWindow("image",CV_WINDOW_AUTOSIZE);//用于显示图像的窗口//cvNamedWindow("hsv",CV_WINDOW_AUTOSIZE);//cvNamedWindow("saturation",CV_WINDOW_AUTOSIZE);//cvNamedWindow("value",CV_WINDOW_AUTOSIZE);//cvNamedWindow("pImg8u",1);IplImage *hsv=cvCreateImage(cvGetSize(image),8,3);//给hsv色系的图像申请空间IplImage *hue=cvCreateImage(cvGetSize(image),8,1);  //色调IplImage *saturation=cvCreateImage(cvGetSize(image),8,1);//饱和度IplImage *value=cvCreateImage(cvGetSize(image),8,1);//亮度IplImage *imgThresholded=cvCreateImage(cvGetSize(hue),8,1); cvNamedWindow("yuan",1);cvCvtColor(image,hsv,CV_BGR2HSV);//将RGB色系转为HSV色系cvShowImage("yuan",image);//cvShowImage("hsv",hsv);cvSplit(hsv, hue, 0, 0, 0 );//分离三个通道cvSplit(hsv, 0, saturation, 0, 0 );cvSplit(hsv, 0, 0, value, 0 );int value_1=0;  cvInRangeS(   hsv,     cvScalar(iLowH, iLowS, iLowV),    cvScalar(iHighH, iHighS, iHighV),   imgThresholded   );  cvNamedWindow("imgThresholded",1); cvShowImage("imgThresholded",imgThresholded); IplImage*pContourImg= cvCreateImage( cvGetSize(image), 8, 1 ); cvCopy(imgThresholded,pContourImg); cvNamedWindow("pContourImg",1); cvShowImage("pContourImg",pContourImg); IplImage* dst = cvCreateImage( cvGetSize(image), 8, 3 );  CvMemStorage* storage3 = cvCreateMemStorage(0);  CvSeq* contour = 0; // 提取轮廓      int contour_num = cvFindContours(pContourImg, storage3, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);      cvZero(dst);        // 清空数组      CvSeq *_contour = contour;       double maxarea = 100;      double minarea = 10;      int m = 0;      for( ; contour != 0; contour = contour->h_next )        {              double tmparea = fabs(cvContourArea(contour));          if(tmparea < minarea)             {                cvSeqRemove(contour, 0); // 删除面积小于设定值的轮廓              continue;          }            CvRect aRect = cvBoundingRect( contour, 0 );           if ((aRect.width/aRect.height)<1)            {                cvSeqRemove(contour, 0); //删除宽高比例小于设定值的轮廓              continue;          }            if(tmparea > maxarea)            {                maxarea = tmparea;          }            m++;          // 创建一个色彩值      //    CvScalar color = CV_RGB( 0, 0, 255 );         /*   max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓          如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种          如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓 */      //   cvDrawContours(dst, contour, color, color, 0, 1, 8);   //绘制外部和内部的轮廓      }        contour = _contour;      int count = 0;  double tmparea=0;    for(; contour != 0; contour = contour->h_next)      {            count++;           tmparea = fabs(cvContourArea(contour));          if (tmparea >= maxarea)            {                CvScalar color = CV_RGB( 0, 255, 0);              cvDrawContours(dst, contour, color, color, -1, 1, 8);  cout<<"222"<<endl;cout<<"面积为"<<tmparea<<endl;cout<<endl;CvRect aRect = cvBoundingRect( contour, 0 ); //找重心{CvPoint2D32f center = cvPoint2D32f(0, 0);int countOfPoint = 0;for(int i = aRect.x; i < aRect.x + aRect.width; ++i){for(int j = aRect.y; j < aRect.y + aRect.height; ++j){if(*(image->imageData + image->widthStep * j + i) != 0){center.x += i;center.y += j;countOfPoint++;}}}center.x /= countOfPoint;center.y /= countOfPoint;cout<<"重心坐标为x:"<<center.x<<endl;         cout<<"重心坐标为y:"<<center.y<<endl;cvCircle(dst, cvPoint(center.x, center.y), 5, cvScalar(0, 255), 2);}}  //  //Threshold the image  //   cvErode(imgThresholded,imgThresholded);  //   cvErode(imgThresholded,imgThresholded); //cvErode(imgThresholded,imgThresholded); //cvErode(imgThresholded,imgThresholded);    //IplImage* pImg8u=cvCloneImage(imgThresholded); //cvCanny(pImg8u, pImg8u,40, 50, 5); //cvShowImage("pImg8u",pImg8u); //circles=cvHoughCircles(pImg8u,storage,CV_HOUGH_GRADIENT,//2,   //最小分辨率,应当>=1//pImg8u->height/15,   //该参数是让算法能明显区分的两个不同圆之间的最小距离//80,    //用于Canny的边缘阀值上限,下限被置为上限的一半//65,    //累加器的阀值//25,      //最小圆半径 //50      //最大圆半径//);  }cvShowImage( "contour", dst );}

0 0