问题
I am using cvHoughCircles to find the two white ovals in the following image:
I first used thresholding for locating the white regions and then used Hough Transforms. But the output is not coming correct as shown below:
I am not able to understand what is happening? Why it is detecting 3 circles and why only one is being detected correctly? Any suggestions?
Below is my code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include<conio.h>
#include<malloc.h>
using namespace cv;
using namespace std;
int main( ) {
IplImage* image = cvLoadImage(
"testing.bmp",
CV_LOAD_IMAGE_GRAYSCALE
);
IplImage* src = cvLoadImage("testing.bmp");
CvMemStorage* storage = cvCreateMemStorage(0);
cvThreshold( src, src, 200, 255, CV_THRESH_BINARY );
CvSeq* results = cvHoughCircles(
image,
storage,
CV_HOUGH_GRADIENT,
3,
image->width/10
);
for( int i = 0; i < results->total; i++ )
{
float* p = (float*) cvGetSeqElem( results, i );
CvPoint pt = cvPoint( cvRound( p[0] ), cvRound( p[1] ) );
cvCircle(
src,
pt,
cvRound( p[2] ),
CV_RGB(0xff,0,0)
);
}
cvNamedWindow( "HoughCircles", 1 );
cvShowImage( "HoughCircles", src);
cvWaitKey(0);
}
Edit:
Since I am not get satisfactory results with Hough Transform, I am willing to go for some other way. I can assume that each white blob in the figure is of equal size (size is known)and also the distance between the blob is known. Is there a non-trivial way I can find a vertical line (a tangent) touching the left side of left white blob? Once I know this tangent, I get an idea of the boundary location, then I will draw a circle at x=(this location + radius(which is known)), y= this location. Can I find such x and y coordinates using some non-trivial ways?
Solved, by changing as per below:
cvThreshold(image, image, 220, 255, CV_THRESH_BINARY );
cvCanny(image, image, 255, 255, 3);
cvNamedWindow( "edge", 1 );
cvShowImage( "edge", image);
cvWaitKey(0);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* results = cvHoughCircles(
image,
storage,
CV_HOUGH_GRADIENT,
4,
image->width/4, 100,100,0,50);
Here is the output:
回答1:
You should use edge detected image as input, not the thresholded. Secondly, Hough circles will not work for elipses, unless they are very close to circles. I recommend reading about Generalized Hough Transform and implementing it for ellipses.
回答2:
It's all about the parameters:
IplImage* src = cvLoadImage(argv[1]);
if (!src)
{
cout << "Failed: unable to load image " << argv[1] << endl;
return -1;
}
//IplImage* image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
IplImage* image = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
cvCvtColor(src, image, CV_RGB2GRAY);
cvThreshold(image, image, 220, 255, CV_THRESH_BINARY );
// cvNamedWindow( "thres", 1 );
// cvShowImage( "thres", image);
// cvWaitKey(0);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* results = cvHoughCircles(
image,
storage,
CV_HOUGH_GRADIENT,
4,
image->width/3);
std::cout << "> " << results->total << std::endl;
for( int i = 0; i < results->total; i++ )
{
float* p = (float*) cvGetSeqElem( results, i );
CvPoint pt = cvPoint( cvRound( p[0] ), cvRound( p[1] ) );
cvCircle(src,
pt,
cvRound( p[2] ),
CV_RGB(0xff,0,0));
}
cvNamedWindow( "HoughCircles", 1 );
cvShowImage( "HoughCircles", src);
cvWaitKey(0);
If you've done a little bit more experimentation you would have eventually found out that with different parameters you get different results:
来源:https://stackoverflow.com/questions/10653433/opencv-error-in-cvhoughcircles-usage