检测与圆圈类似的对象
我试图使用OpenCV的HoughCircles
来检测与圆圈相似的HoughCircles
。 问题是: HoughCircles
在某些情况下无法检测到这些对象。
有没有人知道任何其他方式来检测类似于这些圈子的物体?
更新
更新
Hello Folks我正在添加我的检测方法结果的gif。
用gif解释问题更容易。 我想删除的不良效果是圆圈大小的变化。 即使是像右边那样的静态形状,左边的结果也是不精确的。 有没有人知道这个解决方案?
更新从这个对象中我需要的是它的直径。 我用findContours
来完成它。 现在如果使用openCV和OpenMP,速度太慢,我无法使用findContours
。 有没有人知道一个快速替代findContours?
更新
我用来检测这些形状的代码。
for (int j=0; j<=NUM_THREADS-1;j++)
{
capture >> frame[j];
}
#pragma omp parallel shared(frame,processOutput,circles,diameterArray,diameter)
{
int n=omp_get_thread_num();
cvtColor( frame[n], processOutput[n], CV_BGR2GRAY);
GaussianBlur(processOutput[n], processOutput[n], Size(9, 9), 2, 2);
threshold(processOutput[n], processOutput[n], 21, 250, CV_THRESH_BINARY);
dilate(processOutput[n], processOutput[n], Mat(), Point(-1, -1), 2, 1, 1);
erode(processOutput[n], processOutput[n], Mat(), Point(-1, -1), 2, 1, 1);
Canny(processOutput[n], processOutput[n], 20, 20*2, 3 );
HoughCircles( processOutput[n],circles[n], CV_HOUGH_GRADIENT, 1, frame[n].rows/8, 100,21, 50, 100);
}
#pragma omp parallel private(m, n) shared(circles)
{
#pragma omp for
for (n=0; n<=NUM_THREADS-1;n++)
{
for( m = 0; m < circles[n].size(); m++ )
{
Point center(cvRound(circles[n][m][0]), cvRound(circles[n][m][2]));
int radius = cvRound(circles[n][m][3]);
diameter = 2*radius;
diameterArray[n] = diameter;
circle( frame[0], center, 3, Scalar(0,255,0), -1, 8, 0 );
circle( frame[0], center, radius, Scalar(0,0,255), 3, 8, 0 );
}
}
}
根据新的描述和附加的性能和精度要求进行编辑。
这超出了“OpenCV示例项目”的范围,并进入了实际应用程序开发的领域。 性能和准确性都成为要求。
这需要技术的组合。 所以,不要只选择一种方法。 您将不得不尝试所有方法的组合,以及微调参数以找到可接受的组合。
#1。 用于连续视频帧识别任务的整体方法
使用缓慢但准确的方法获取初始检测结果。
一旦在一帧中发现肯定检测,下一帧应该使用在最近帧中检测到的位置切换到快速本地搜索算法。
作为提醒,不要忘记更新“最近的位置”以供下一帧使用。
#2。 对初始对象获取的建议。
保持目前的做法,并纳入建议。
您仍然可以精确调整速度和精度之间的平衡,因为当使用本地搜索方法处理下一帧时,正确但不精确的结果(数十像素关闭)将会更新和精炼。
dp
参数。 较大的dp
值会降低执行Hough Gradient变换的分辨率。 这会降低中心坐标的精度 ,但会提高检测凹陷圆的机会,因为当以较低的分辨率执行变换时,凹痕变得不太重要。
另一个好处是降低分辨率应该运行得更快。
#3。 围绕之前检测到的位置进行快速本地搜索的建议
由于搜索空间有限且所需数据量有限,因此可以快速准确地进行本地搜索。
为了跟踪通过视频帧的虹膜边界的移动,我建议使用称为蛇模型的算法族。
重点是跟踪通过轮廓的边缘移动。 有很多算法可以实现Snakes模型。 不幸的是,大多数实现都是针对非常复杂的形状识别进行量身定制的,这对您的项目来说会是一种矫枉过正的行为。
基本思路:(假设前面的结果是曲线)
你可以在互联网上找到许多不同的实现方法。 不幸的是,据报道,与OpenCV一起打包的那个可能无法很好地工作。 你可能不得不尝试不同的开源实现,最终你可能不得不实施一个简单但适合你的项目需求的实现。
#4。 为您的速度优化尝试寻求建议。
使用软件性能分析器。
在每次调用OpenCV函数时添加一些时间和日志代码,以打印出每一步所花费的时间。 你会感到惊讶。 原因在于一些OpenCV功能比其他功能更加矢量化和并行化,这可能是因为爱的劳动。
不幸的是,对于最慢的步骤 - 最初的对象获取,并不多(通过多线程)。
这对你来说可能已经很明显了,因为你没有在#pragma omp for
的第一个代码块周围放置它。 (反正无济于事。)
我的猜测是cvtColor
, GaussianBlur
, threshold
, dilate
, erode
可能是矢量化的,但其他可能不是。
下面试试,
在源中查找轮廓。
找出轮廓的最小包围圆。
现在使用CV_FILLED将轮廓绘制到新垫子上。
同样用封闭的选项将封闭的圆圈绘制到新的垫子上。
执行上述两者之间的x或运算并计算非零值。
通过比较轮廓和外框圆圈之间的非零像素与阈值,可以决定轮廓是否接近圆圈。 您可以通过计算加密圆圈的面积并以此为百分比来决定阈值。
这个想法很简单,轮廓与其包围圆之间的区域随着轮廓闭合而减小
链接地址: http://www.djcxy.com/p/19417.html上一篇: Detect objects similar to circles
下一篇: Python: multiple assignment vs. individual assignment speed