I’m trying to locate orange balls from a video camera.
I’m converting each frame to HSV, blurring it, and using inRange to filter the orange color. I then apply the HoughCircles function but I can’t find the right parameters.
When it works, it’s not very stable: the circle is not always detected.
Here is a screenshot plus the code of the setup:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <vector>
using namespace cv;
int hmin[2] = {2,0}, smin[2] = {163,104}, vmin[2] = {16,29};
int hmax[2] = {16,25}, smax[2] = {255, 255}, vmax[2] = {212,255};
int p1 = 6, p2 = 12;
int f1 = 9, f2 = 3;
int main() {
VideoCapture cap(0);
if(!cap.isOpened()) {
fprintf( stderr, "ERROR: capture is NULL \n" );
return -1;
}
namedWindow( "couleur", CV_WINDOW_AUTOSIZE );
namedWindow( "filtre1", CV_WINDOW_AUTOSIZE );
createTrackbar("hmin[0]", "filtre1", &hmin[0], 180, NULL);
createTrackbar("smin[0]", "filtre1", &smin[0], 255, NULL);
createTrackbar("vmin[0]", "filtre1", &vmin[0], 255, NULL);
createTrackbar("hmax[0]", "filtre1", &hmax[0], 180, NULL);
createTrackbar("smax[0]", "filtre1", &smax[0], 255, NULL);
createTrackbar("vmax[0]", "filtre1", &vmax[0], 255, NULL);
namedWindow( "hough", CV_WINDOW_AUTOSIZE );
createTrackbar("p1", "hough", &p1, 500, NULL);
createTrackbar("p2", "hough", &p2, 500, NULL);
createTrackbar("f1", "hough", &f1, 30, NULL);
createTrackbar("f2", "hough", &f2, 30, NULL);
std::vector<Vec3f> cercle;
while ( 1 ) {
Mat frame, hsv, orange;
cap >> frame;
f1 = f1%2?f1:f1+1;
cvtColor(frame, hsv, CV_BGR2HSV);
GaussianBlur(hsv, hsv, Size(f1, f1), f2, f2 );
inRange(hsv, Scalar(hmin[0],smin[0],vmin[0]), Scalar(hmax[0],smax[0],vmax[0]), orange);
if(p1 <= 0)
p1 = 1;
if(p2 <= 0)
p2 = 1;
HoughCircles(orange, cercle, CV_HOUGH_GRADIENT, 2, orange.rows/4, p1, p2, 0, 30);
for(uint i = 0; i < cercle.size(); i++) {
Point c(cvRound(cercle[i][0]), cvRound(cercle[i][1]));
int r = cvRound(cercle[i][2]);
circle(frame, c, 3, Scalar(0,255,0), -1, 8, 0);
circle(frame, c, r, Scalar(255,0,0), 3, 8, 0);
printf("%d) %d %d %d\n", i, c.x, c.y, r);
}
printf("---\n");
cercle.clear();
imshow("couleur", frame );
imshow("filtre1", orange );
if ( (waitKey(10) & 255) == 27 ) break;
}
return 0;
}
Here are some parameters that work.
param1 (upper threshold for the internal Canny edge detector) is fixed at 100
before passing image in to HoughCircles() the image is converted to grayscale and a median blur of ksize 5 is applied.
Although this works for this one still frame, I am sure that a series of video frames will show a fair amount of variation and instability. For example, it’s quite tricky to find settings for this image that pick out both of the balls but don’t also select the white labels on the boxes.