使用android opencv进行硬币检测

时间:2013-11-26 07:45:52

标签: android opencv bitmap

我正在尝试使用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,但它不够好。

0 个答案:

没有答案