稳健求n圆直径相同的:替代穷举Hough变换门槛 [英] Robustly find N circles with the same diameter: alternative to bruteforcing Hough transform threshold

查看:276
本文介绍了稳健求n圆直径相同的:替代穷举Hough变换门槛的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发的应用程序来跟踪在皮氏培养皿(或其他圆形容器)的小动物。 前的任何跟踪发生时,开头几帧用于定义区域。 每道菜都将匹配一个圆形独立的静态区域(即不会追踪过程中被更新)。 用户可以点播节目,试图找到从原始图像的菜肴,并把它们作为区域。

I am developing application to track small animals in Petri dishes (or other circular containers). Before any tracking takes place, the first few frames are used to define areas. Each dish will match an circular independent static area (i.e. will not be updated during tracking). The user can request the program to try to find dishes from the original image and use them as areas.

下面举例说明:

Here are examples:

为了完成这个任务,我使用的霍夫圆变换。 但在实践中,不同的用户将具有非常不同的设置,图像和我不想以询问用户手动定义的参数。 我不能只是猜测所有的参数,无论是。

In order to perform this task, I am using Hough Circle Transform. But in practice, different users will have very different settings and images and I do not want to ask the user to manually define the parameters. I cannot just guess all the parameters either.

不过,我有,我想用另外的信息:

However, I have got additional informations that I would like to use:

我知道要检测圆的确切人数。

I know the exact number of circles to be detected.

  • 所有的圈子都几乎相同的尺寸。
  • 在圆圈不能重叠。
  • 我有圆的最小和最大尺寸的一个粗略的想法。
  • 的圈子必须是完全的图片。

我因此可以缩小参数的数量来定义一个:阈值。 利用这些信息,并考虑到我有n周期发现,我目前的解决办法是, 阈值测试许多值,并保持圈之间的标准偏差是最小的(因为所有的圈子应具有类似大小):

I can therefore narrow down the number of parameters to define to one: the threshold. Using these informations and considering that I have got N circles to find, my current solution is to test many values of threshold and keep the circles between which the standard deviation is the smallest (since all the circles should have a similar size):

//at this point, minRad and maxRad were calculated from the size of the image and the number of circles to find.
//assuming circles should altogether fill more than 1/3 of the images but cannot be altogether larger than the image.
//N is the integer number of circles to find.
//img is the picture of the scene (filtered).

//the vectors containing the detected circles and the --so far-- best circles found.
std::vector<cv::Vec3f> circles, bestCircles;

//the score of the --so far-- best set of circles
double bestSsem = 0;

 for(int t=5; t<400 ; t=t+2){
//Apply Hough Circles with the threshold t
    cv::HoughCircles(img, circles, CV_HOUGH_GRADIENT, 3, minRad*2, t,3, minRad, maxRad );

    if(circles.size() >= N){
//call a routine to give a score to this set of circles according to the similarity of their radii
        double ssem = scoreSetOfCircles(circles,N);
//if no circles are recorded yet, or if the score of this set of circles is higher than the former best
        if( bestCircles.size() < N ||  ssem > bestSsem){
//this set become the temporary best set of circles
                bestCircles=circles;
                bestSsem=ssem;
        }
    }
}

使用:

 //the methods to assess how good is a set of circle (the more similar the circles are, the higher is ssem)
    double scoreSetOfCircles(std::vector<cv::Vec3f> circles, int N){
    double ssem=0, sum = 0;
        double mean;
        for(unsigned int j=0;j<N;j++){
            sum = sum + circles[j][2];
        }
        mean = sum/N;
        for(unsigned int j=0;j<N;j++){
            double em = mean - circles[j][2];
            ssem = 1/(ssem + em*em);
        }
    return ssem;

}

我已通过执行其中我重复此算法缩小[minRad:maxRad]的第二通达到更高的精度。使用第一通的结果间隔

I have reached a higher accuracy by performing a second pass in which I repeated this algorithm narrowing the [minRad:maxRad] interval using the result of the first pass.

例如minRad2 =最佳界和最佳界maxRad2 = 1.05 *平均半径0.95 *平均半径

For instance minRad2 = 0.95 * average radius of best circles and maxRad2 = 1.05 * average radius of best circles.

我不得不使用这种方法到目前为止还算不错的成绩。然而,它是缓慢和相当脏。 我的问题是:

I had fairly good results using this method so far. However, it is slow and rather dirty. My questions are:

  • 你能对任何其他算法的东西来解决这个问题,在一个更​​清洁/更快的方式?
  • 或者你会建议,以改善这种算法?
  • 你觉得我应该调查广义Hough变换?

感谢您的答案和建议。

推荐答案

下面的方法应该pretty的同时为您的情况:

The following approach should work pretty well for your case:

  1. 在二值化图像(您可能需要为此在几个层次上的阈值,使独立的照明条件下的算法)
  2. 找到轮廓
  3. 对于每个轮廓计算的时刻
  4. 按面积过滤它们以去除过小的轮廓
  5. 由圆过滤轮廓:

  1. Binarize your image (you might need to do this on several levels of threshold to make algorithm independent of the lighting conditions)
  2. Find contours
  3. For each contour calculate the moments
  4. Filter them by area to remove too small contours
  5. Filter contours by circularity:

double area = moms.m00;
double perimeter = arcLength(Mat(contours[contourIdx]), true);
double ratio = 4 * CV_PI * area / (perimeter * perimeter);

接近1会给你的圈子。

ratio close to 1 will give you circles.

半径计算每圈和中心

center = Point2d(moms.m10 / moms.m00, moms.m01 / moms.m00);

和您可以添加更多的过滤器,提高了耐用性。

And you can add more filters to improve the robustness.

其实你可以找到OpenCV的整个过程的实现。瞧, SimpleBlobDetector 类和 findCirclesGrid 功能的实现。

Actually you can find an implementation of the whole procedure in OpenCV. Look how the SimpleBlobDetector class and findCirclesGrid function are implemented.

这篇关于稳健求n圆直径相同的:替代穷举Hough变换门槛的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆