Ask Your Question

# Hough Transform sort output vector

Hello!

I wrote a code for detcting some circle, but i dont understand how the Hough Transform sort the output.

My program is runing like this

1. I have six circle that are positioned like this

1. i need to detect the cirlces and then make de half distance between the ccenters of circles two by two like this

• the blue dots are the half distances between circles two by two

Now the real example is something like this

For case 1 it works

But when i process a photo like this

Circles are sorted like this :

HERE IS MY CODE : http://pastebin.com/9WrsMtNQ

edit retag close merge delete

## 1 answer

Sort by ยป oldest newest most voted

I am not quite sure after which parameter the circles are sorted, but I ask you: do you actually need that at all? You have the circles and now you are interested in each mid-point between the two closest circles. So, what you only need is to search for the nearest center of each circle.

std::vector<cv::Vec3f> circles;
cv::Mat edges;
GaussianBlur( img, img, cv::Size(9, 9), 3, 3 );
cv::Canny( img, edges, 50, 100, 3);
HoughCircles( edges, circles, CV_HOUGH_GRADIENT, 1, img.rows / 8, 80, 10, 25, 70 );
std::vector<bool> visited(circles.size(),false);

// search now for the nearest circle
for( size_t i =0; i < circles.size(); i++){
visited[i] = true;
float min_dist = std::numeric_limits<float>::max();
// set nearest circle idx first to -1
int nearest_circle_idx = -1;
for( size_t k =0; k < circles.size(); k++){
if (visited[k]) continue;
// choose squared Eudlidian distance
float dist = (circles[i][0]-circles[k][0])*(circles[i][0]-circles[k][0])
+(circles[i][1]-circles[k][1])*(circles[i][1]-circles[k][1])
if( dist < min_dist) {
nearest_circle_idx = k;
min_dist = dist;
}
}
if ( nearest_circle_idx == -1) continue;

// we don't need to visit nearest circle any more
visited[ nearest_circle_idx ] = true;

// now compute half distance between circles:
int x_half = (circles[i][0]+circles[nearest_circle_idx][0]) / 2;
int y_half = (circles[i][1]+circles[nearest_circle_idx][1]) / 2;

// do whatever you actually wanted now to do with that point
// ...
cv::circle( img, cv::Point(x_half,y_half), 3, cv::Scalar(0,0,255), -1, 8, 0 );
}


My result image:

more

## Comments

Thanks for help!

( 2015-02-15 12:42:10 -0600 )edit
1

My problem was solved! Just a little adjustemnt at the code (for anybody who looks at this post). The index "i" need to go only to contours.size()/2, beacause if it goes after the nearest_circles_idx will be -1 and will be out of range of the array visited[] and will give an error of "Vector<bool> : iterator not dereferencable".

Thank you very much Guanta for your help!

( 2015-02-15 19:06:40 -0600 )edit

Ah yes you are right, however I wouldn't use contours.size() / 2 since then maybe not all circles will be used. But an if clause after the inner loop like if ( nearest_circle_idx == -1) continue; should do the job.

( 2015-02-16 03:24:21 -0600 )edit

I have edited my answer accordingly.

( 2015-02-16 06:49:31 -0600 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2015-02-15 09:38:54 -0600

Seen: 2,093 times

Last updated: Feb 16 '15