Java OpenCV HoughCircles未检测圆

Java OpenCV HoughCircles未检测圆,java,opencv,geometry,detection,hough-transform,Java,Opencv,Geometry,Detection,Hough Transform,我正在实现一个函数来检测图像中的圆。我正在使用OpenCVforjava来识别圆圈。灰度图像确实显示了一个圆圈 这是我的密码: Mat gray = new Mat(); Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY); Imgproc.blur(gray, gray, new Size(3, 3)); Mat edges = new Mat(); int lowThreshold = 100; int ratio = 3; Imgpro

我正在实现一个函数来检测图像中的圆。我正在使用
OpenCV
forjava来识别圆圈。灰度图像确实显示了一个圆圈

这是我的密码:

Mat gray = new Mat();
Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(gray, gray, new Size(3, 3));

Mat edges = new Mat();
int lowThreshold = 100;
int ratio = 3;
Imgproc.Canny(gray, edges, lowThreshold, lowThreshold * ratio);

Mat circles = new Mat();
Vector<Mat> circlesList = new Vector<Mat>();

Imgproc.HoughCircles(edges, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 60, 200, 20, 30, 0);

Imshow grayIM = new Imshow("grayscale");
grayIM.showImage(edges);
Mat gray=新Mat();
Imgproc.cvt颜色(img,灰色,Imgproc.COLOR\u bgr2灰色);
模糊(灰色,灰色,新尺寸(3,3));
垫边=新垫();
int低阈值=100;
整数比=3;
Imgproc.Canny(灰色、边缘、低阈值、低阈值*比率);
垫圆=新垫();
向量圈列表=新向量();
Imgproc.HOUGH圆(边,圆,Imgproc.CV_-HOUGH_梯度,1,60,200,20,30,0);
Imshow grayIM=新的Imshow(“灰度”);
灰度显示图像(边缘);

知道为什么会这样吗?

首先,正如Miki指出的那样,HughCircles应该直接应用于灰度,它有一个自己的内部Canny边缘检测器

其次,圆的参数应该根据您的特定图像类型进行调整。没有一个一刀切的公式

根据您的代码,这在一些生成的圆上对我有效:

public static void main(String[] args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    Mat img = Highgui.imread("circle-in.jpg", Highgui.CV_LOAD_IMAGE_ANYCOLOR);

    Mat gray = new Mat();
    Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.blur(gray, gray, new Size(3, 3));

    Mat circles = new Mat();
    double minDist = 60;
    // higher threshold of Canny Edge detector, lower threshold is twice smaller
    double p1UpperThreshold = 200;
    // the smaller it is, the more false circles may be detected
    double p2AccumulatorThreshold = 20;
    int minRadius = 30;
    int maxRadius = 0;
    // use gray image, not edge detected
    Imgproc.HoughCircles(gray, circles, Imgproc.CV_HOUGH_GRADIENT, 1, minDist, p1UpperThreshold, p2AccumulatorThreshold, minRadius, maxRadius);

    // draw the detected circles
    Mat detected = img.clone();
    for (int x = 0; x < circles.cols(); x++) {
        double[] c1xyr = circles.get(0, x);
        Point xy = new Point(Math.round(c1xyr[0]), Math.round(c1xyr[1]));
        int radius = (int) Math.round(c1xyr[2]);
        Core.circle(detected, xy, radius, new Scalar(0, 0, 255), 3);
    }

    Highgui.imwrite("circle-out.jpg", detected);
}
publicstaticvoidmain(字符串[]args){
System.loadLibrary(Core.NATIVE\u LIBRARY\u NAME);
Mat img=Highgui.imread(“circle in.jpg”,Highgui.CV\u LOAD\u IMAGE\u ANYCOLOR);
Mat灰色=新Mat();
Imgproc.cvt颜色(img,灰色,Imgproc.COLOR\u bgr2灰色);
模糊(灰色,灰色,新尺寸(3,3));
垫圆=新垫();
双重正念者=60;
//Canny边缘检测的阈值越高,阈值越低,阈值越小
双阈值=200;
//它越小,可能检测到的假圆越多
双P2累加器或RESHOLD=20;
int minRadius=30;
int maxRadius=0;
//使用灰色图像,而不是边缘检测
Imgproc.HOUGH圆圈(灰色,圆圈,Imgproc.CV_-HOUGH_梯度,1,Minist,p1UpperThreshold,p2累加器阈值,minRadius,maxRadius);
//绘制检测到的圆
检测到Mat=img.clone();
对于(int x=0;x
输入带圆圈的图像:

检测到的圆颜色为红色:


请注意,在输出图像中,未检测到左侧的白色圆圈非常接近白色。如果您将
p1UpperThreshold=20

设置为,您可以发布源图像并将图像传递给Houghcirle吗?如果可能,也可以使用中间图像。应在tge灰度图像上使用Houghcircles,而不是边缘图像