我正在开发应用程序来跟踪培养皿(或其他圆形容器)中的小动物。在进行任何跟踪之前,前几帧用于定义区域。每道菜都会匹配一个圆形的独立静态区域(即在跟踪过程中不会更新)。用户可以请求程序尝试从原始图像中查找菜肴并将其用作区域。
以下是示例:
为了执行此任务,我正在使用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 * 最佳圆的平均半径。
到目前为止,我使用这种方法取得了相当好的结果。但是,它很慢而且很脏。我的问题是:
- 您可以使用任何替代算法以更清洁/更快的方式解决此问题吗?
- 或者你有什么建议来改进这个算法?
- 你认为我应该研究广义霍夫变换吗?
感谢您的回答和建议。