我正在尝试使用Opencv4Android检测硬币(圆圈)检测 . 到目前为止,我尝试了两种方法

1)常规方法:

// convert image to grayscale
Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGBA2GRAY);
// apply Gaussian Blur 
Imgproc.GaussianBlur(mGray, mGray, sSize5, 2, 2);

iMinRadius = 20;
iMaxRadius = 400;
iAccumulator = 300;
iCannyUpperThreshold = 100;

//apply houghCircles 
Imgproc.HoughCircles(mGray, mIntermediateMat, Imgproc.CV_HOUGH_GRADIENT, 2.0, mGray.rows() / 8, 
  iCannyUpperThreshold, iAccumulator, iMinRadius, iMaxRadius);
    if (mIntermediateMat.cols() > 0)
    for (int x = 0; x < Math.min(mIntermediateMat.cols(), 10); x++) {
      double vCircle[] = mIntermediateMat.get(0,x);
        if (vCircle == null)
          break;
          pt.x = Math.round(vCircle[0]);
          pt.y = Math.round(vCircle[1]);
          radius = (int)Math.round(vCircle[2]);
          // draw the found circle
          Core.circle(mRgba, pt, radius, colorRed, iLineThickness);
   }

2)Sobel然后Hough Cicles

// apply Gaussian Blur 
    Imgproc.GaussianBlur(mRgba, mRgba, sSize3, 2, 2,
            Imgproc.BORDER_DEFAULT);

    // / Convert it to grayscale
    Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGBA2GRAY);
    // / Gradient X

    Imgproc.Sobel(mGray, grad_x, CvType.CV_16S, 1, 0, 3, scale, delta,
            Imgproc.BORDER_DEFAULT);
    Core.convertScaleAbs(grad_x, abs_grad_x);

    // / Gradient Y
    Imgproc.Sobel(mGray, grad_y, CvType.CV_16S, 0, 1, 3, scale, delta,
            Imgproc.BORDER_DEFAULT);
    Core.convertScaleAbs(grad_y, abs_grad_y);
    // / Total Gradient (approximate)
    Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);

    iCannyUpperThreshold = 100;

    Imgproc.HoughCircles(grad, mIntermediateMat,
            Imgproc.CV_HOUGH_GRADIENT, 2.0, grad.rows() / 8,
            iCannyUpperThreshold, iAccumulator, iMinRadius, iMaxRadius);

    if (mIntermediateMat.cols() > 0)
        for (int x = 0; x < Math.min(mIntermediateMat.cols(), 10); x++) {
            double vCircle[] = mIntermediateMat.get(0, x);

            if (vCircle == null)
                break;

            pt.x = Math.round(vCircle[0]);
            pt.y = Math.round(vCircle[1]);
            radius = (int) Math.round(vCircle[2]);
            // draw the found circle
            Core.circle(mRgba, pt, radius, colorRed, iLineThickness);
    }

方法一在硬币检测的情况下给出公平的结果,方法二给出更好的结果

在这两种方法中,第二种方法处理很慢但结果很好

当使用来自opencv库的JavaCameraView或NativeCameraView捕获相机frmae时,这两种方法都有效 .

如果我在从返回Bitmap的android天真图像捕获意图中捕获的图像上使用相同的程序,我根本无法得到任何结果,即根本没有检测到圆圈 .

在方法一中,有时我会在使用使用Android摄像头意图捕获的Bitmap时检测到圆圈 .

我也尝试按照Post中的建议更改捕获的位图,但仍然没有圆检测 .

任何人都可以告诉我我必须做什么修改 .

而且我想知道哪种算法可以在硬币(圆圈)检测中提供更好的结果,但处理更少 .

我已经使用了houghCircle方法的各种值,并尝试将canny edge输出作为输入到houghCircles,但它不够好 .