Hello,
I am attempting to detect a yellow ball (as seen here) using the hough circle transform. However, after applying my mask using inRange, I still have a lot of noise and the hough circle transform is detecting non-existent circles.
Here is an image with the mask applied.
My HSV values are:
lower - 20, 0, 100
upper - 40, 255, 255
Thank you in advanced for your help!
Hi.
I couldn’t reproduce your binary image with lower - 20, 0, 100 and upper - 40, 255, 255, I think you have done some mistakes. Please tell us what was your right values.
Btw i did these steps on your provided binary image :
1 - I did erosion on your binary image , so it removed most of noises from your image.
There is a good example for erosion operation in official docs
2- You can now find the ball circle with hough transform :
This is my my code . Hope it would be helpful.
Mat img = imread(“/home/eaglesoft/Downloads/Screenshot (58).png”);
Mat gray_img;
cvtColor(img,gray_img,COLOR_BGR2GRAY);
Mat erosion_dst;
int erosion_type = MORPH_RECT;
int erosion_size = 2;
Mat element = getStructuringElement( erosion_type,
Size( 2erosion_size + 1, 2erosion_size+1 ),
Point( erosion_size, erosion_size ) );
erode( gray_img, erosion_dst, element );
vector circles;
HoughCircles(erosion_dst, circles, HOUGH_GRADIENT, 1, img.rows/64, 200, 10,75, 120);
for(size_t i=0; i<circles.size(); i++) {
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle(img, center, radius, Scalar(0, 0, 255), 2, 8, 0);
}
imshow(“erosion”,img);
waitKey(0);
I investigated your picture some.
the issue here is that the background (wood) is very similar in color to your ball. you need a different ball or different background.
Do not forget, that HoughCircles also works with grayscale image so binarisation of image si not necessary.
Result:
CPP example:
// Read ball image
cv::Mat ball = cv::imread("ball.png");
// Convert ball image to grayscale
cv::Mat gray;
cv::cvtColor(ball, gray, cv::COLOR_BGR2GRAY);
// Detect ball
vector<cv::Vec3f> circles;
cv::HoughCircles(gray, circles, cv::HOUGH_GRADIENT, 1,
gray.cols, // Minimal circle distance set to width of frame to find only one ball
100, 20,
70, // Minimal radius of ball [px]
100 // Maximal radius of ball [px]
);
// Draw found circles
for (const auto& c: circles)
{
cv::Point center = cv::Point(c[0], c[1]);
// Circle center
cv::circle(ball, center, 1, cv::Scalar(0, 0, UCHAR_MAX), 3, cv::LINE_AA);
// Circle outline
int radius = c[2];
cv::circle(ball, center, radius, cv::Scalar(0, 0, 0), 2, cv::LINE_AA);
cv::circle(ball, center, radius, cv::Scalar(UCHAR_MAX, UCHAR_MAX, UCHAR_MAX), 1, cv::LINE_AA);
}
1 Like