检测颜色的圆圈会导致OpenCV中“图像必须在HoughCircle中为8位单通道”错误

问题描述 投票:0回答:1

我正在构建一个Android应用程序,并且希望能够检测到黑眼圈。我正在使用适用于Android的OpenCV3,并且可以使用以下代码从相机Feed中滤除黑色。请注意,我使用了Android SDK中给出的Color-blob-detection示例,并对代码进行了如下调整:

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();

    if (mIsColorSelected) {

        Bitmap resultBitmap;

        resultBitmap = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(),Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(mRgba, resultBitmap);

        //TODO - look for circles
        Mat mat = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
        Utils.bitmapToMat(resultBitmap, mat);

        final Bitmap bitmap;

        //TODO - filter out the black only
        Mat mHSV = mat;
        Mat mHSVThreshed = mat;
        Mat mRgba2 = mat;

        Imgproc.cvtColor(mat, mHSV, Imgproc.COLOR_BGR2HSV, 0);
        Core.inRange(mHSV, new Scalar(0, 0, 0), new Scalar(130, 130, 130), mHSVThreshed);
        Imgproc.cvtColor(mHSVThreshed, mat, Imgproc.COLOR_GRAY2BGR, 0);
        Imgproc.cvtColor(mat, mRgba2, Imgproc.COLOR_BGR2RGBA, 0);

        Imgproc.GaussianBlur(mRgba2, mRgba2, new Size(9, 9), 2, 2);

        //this is for displaying purposes only. 
        //At this point, the image would be black and white, where the white spots are the black detected blobs 
        //            Bitmap bmp = Bitmap.createBitmap(mRgba2.cols(), mRgba2.rows(), Bitmap.Config.ARGB_8888);
        //Utils.matToBitmap(mRgba2, bmp);
       //bitmap = bmp; //resultBitmap;

        //TODO - new circle detection code: this uses the colour filtered Mat
        mat = mRgba2;
        Imgproc.HoughCircles(mat, circles,
                Imgproc.CV_HOUGH_GRADIENT, 1, minDist, 100,
                20, 0, 0);

        /* get the number of circles detected */
        int numberOfCircles = (circles.rows() == 0) ? 0 : circles.cols();

        /* draw the circles found on the image */
        for (int i = 0; i < numberOfCircles; i++) {

        /* get the circle details, circleCoordinates[0, 1, 2] = (x,y,r)
         * (x,y) are the coordinates of the circle's center
         */

            double[] circleCoordinates = circles.get(0, i);

            int x = (int) circleCoordinates[0], y = (int) circleCoordinates[1];

            Point center = new Point(x, y);
            int radius = (int) circleCoordinates[2];

            /* circle's outline */
            Imgproc.circle(mRgba2, center, radius, new Scalar(0,
                    200, 255), 4);

            /* circle's center outline */
            Imgproc.rectangle(mRgba2, new Point(x - 5, y - 5),
                    new Point(x + 5, y + 5),
                    new Scalar(0, 200, 255), -1);
        }
        Utils.matToBitmap(mRgba2, resultBitmap);

        bitmap = resultBitmap;

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mOpenCvCameraView.disableView();
                mOpenCvCameraView.setVisibility(SurfaceView.GONE);
                imageView.setVisibility(View.VISIBLE);
                imageView.setImageBitmap(bitmap);
            }
        });
    }
    return mRgba;
}

我的代码所做的是,将相机Feed的快照作为Mat拍摄,然后使用该Mat对其进行一些图像处理,以将除黑色以外的所有颜色涂黑。生成的Mat是mRgba2变量,我转换为Bitmap并显示在ImageView上。我显示了此位图,以确认我得到了想要的结果。

[我知道我能够滤除想要的颜色后,然后在其上运行GaussianBlur,然后继续运行HoughCircles。但是,当我运行

Imgproc.HoughCircles(mat, circles,
        Imgproc.CV_HOUGH_GRADIENT, 1, minDist, 100,
        20, 0, 0);

行,我得到一个

The source image must be 8-bit, single-channel in function CvSeq* cvHoughCircles(CvArr*, void*, int, double, double, double, double, int, int)

错误。

我知道我在给定的mat变量上运行HoughCircles的代码有效,因为我之前已经对其进行过测试。现在,更改我提供给它的mat变量不会,而且我想知道我为使代码无法工作做了什么不同的事情。

android opencv bitmap
1个回答
2
投票

HoughCircles仅在灰度(CV8U)图像上运行。

替换

Imgproc.cvtColor(mat, mRgba2, Imgproc.COLOR_BGR2RGBA, 0);

with

Imgproc.cvtColor(mat, mRgba2, Imgproc.COLOR_BGR2GRAY, 0);

应删除错误。

然后问题是检测给定颜色的圆圈。在您的情况下,这不会造成太大问题,因为无论如何您都检测到黑眼圈。代替黑眼圈,这将检测到黑眼圈。

如果某些圆圈中的颜色不是黑色,则可以通过查看不同颜色空间中的像素值来分别过滤掉它们。

© www.soinside.com 2019 - 2024. All rights reserved.