Tôi đang phát triển ứng dụng để theo dõi động vật nhỏ trong đĩa Petri (hoặc các hộp chứa hình tròn khác). Trước khi thực hiện theo dõi, một vài khung hình đầu tiên được sử dụng để xác định các khu vực. Mỗi món ăn sẽ khớp với khu vực tĩnh độc lập tròn (tức là sẽ không được cập nhật trong khi theo dõi). Người dùng có thể yêu cầu chương trình tìm cách tìm các món ăn từ hình ảnh gốc và sử dụng chúng làm khu vực.Mạnh mẽ tìm thấy N vòng tròn có cùng đường kính: thay thế cho bruteforcing Hough transform threshold
Dưới đây là ví dụ:
Để thực hiện nhiệm vụ này, tôi đang sử dụng Hough Vòng Chuyển. Nhưng trên thực tế, những người dùng khác nhau sẽ có cài đặt và hình ảnh rất khác nhau và tôi không muốn yêu cầu người dùng xác định các tham số theo cách thủ công. Tôi không thể đoán được tất cả các tham số.
Tuy nhiên, tôi có thêm thông tin mà tôi muốn sử dụng:
Tôi biết chính xác số vòng kết nối được phát hiện.
- Tất cả các vòng kết nối có cùng kích thước.
- Vòng kết nối không thể trùng lặp.
- Tôi có ý tưởng sơ bộ về kích thước tối thiểu và tối đa của vòng kết nối.
- Các vòng tròn phải hoàn toàn trong ảnh.
Do đó, tôi có thể thu hẹp số tham số để xác định thành một: ngưỡng. Sử dụng những thông tin này và xem xét rằng tôi có N vòng kết nối để tìm, giải pháp hiện tại của tôi là kiểm tra nhiều giá trị ngưỡng và giữ vòng tròn giữa độ lệch chuẩn là nhỏ nhất (vì tất cả các vòng tròn phải có kích thước tương tự):
//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;
}
}
}
Với:
//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;
}
tôi đã đạt đến một độ chính xác cao hơn bằng cách thực hiện một pas thứ hai s trong đó tôi lặp lại thuật toán này thu hẹp khoảng [minRad: maxRad] sử dụng kết quả của pass đầu tiên.
Ví dụ minRad2 = 0,95 * bán kính trung bình của các vòng kết nối tốt nhất và maxRad2 = 1,05 * bán kính trung bình của các vòng kết nối tốt nhất.
Tôi đã có kết quả khá tốt bằng cách sử dụng phương pháp này cho đến nay. Tuy nhiên, nó là chậm và khá bẩn. Câu hỏi của tôi là:
- Bạn có thể điều gì về giải thuật thay thế để giải quyết vấn đề này một cách sạch hơn/nhanh hơn không?
- Hoặc bạn sẽ đề xuất gì để cải thiện thuật toán này?
- Bạn có nghĩ rằng tôi nên điều tra biến đổi Hough tổng quát không?
Cảm ơn câu trả lời và đề xuất của bạn.
những thứ đó trong món ăn là gì? –
Chúng là những nhịp đập, nhưng chương trình sẽ hoạt động với nhiều lỗi khác nhau :) –
Không có gì về thuật toán, nhưng bạn có thể tận dụng lợi thế của C++ 11 nếu bạn chưa sử dụng nó (container tiêu chuẩn nhanh hơn) và các chức năng như std :: fma để có độ chính xác cao hơn với một số nội dung. Và sử dụng "a + = b" thay vì "a = a + b". Tất cả điều đó chỉ là về cú pháp C++ vì vậy nó sẽ không cải thiện thuật toán mà chỉ là hàm C++ của nó. – Morwenn