Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect objects similar to circles

Tags:

opencv

I'm trying to detect objects that are similar to circles using OpenCV's HoughCircles. The problem is: HoughCircles fails to detect such objects in some cases.

Does anyone know any alternative way to detect objects similar to circles like these ones?

Update enter image description here

Update

Hello Folks I'm adding a gif of the result of my detection method.

enter image description here

It's easier use a gif to explain the problem. The undesired effect that I want to remove is the circle size variation. Even for a static shape like the one on the right, the result on the left is imprecise. Does anyone know a solution for that?

Update All that I need from this object is its diameter. I've done it using findContours. Now I can't use findContours once it is too slow when using openCV and OpenMP. Does anyone know a fast alternatives to findContours?

Update

The code that I'm using to detect these shapes.

     for (int j=0; j<=NUM_THREADS-1;j++)
        {
            capture >> frame[j];
        }


        #pragma omp parallel shared(frame,processOutput,circles,diameterArray,diameter) 
        {  

            int n=omp_get_thread_num();
            cvtColor( frame[n], processOutput[n], CV_BGR2GRAY);

            GaussianBlur(processOutput[n],  processOutput[n],  Size(9, 9), 2, 2);
            threshold(processOutput[n],  processOutput[n], 21, 250, CV_THRESH_BINARY);

            dilate(processOutput[n],  processOutput[n], Mat(), Point(-1, -1), 2, 1, 1);
            erode(processOutput[n],  processOutput[n], Mat(), Point(-1, -1), 2, 1, 1);

            Canny(processOutput[n],  processOutput[n], 20, 20*2, 3 );

            HoughCircles( processOutput[n],circles[n], CV_HOUGH_GRADIENT, 1, frame[n].rows/8, 100,21, 50, 100);

        }

        #pragma omp parallel private(m, n) shared(circles)
        {
            #pragma omp for
            for (n=0; n<=NUM_THREADS-1;n++)
            {
                for( m = 0; m < circles[n].size(); m++ ) 
                {
                    Point center(cvRound(circles[n][m][0]), cvRound(circles[n][m][2]));
                    int radius = cvRound(circles[n][m][3]);
                    diameter = 2*radius;
                    diameterArray[n] = diameter;
                    circle( frame[0], center, 3, Scalar(0,255,0), -1, 8, 0 );
                    circle( frame[0], center, radius, Scalar(0,0,255), 3, 8, 0 );
                }   
            }
        }
like image 925
MSO Avatar asked Mar 08 '14 20:03

MSO


People also ask

What algorithm is used to detect circles?

Automatic circle detection is an important element of many image processing algorithms. Traditionally the Hough transform has been used to find circular objects in images but more modern approaches that make use of heuristic optimisation techniques have been developed.

What algorithm is used to detect circles in OpenCV?

cv2. HoughCircles(image, method, dp, minDist) Where Image is the image file converted to grey scale Method is the algorithm used to detct the circles. Dp is the inverse ratio of the accumulator resolution to the image resolution. minDist is the Minimum distance between the center coordinates of detected circles.

How does Hough circle transform work?

The circle Hough Transform (CHT) is a basic feature extraction technique used in digital image processing for detecting circles in imperfect images. The circle candidates are produced by “voting” in the Hough parameter space and then selecting local maxima in an accumulator matrix.


1 Answers

Edited based on new description and additional performance and accuracy requirements.


This is getting beyond the scope of an "OpenCV sample project", and getting into the realm of actual application development. Both performance and accuracy become requirements.

This requires a combination of techniques. So, don't just pick one approach. You will have to try all combinations of approaches, as well as fine-tune the parameters to find an acceptable combination.


#1. overall approach for continuous video frame recognition tasks

  • Use a slow but accurate method to acquire an initial detection result.

  • Once a positive detection is found on one frame, the next frame should switch to a fast local search algorithm using the position detected on the most recent frame.

As a reminder, don't forget to update the "most recent position" for use by the next frame.


#2. suggestion for initial object acquisition.

  • Stay with your current approach, and incorporate the suggestions.

  • You can still fine-tune the balance between speed and precision, because a correct but imprecise result (off by tens of pixels) will be updated and refined when the next frame is processed with the local search approach.

    • Try my suggestion of increasing the dp parameter.

A large value of dp reduces the resolution at which Hough Gradient Transform is performed. This reduces the precision of the center coordinates, but will improve the chance of detecting a dented circle because the dent will become less significant when the transform is performed at a lower resolution.

An added benefit is that reduced resolution should run faster.


#3. suggestion for fast local search around a previously detected position

Because of the limited search space and amount of data needed, it is possible to make local search both fast and precise.

For tracking the movement of the boundary of iris through video frames, I suggest using a family of algorithms called the Snakes model.

The focus is on tracking the movement of edges through profiles. There are many algorithms that can implement the Snakes model. Unfortunately, most implementations are tailored to very complex shape recognition, which would be an overkill and too slow for your project.

Basic idea: (assuming that the previous result is a curve)

  1. Choose some sampling points on the curve.
  2. Scan the edge profile (perpendicular to the curve) at each the sampling point, on the new frame, using the position of the old frame. Look for the sharpest change.
  3. Remember the new edge position for this sampling point.
  4. After all of the sampling points have been updated, create a new curve by joining all of the updated sampling point positions.

There are many varieties, and different levels of sophistication of implementations which you can find on the Internet. Unfortunately, it was reported that the one packaged with OpenCV might not work very well. You may have to try different open-source implementation, and ultimately you may have to implement one that is simple but well-tuned to your project's needs.


#4. Seek advice for your speed optimization attempts.

  • Use a software performance profiler.

  • Add some timing and logging code around each call to OpenCV function to print out the time spent on each step. You will be surprised. The reason is that some OpenCV functions are more heavily vectorized and parallelized than others, perhaps as a result of the labor of love.

  • Unfortunately, for the slowest step - initial object acquisition, there is not much you can parallelize (by multithread).

This is perhaps already obvious to you since you did not put #pragma omp for around the first block of code. (It would not help anyway.)

  • Vectorization (SIMD) would only benefit pixel-level processing. If OpenCV implements it, great; if not, there is not much you can do.

My guess is that cvtColor, GaussianBlur, threshold, dilate, erode could have been vectorized, but the others might not be.


like image 197
rwong Avatar answered Oct 04 '22 02:10

rwong