S
S
schroeder2014-11-21 20:16:27
OpenCV
schroeder, 2014-11-21 20:16:27

How to find an object in an image?

Good day to all.
There is the following problem. There is an image, as a rule it looks something like this:
b25f664dde5a42b7ac7ce9810f36f644.bmp
On this image, you need to find and read the DataMatrix codes, these are those in black circles. I was looking for a ready-made open source solution. The following options have been found:

  1. Zxing, but it only works if the code is centered and rotated properly
  2. Dmtx, I couldn't compile it. I created a question about this, but unfortunately nothing came of it.

Therefore, it was decided to write your own bike. Java and openCV were taken.
The idea is to find the codes, find out what angle they are rotated to, rotate them and feed them to the Zxing library.
I did the following.
First I find the circles, it works more or less:
873ef8907d834949a1c93891bd3b4698.bmp
Those areas that are in the circles I cut out. In doing so, I take a slightly larger circle size than was calculated. This is done to accurately get the area with the code. It turns out something like this:
0e5b3433662b4620bf6a36b8aace22a8.bmp
As you can see, two white lines stand out clearly in the image:
6d89c4fe9a2246358b9e371387e88a2e.bmp
If you find them, it will be clear where the code is and at what angle it is rotated. For this, I'm looking for straight lines. The code is like this:
Mat binImage = new Mat(image.rows(), image.cols(), image.type());
        Imgproc.GaussianBlur(image, binImage, new Size(5, 5), 5, 5);
        Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 5, 0);
        double iCannyLowerThreshold = 25;
        double iCannyUpperThreshold = 70;
        Imgproc.Canny(binImage, binImage, iCannyLowerThreshold, iCannyUpperThreshold);
        Highgui.imwrite("lines/cannyImage_" + counter + ".bmp", binImage);

        List<Line> result = new ArrayList<Line>();
        Mat lines = new Mat();
        int linesThreshold = 20;
        int linesMinLineSize = 35;
        int linesGap = 5;
        Imgproc.HoughLinesP(binImage, lines, 1, Math.PI / 180, linesThreshold, linesMinLineSize, linesGap);

        for (int x = 0; x < lines.cols(); x++) {
            double[] vecHoughLines = lines.get(0, x);

            if (vecHoughLines.length == 0)
                break;

            double x1 = vecHoughLines[0];
            double y1 = vecHoughLines[1];
            double x2 = vecHoughLines[2];
            double y2 = vecHoughLines[3];
            Point pt1 = new Point();
            Point pt2 = new Point();

            pt1.x = x1;
            pt1.y = y1;
            pt2.x = x2;
            pt2.y = y2;
            result.add(new Line(pt1, pt2));
            Core.line(image, pt1, pt2, new Scalar(255, 0, 0, 255), 2);
        }

Unfortunately the results are not very good. After Canny, the image looks like this:
7253d3f2a01f4daf881512f918351763.bmp
Everything seems to be fine, two straight lines are clearly visible. But after searching for straight lines, the wrong straight line was found at all:
db94b0e3f0d34b07bfd42ccb7160078f.bmp
I played around with the parameters for a long time and, unfortunately, did not find a good option. Do not tell me where else to dig, is it possible to find this code in another way? Thanks in advance.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Sofonov, 2014-11-21
@sofcom

Defined the circles, the QR code is supposed to be in the circles. Throw this QR code into a library that works with these codes, without aligning, clearing everything behind the circles

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question