16

我正在开发应用程序来跟踪培养皿(或其他圆形容器)中的小动物。在进行任何跟踪之前,前几帧用于定义区域。每道菜都会匹配一个圆形的独立静态区域(即在跟踪过程中不会更新)。用户可以请求程序尝试从原始图像中查找菜肴并将其用作区域。

以下是示例: 在此处输入图像描述 在此处输入图像描述

为了执行此任务,我正在使用Hough Circle Transform。但实际上,不同的用户会有非常不同的设置和图像,我不想让用户手动定义参数。我也不能只猜测所有参数。

但是,我得到了我想使用的其他信息:

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

  • 所有圆圈的尺寸几乎相同。
  • 圆圈不能重叠。
  • 我对圆圈的最小和最大尺寸有一个粗略的了解。
  • 圆圈必须完全在图片中。

因此,我可以将要定义的参数数量缩小为一个:阈值。使用这些信息并考虑到我要找到 N 个圆圈,我当前的解决方案是测试许多阈值值并保持标准偏差最小的圆圈(因为所有圆圈都应该具有相似的大小):

//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] 间隔。

例如 minRad2 = 0.95 * 最佳圆的平均半径和 maxRad2 = 1.05 * 最佳圆的平均半径。

到目前为止,我使用这种方法取得了相当好的结果。但是,它很慢而且很脏。我的问题是:

  • 您可以使用任何替代算法以更清洁/更快的方式解决此问题吗?
  • 或者你有什么建议来改进这个算法?
  • 你认为我应该研究广义霍夫变换吗?

感谢您的回答和建议。

4

3 回答 3

10

以下方法应该非常适合您的情况:

  1. 二值化您的图像(您可能需要在多个阈值级别上执行此操作,以使算法独立于照明条件)
  2. 寻找轮廓
  3. 对于每个轮廓计算力矩
  4. 按区域过滤它们以删除太小的轮廓
  5. 按圆度过滤轮廓:

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

    ratio接近 1 会给你圈子。

  6. 计算每个圆的半径和中心

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

并且您可以添加更多过滤器以提高鲁棒性。

实际上,您可以在 OpenCV 中找到整个过程的实现。看看SimpleBlobDetector类和findCirclesGrid函数是如何实现的。

于 2012-06-03T21:02:22.940 回答
5

在当前算法中,最突出的是for(int t=5; t<400; t=t+2)循环。尝试记录一些测试图像的得分值。图score(t)t. 运气好的话,它要么建议一个较小的范围,t要么是一条具有单个最大值的平滑曲线。在后一种情况下,您可以使用爬山方法将所有t值的循环更改为更智能的搜索。

即使它相当嘈杂,您也可以先循环遍历 30 的倍数,然后最好将其中的 1 或 2 个循环遍历附近的 2 的倍数。

此外,在您的评分功能中,您应该取消任何具有重叠圆圈的结果,并可能惩罚过度间隔的圆圈。

于 2012-06-03T21:48:28.177 回答
3

You don't explain why you are using a black background. Unless you are using a telecentric lens (which seems unlikely, given the apparent field of view), and ignoring radial distortion for the moment, the images of the dishes will be ellipses, so estimating them as circles may lead to significant errors.

All and all, it doesn't seem to me that you are following a good approach. If the goals is simply to remove the background, so you can track the bugs inside the dishes, then your goal should be just that: find which pixels are background and mark them. The easiest way to do that is to take a picture of the background without dishes, under the same illumination and camera, and directly detect differences with the picture with the images. A colored background would be preferable to do that, with a color unlikely to appear in the dishes (e.g. green or blue velvet). So you'd have reduced the problem to bluescreening (or chroma keying), a classic technique in machine vision as applied to visual effects. Do a google search for "matte petro vlahos assumption" to find classic algorithms for solving this problem.

于 2012-06-04T16:19:57.963 回答