OpenCV:cvHoughCircles使用中出错
我使用cvHoughCircles查找下图中的两个白色椭圆: 我首先使用阈值定位白色区域,然后使用Hough变换。但输出不正确,如下所示: 我无法理解发生了什么?为什么它检测到3个圆,为什么只有一个圆被正确检测到?有什么建议吗 下面是我的代码:OpenCV:cvHoughCircles使用中出错,c,opencv,image-processing,hough-transform,opencvdotnet,C,Opencv,Image Processing,Hough Transform,Opencvdotnet,我使用cvHoughCircles查找下图中的两个白色椭圆: 我首先使用阈值定位白色区域,然后使用Hough变换。但输出不正确,如下所示: 我无法理解发生了什么?为什么它检测到3个圆,为什么只有一个圆被正确检测到?有什么建议吗 下面是我的代码: #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h&
#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);
}
以下是输出:
:
IplImage*src=cvLoadImage(argv[1]);
如果(!src)
{
库特宽度(1/3);
std::cout您应该使用边缘检测图像作为输入,而不是阈值。
其次,Hough圆不适用于椭圆,除非它们非常接近圆。我建议阅读并实现椭圆的Hough圆。我尽了最大努力,使用了您的参数以及以下参数:CvSeq*results=CVHough圆(图像、存储、CV_Hough_渐变,2,1);但不起作用,未检测到圆,返回>0上面的代码生成了我共享的图像。我使用了OpenCV 2.3.1。我建议您在另一台机器上进行测试。我有类似OpenCV_core240.lib的库,因此这意味着我有OpenCV 2.4。您的值4,image->width/3对应于“dp=1:分辨率的反比”,并且“检测到的中心之间的最小距离"我说的对吗?我不太清楚,但你可以通过查看OpenCV 2.3文档来了解。顺便说一句,我刚刚用OpenCV 2.3.1在Windows box上测试了我的代码,它也起了作用。也许我不熟悉OpenCV,但你不应该使用边缘图像,而不是阈值作为Hough算法的输入吗?使用Canny边缘检测,然后是by Hough变换成功了!但是当我拍摄另一张带有更多白色斑点的图像时,相同的算法失败了。@Andrey,你认为椭圆形检测应该使用相同的程序吗?(因为在我的例子中,实际上形状是椭圆形的,而不是圆形的)事实上,在canny之前进行阈值处理时,边缘可以完美地检测到。但我猜canny内部也会涉及阈值处理。因此,参数中可能存在一些问题。无论如何,您的回答对其他一些图像也适用。感谢您,应该先进行阈值处理,然后进行边缘处理,然后进行hough变换。在我的图像处理中对于近似圆形,解决方案有效,但椭圆形无效。因此,我认为广义霍夫变换可能是更好的解决方案。由于我知道白色斑点的大小和许多其他参数,所以手头的应用程序实际上要简单得多,所以在我的情况下,一些简单的方法也可能有效。
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);
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);