答案 0 :(得分:0)
我看到你安装了相当多的设置。正如评论中所提到的那样,请确保您有适当的光线来捕捉球,并通过将球涂成不同的颜色使球与周围环境区分开来。
一旦您的设置针对检测进行了优化,您可以通过不同的方式跟踪您的球(静止与否)。有几种方法可能是:
还有很多方法可以通过特征检测来检测对象,例如this clever blog指出。
此代码使用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