Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android OpenCV Improving detection quality

Currently I am developing an app, which will detect circles from photos. I have managed to write a code for this, but it either does false negatives or false positives, if I get phone a bit away from PC screen. How can I improve the result?I mean, there are lots of apps that detect small and unclear circles.

[Update]

I'm fiddling with values in GaussianBlur and HoughCircles. Changing Imgproc.GaussianBlur(grayMat, grayMat, new Size(9, 9), 2, 2); to Imgproc.GaussianBlur(grayMat, grayMat, new Size(9, 9), 9, 9); and double param1 = 70, param2 = 72; to double param1 = 50, param2 = 52; improve the result, but not enough.

            Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
                    CvType.CV_8UC1);
            Mat grayMat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
                    CvType.CV_8UC1);

            Utils.bitmapToMat(bitmap, mat);

            int colorChannels = (mat.channels() == 3) ? Imgproc.COLOR_BGR2GRAY
                    : ((mat.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);

            Imgproc.cvtColor(mat, grayMat, colorChannels);


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

            // accumulator value
            double dp = 1.2d;
            // minimum distance between the center coordinates of detected circles in pixels
            double minDist = 100;


            int minRadius = 0, maxRadius = 0;

            double param1 = 70, param2 = 72;


            Mat circles = new Mat(bitmap.getWidth(),
                    bitmap.getHeight(), CvType.CV_8UC1);


            Imgproc.HoughCircles(grayMat, circles,
                    Imgproc.CV_HOUGH_GRADIENT, dp, minDist, param1,
                    param2, minRadius, maxRadius);


            int numberOfCircles = 9;

            if (numberOfCircles > circles.cols()){ 
                numberOfCircles = circles.cols();
             }


            for (int i=0; i<numberOfCircles;  i++) {



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



                if(circleCoordinates == null){
                break;
                 }



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

                Point center = new Point(x, y);
                android.graphics.Point centerC = new android.graphics.Point(x, y);

                int radius = (int) circleCoordinates[2];



                Core.circle(mat, center, radius, new Scalar(0,
                        255, 0), 4);


                Core.rectangle(mat, new Point(x - 5, y - 5),
                        new Point(x + 5, y + 5),
                        new Scalar(0, 128, 255), -1);

Thanks in advance.

Right now I use those A-shaped points to test the code, but I want to detect even smaller circles on the photo. enter image description here

like image 913
Oleksandr Firsov Avatar asked Jul 05 '15 20:07

Oleksandr Firsov


1 Answers

I think, if you want to detect only white circles, you need to implement color detection. Not only it will greatly improve detection quality, but remove a lot of false positives and negatives. Using color detection is pretty simple, since it is already present in OpenCV. For this use Core.inRange function. You can find more about it here. But probably the best thing for you would be follow this tutorial. It was written in Python, but it's understandable and you need to change only few lines to get it work for android. Hope this helps :)

like image 108
Oleksandr Firsov Avatar answered Oct 04 '22 18:10

Oleksandr Firsov