Ask Your Question
2

Hough Transform sort output vector

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

Graver gravatar image

updated 2015-09-04 14:57:52 -0600

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

image description

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

image description

  • 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

image description

But when i process a photo like this

image description

Circles are sorted like this :

image description

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

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
4

answered 2015-02-15 10:56:40 -0600

Guanta gravatar image

updated 2015-02-16 06:48:56 -0600

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: Result

edit flag offensive delete link more

Comments

Thanks for help!

Graver gravatar imageGraver ( 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!

Graver gravatar imageGraver ( 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.

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

I have edited my answer accordingly.

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

Question Tools

1 follower

Stats

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

Seen: 2,185 times

Last updated: Feb 16 '15