OpenCV:cvHoughCircles使用中出错

我使用cvHoughCircles在下图中找到两个白色椭圆:

在此处输入图像描述

我首先使用阈值来定位白色区域,然后使用霍夫变换。 但输出结果不正确,如下所示:

在此处输入图像描述

我无法理解发生了什么? 为什么它检测到3个圆圈以及为什么只有一个被正确检测? 有什么建议?

以下是我的代码:

#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include  #include  #include  #include  #include  #include "opencv/cv.h" #include "opencv/highgui.h" #include #include 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 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); } 

编辑:

由于Hough变换不能得到令人满意的结果,我愿意采取其他方式。 我可以假设图中的每个白色斑点都具有相同的大小(大小已知),并且斑点之间的距离也是已知的。 是否有一种非平凡的方式我可以找到一条垂直线(一条切线)触及左侧白色斑点的左侧? 一旦我知道这个切线,我就会知道边界位置,然后我会在x =(这个位置+半径(已知))绘制一个圆,y =这个位置。 我可以使用一些非平凡的方法找到这样的x和y坐标吗?

通过以下更改解决:

 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); 

这是输出:

在此处输入图像描述

您应该使用边缘检测图像作为输入,而不是阈值。 其次,除非它们非常靠近圆圈,否则霍夫圆圈不适用于椭圆形。 我建议阅读有关广义Hough变换的内容并将其实现为省略号。

这些都 与参数有关 :

 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); 

如果你做了一些实验,你最终会发现使用不同的参数可以得到不同的结果 :