OpenCV different go board detection approach

I am working on an Android application that recognizes the GO board and creates an SGF file .

I made a version that is able to detect the board and distort the perspective to make it square (the code and example image below), unfortunately, it becomes a little more complicated when adding stones. (image below)

Important things about the middle board for go:

  • round black and white stones
  • black lines on blackboard
  • the color of the board varies from white to light brown, and sometimes with wood grains
  • stones are located at the intersection of two lines

Correct me if I'm wrong, but I think my current approach is not good. Does anyone have a general idea of ​​how I can separate the stones and lines from the rest of the picture?

My code is:

    Mat input = inputFrame.rgba(); //original image
    Mat gray = new Mat();          //grayscale image

    //convert image to grayscale
    Imgproc.cvtColor( input, gray, Imgproc.COLOR_RGB2GRAY);

    //try to improve histogram (more contrast)
    equalizeHist(gray, gray);

    //blur image
    Size s = new Size(5,5);
    GaussianBlur(gray, gray, s, 0);

    //apply adaptive treshold 
    adaptiveThreshold( gray, gray, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY,11,2);

    //adding secondary treshold, removes a lot of noise
    threshold(gray, gray, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);

Some images:

empty board
(source: eighttytwo.axc.nl )

filledboard
(source: eighttytwo.axc.nl )

UPDATE: 05-03-2016

Hurrah! It was possible to correctly determine the lines of stones and colors. precondition: the image should only be on the board itself, without any other visible background.
I use houghLinesP (60 lines) and houghCircles (17 laps), the duration on my phone (1st generation Moto G) is about 5 seconds.
Detecting the circuit board and deformation is quite a challenge when it needs to work at different angles and in lightning conditions ... still working on it

- !!

filledboard
(: eighttytwo.axc.nl)

: 15-03-2016

, , , , , (. ) morph
(: eighttytwo.axc.nl)

, , , .


, , , , . . , . ( )

    Mat corners = new Mat();
    Imgproc.cornerHarris(image, corners, 5, 3, 0.03);

    Mat mask = new Mat(corners.size(), CvType.CV_8U, new Scalar(1));
    Core.MinMaxLocResult maxVal = Core.minMaxLoc(corners);

    Core.inRange(corners, new Scalar(maxVal.maxVal * 0.01), new Scalar(maxVal.maxVal), mask);

-
, , , ( )

    Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
    Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);

    int morph_elem = 1;     //0: Rect - 1: Cross - 2: Ellipse
    int morph_size = 5;

    int morph_operator = 0; //0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat
    Mat element = getStructuringElement( morph_elem, new Size(2 * morph_size + 1, 2 * morph_size + 1), new Point( morph_size, morph_size ));
    morphologyEx(image, image, morph_operator + 2, element);


, , . ( )

    Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
    Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);

    Mat hierarchy = new Mat();
    MatOfPoint biggest     = null;
    int contourId          = 0;
    double biggestArea     = 0;

    double minSize = 2000;
    List<MatOfPoint> contours = new ArrayList<>();

    findContours(InvertedImage, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    //find biggest
    for( int x = 0; x < contours.size() ; x++ ){

        double area = Imgproc.contourArea(contours.get(x));

        if( area > minSize && area > biggestArea ){

            biggestArea = area;
            biggest     = contours.get(x);
            contourId   = x;
        }
    }

, , , . , , -, , =)

comparison

: 31-03-2016

, . .

- : GOSU Snap Alpha, !

: 16-10-2016

: , . - Tensorflow, , . , , .

, .

+5
2
+3

. . , , . 19x19. , , 19x19, . . , , . . , , .

0

Source: https://habr.com/ru/post/1628844/


All Articles