Bạn đã biết các vòng tròn nhỏ hơn trong hình ảnh (bạn đã vẽ màu đen).
- Chuẩn bị hình ảnh mặt nạ bằng các vòng kết nối này để các khu vực có vòng tròn nhỏ hơn sẽ có pixel khác 0. Chúng tôi sẽ gọi nó là mặt nạ:
- Trong ảnh gốc, điền các khu vực vòng tròn trong một màu tối (nói màu đen). Điều này sẽ dẫn đến một hình ảnh như vả của bạn 2. Chúng tôi sẽ gọi nó là điền
- Ngưỡng điền hình ảnh để có được các vùng tối. Chúng tôi sẽ gọi nó là nhị phân. Bạn có thể sử dụng Otsu thresholding cho việc này. Kết quả sẽ giống như thế này:
- Hãy khoảng cách biến đổi của nhị phân hình ảnh này. Sử dụng một phương pháp ước lượng khoảng cách chính xác cho việc này. Chúng tôi sẽ gọi số điện thoại này dist. Nó sẽ trông như thế này Một màu chỉ là một map nhiệt cho rõ ràng hơn:
- Sử dụng mặt nạ để có được những vùng đỉnh từ quận. Giá trị tối đa của mỗi khu vực như vậy sẽ cung cấp cho bạn bán kính của vòng tròn lớn hơn. Bạn cũng có thể thực hiện một số quá trình xử lý trên các vùng này để có được giá trị hợp lý hơn cho bán kính chứ không phải chỉ cần chọn tối đa.
- Đối với việc lựa chọn các khu vực, bạn có thể tìm thấy các đường viền của mặt nạ và sau đó trích xuất khu vực mà từ quận hình ảnh, hay, kể từ khi bạn đã biết các vòng tròn nhỏ từ việc áp dụng hough vòng tròn biến đổi, chuẩn bị một mặt nạ từ mỗi vòng kết nối đó và trích xuất vùng đó từ dist hình ảnh. Tôi không chắc chắn nếu bạn có thể tính toán số liệu thống kê tối đa hoặc khác bằng cách đưa ra một mặt nạ. Max chắc chắn sẽ hoạt động vì phần còn lại của pixel là 0. Bạn có thể tính toán số liệu thống kê của khu vực nếu bạn trích xuất các pixel đó sang một mảng khác.
Hình bên dưới hiển thị mặt nạ như vậy và vùng được trích xuất từ dist. Đối với điều này tôi nhận được tối đa khoảng 29, phù hợp với bán kính của vòng tròn đó. Lưu ý rằng hình ảnh không được chia tỷ lệ.
mặt nạ cho một vòng tròn, khu vực chiết xuất từ quận
Dưới đây là đoạn code (tôi không sử dụng hough-circles transform):
Mat im = imread(INPUT_FOLDER_PATH + string("ex1.jpg"));
Mat gray;
cvtColor(im, gray, CV_BGR2GRAY);
Mat bw;
threshold(gray, bw, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU);
// filtering smaller circles: not using hough-circles transform here.
// you can replace this part with you hough-circles code.
vector<int> circles;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
{
Rect rect = boundingRect(contours[idx]);
if (abs(1.0 - ((double)rect.width/rect.height) < .1))
{
Mat mask = Mat::zeros(im.rows, im.cols, CV_8U);
drawContours(mask, contours, idx, Scalar(255, 255, 255), -1);
double area = sum(mask).val[0]/255;
double rad = (rect.width + rect.height)/4.0;
double circArea = CV_PI*rad*rad;
double dif = abs(1.0 - area/circArea);
if (dif < .5 && rad < 50 && rad > 30) // restrict the radius
{
circles.push_back(idx); // store smaller circle contours
drawContours(gray, contours, idx, Scalar(0, 0, 0), -1); // fill circles
}
}
}
threshold(gray, bw, 0, 255, CV_THRESH_BINARY_INV|CV_THRESH_OTSU);
Mat dist, distColor, color;
distanceTransform(bw, dist, CV_DIST_L2, 5);
double max;
Point maxLoc;
minMaxLoc(dist, NULL, &max);
dist.convertTo(distColor, CV_8U, 255.0/max);
applyColorMap(distColor, color, COLORMAP_JET);
imshow("", color);
waitKey();
// extract dist region corresponding to each smaller circle and find max
for(int idx = 0; idx < (int)circles.size(); idx++)
{
Mat masked;
Mat mask = Mat::zeros(im.rows, im.cols, CV_8U);
drawContours(mask, contours, circles[idx], Scalar(255, 255, 255), -1);
dist.copyTo(masked, mask);
minMaxLoc(masked, NULL, &max, NULL, &maxLoc);
circle(im, maxLoc, 4, Scalar(0, 255, 0), -1);
circle(im, maxLoc, (int)max, Scalar(0, 0, 255), 2);
cout << "rad: " << max << endl;
}
imshow("", im);
waitKey();
Kết quả (quy mô):
Hy vọng điều này sẽ hữu ích.
bạn có thể hiển thị mã HoughCircles của mình không? chồng chéo/halfcircles vv thường không phải là một vấn đề cho HoughCircles afaik. – Micka
Cảm ơn bạn Micka Tôi chỉ cần thêm một số mã – coincoin
Bạn có thể lưu maskedImage vào một tệp ('imwrite (" maskedImage.jpg ", maskedImage)') và đăng liên kết không? –