检测与圆圈类似的对象

我试图使用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的第一个代码块周围放置它。 (反正无济于事。)

  • 矢量化(SIMD)只会使像素级处理受益。 如果OpenCV实现它,很棒; 如果不是的话,你可以做的事情不多。
  • 我的猜测是cvtColorGaussianBlurthresholddilateerode可能是矢量化的,但其他可能不是。



    下面试试,

  • 在源中查找轮廓。

  • 找出轮廓的最小包围圆。

  • 现在使用CV_FILLED将轮廓绘制到新垫子上。

  • 同样用封闭的选项将封闭的圆圈绘制到新的垫子上。

  • 执行上述两者之间的x或运算并计算非零值。

  • 通过比较轮廓和外框圆圈之间的非零像素与阈值,可以决定轮廓是否接近圆圈。 您可以通过计算加密圆圈的面积并以此为百分比来决定阈值。

  • 这个想法很简单,轮廓与其包围圆之间的区域随着轮廓闭合而减小

    链接地址: http://www.djcxy.com/p/19417.html

    上一篇: Detect objects similar to circles

    下一篇: Python: multiple assignment vs. individual assignment speed