如何使用opencv检测球的位置和半径?

时间:2016-08-30 08:34:01

标签: c++ opencv

我需要检测这个球:please click here并使用opencv找到它的位置和半径。我已经下载了很多代码,但它们都没有。任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:0)

我看到你安装了相当多的设置。正如评论中所提到的那样,请确保您有适当的光线来捕捉球,并通过将球涂成不同的颜色使球与周围环境区分开来。

一旦您的设置针对检测进行了优化,您可以通过不同的方式跟踪您的球(静止与否)。有几种方法可能是:

  1. 特征检测:通过Hough Circles,检测位于特定颜色范围内的2D圆(及其半径),如下所述
  2. 还有很多方法可以通过特征检测来检测对象,例如this clever blog指出。

    1. 物体检测:通过SURF,SIFT和许多其他方法,您可以检测到您的球,计算它的半径,甚至可以预测它的运动。
    2. 此代码使用Hough Circles来计算球的位置,实时显示并实时计算它的半径。我正在使用Qt 5.4和OpenCV版本2.4.12

       void Dialog::TrackMe() {
              webcam.read(cim);         /*call read method of webcam class to take in live feed from webcam and store each frame in an OpenCV Matrice 'cim'*/
      
          if(cim.empty()==false)      /*if there is something stored in cim, ie the webcam is running and there is some form of input*/ {
          cv::inRange(cim,cv::Scalar(0,0,175),cv::Scalar(100,100,256),cproc);
      
      /* if any part of cim lies between the RGB color ranges (0,0,175) and (100,100,175), store in OpenCV Matrice cproc */
          cv::HoughCircles(cproc,veccircles,CV_HOUGH_GRADIENT,2,cproc.rows/4,100,50,10,100);
      
      /* take cproc, process the output to matrice veccircles, use method [CV_HOUGH_GRADIENT][1] to process.*/
      
      for(itcircles=veccircles.begin();   itcircles!=veccircles.end();    itcircles++)
          {
             cv::circle(cim,cv::Point((int)(*itcircles)[0],(int)(*itcircles)[1]), 3, cv::Scalar(0,255,0), CV_FILLED);    //create center point
              cv::circle(cim,cv::Point((int)(*itcircles)[0],(int)(*itcircles)[1]), (int)(*itcircles)[2], cv::Scalar(0,0,255),3);  //create circle
          }
      
              QImage qimgprocess((uchar*)cproc.data,cproc.cols,cproc.rows,cproc.step,QImage::Format_Indexed8);   //convert cv::Mat to Qimage
              ui->output->setPixmap(QPixmap::fromImage(qimgprocess));
      /*render QImage to screen*/
          }
              else
                  return; /*no input, return to calling function*/
      
              }
      

      处理是如何进行的?

      一旦你开始接受球的实时输入,被捕获的帧应该能够显示球的位置。为此,捕获的帧被分成桶,这些桶进一步划分为网格。在每个网格内,检测到边缘(如果存在),从而检测到圆圈。但是,只考虑那些通过上述范围内的网格(在cv :: Scalar中)的圆圈。因此,对于通过位于指定范围内的网格的每个圆,对应于该网格的数字递增。这被称为投票。

      然后每个网格将它的投票存储在累加器网格中。在这里,2 is the accumulator ratio。这意味着累加器矩阵将仅存储输入图像cproc的分辨率的一半。投票后,我们可以在累加器矩阵中找到局部最大值。局部最大值的位置对应于原始空间中的圆心。

      cproc.rows / 4是检测到的圆的中心之间的最小距离。

      100和50分别是传递给canny边缘函数的上限阈值和下限阈值,它基本上只检测上述阈值之间的边缘

      10和100是要检测的最小和最大半径。高于或低于这些值的任何内容都将无法检测到。

      现在,for循环处理捕获并存储在veccircles中的每个帧。它会在框架中创建一个圆圈和一个点。

      对于上述内容,您可以访问this link