Tuesday 9 March 2021

OpenCV - find blackboard edges on video and images

UPDATE

You can find all the images I have for testing on my GitHub here:

GitHub repository with sources

There are also 2 videos, where the detection should work on as well

ORIGINAL QUESTION

I tried to use OpenCV 4.x.x to find the edges of a blackboard (image following), but somehow I cannot succeed. My code at the moment looks like this: (Android with OpenCV and live camera feed), where imgMat is a Mat from the camera feed:

    Mat gray = new Mat();
    Imgproc.cvtColor(imgMat, gray, Imgproc.COLOR_RGB2BGR);

    Mat blurred = new Mat();
    Imgproc.blur(gray, blurred, new org.opencv.core.Size(3, 3));

    Mat canny = new Mat();
    Imgproc.Canny(blurred, canny, 80, 230);

    Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new org.opencv.core.Size(2, 2));
    Mat dilated = new Mat();
    Imgproc.morphologyEx(canny, dilated, Imgproc.MORPH_DILATE, kernel, new Point(0, 0), 10);
    Mat rectImage = new Mat();
    Imgproc.morphologyEx(dilated, rectImage, Imgproc.MORPH_CLOSE, kernel, new Point(0, 0), 5);
    Mat endproduct = new Mat();
    Imgproc.Canny(rectImage, endproduct, 120, 230);

    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(endproduct, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = 0;
    boolean hasContour = false;
    MatOfPoint2f biggestContour = new MatOfPoint2f();
    Iterator<MatOfPoint> each = contours.iterator();
    while (each.hasNext()) {
        MatOfPoint wrapper = each.next();
        double area = Imgproc.contourArea(wrapper);
        if (area > maxArea) {
            maxArea = area;
            biggestContour = new MatOfPoint2f(wrapper.toArray());
            hasContour = true;
        }
    }

    if (hasContour) {
        Mat output = imgMat.clone();

        MatOfPoint2f approx = new MatOfPoint2f();
        MatOfPoint poly = new MatOfPoint();

        Imgproc.approxPolyDP(biggestContour, approx, Imgproc.arcLength(biggestContour, true) * .02, true);
        approx.convertTo(poly, CvType.CV_32S);

        Rect rect = Imgproc.boundingRect(poly);

     }

Somehow I am not able to get it working, although the same code(written in python) worked on my computer with a video. I take the output from the rectangle and display it on my mobile screen, where it flickers around a lot and does not work properly.

These are my images I tried the python program on, and they worked:

big blackboard

big blackboard2

What am I doing wrong? I am not able to constantly detect the edges of the blackboard.

Additional information about the blackboard:

  • always rectangular
  • may have different lighting
  • the text should be ignored, only the main board should be detected
  • the outer blackboard should be ignored as well
  • only the contour for the main board should be shown/returned

Thanks for any advice or code!



from OpenCV - find blackboard edges on video and images

No comments:

Post a Comment