OpenCV检测围棋板的不同方法 [英] OpenCV different approach on detecting go board

查看:170
本文介绍了OpenCV检测围棋板的不同方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款Android应用,该应用可以识别 GO板,创建一个 SGF文件.

i am working on an Android app that will recognize a GO board and create a SGF file of it.

我制作了一个版本,可以检测一块木板并扭曲透视图使其变成正方形(下面的代码和示例图片),不幸的是,添加石头时,它变得更难一点了(下面的图片)

i made a version that is able to detect a board and warp the perspective to make it square ( code and example image below) unfortunately it gets a bit harder when adding stones.(image below)

关于普通棋手的重要事项:

Important things about a average go board:

  • 黑色和白色圆形石头
  • 黑板上的黑线
  • 木板的颜色范围从白色到浅棕色,有时甚至带有木纹
  • 将石头放置在两条线的交点上

如果我错了,请纠正我,但我认为我目前的方法不是一个好方法. 是否有人对我如何将石头和线条与图片的其余部分区分开来有个大致的了解?

correct me if i am wrong but i think my current approach is not a good one. Has somebody a general idea on how i can separate the stones and lines from the rest of the picture?

我的代码:

    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);

一些图片:


(来源: eightytwo.axc.nl )


(source: eightytwo.axc.nl)


(来源: eightytwo.axc.nl )


(source: eightytwo.axc.nl)

2016年5月3日

05-03-2016

是的!设法检测线条结石和颜色正确.前提条件是图片只能是木板本身,而看不到任何其他背景.
我在电话(第1代Moto G)上使用了houghLinesP(60行)和houghCircles(17circles),持续时间约5秒.
如果要在不同的角度和雷电条件下工作,检测板子和翘曲的确是一个很大的挑战.

Yay! managed to detect lines stones and color correctly. precondition the picture has to be only the board itself, without any other background visible.
I use houghLinesP (60lines) and houghCircles (17circles), duration on my phone(1th gen Moto G) about 5 seconds.
Detecting board and warp it turns out to be quite a challenge when it has to be working under different angles and lightning conditions.. still working on that

仍欢迎提出不同方法的建议!


(来源: eightytwo.axc.nl )


(source: eightytwo.axc.nl)

2016年3月15日

15-03-2016

我发现了一种通过十字形形态转换获得线相交的好方法,不幸的是,当照片直接在木板上方拍摄时,效果很好,而并非在一定角度下(见下文)
(来源: eightytwo.axc.nl )

i found a nice way to get line intersects with cross type morphological transformations, works amazing when the picture is taken directly above the board unfortunately not while at an angle (see below)
(source: eightytwo.axc.nl)

在我的上一次更新中,我从上面直接拍摄的照片显示了线和石头的检测,从那时起,我一直在致力于检测电路板并使其变形以使线和石头检测变得有用.

In my last update i showed line and stone detection with a picture taken from directly above since then i have been working on detecting the board and warping it in a way that my line and stone detection becomes useful.

har角检测
我一直在努力获取正确的参数设置,但仍不确定它们是否最佳,在使用harris角之前无法找到有关如何优化图像的大量信息.现在,它检测到许多有用的地方.尽管感觉可行. (示例中带有图片的上一行)

harris corner detection
I struggled to get the right parameter settings and i am still not sure if they are optimal, can't find much information on how to optimize image before using harris corners. right now it detects to many corners to be useful. though it feels like it could work. (upper line with pictures in example)

    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);

跨类型形态转化
当直接从上方拍摄照片,以一定角度使用或与旋转的木板一起使用时,效果很好(例如,在照片中间居中)

cross type morphological transformations
works great when picture is taken directly from above, used from an angle or with a rotated board does not work (middle line with pictures in example)

    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);

轮廓和轮廓线
如果外板上没有结石,并且光照条件不苛刻,则效果很好.轮廓经常只是板子的一部分(例如,下排带有图片)

contour and houghlines
if there are no stones on the outer boardline and light conditions not to harsh it works pretty well. contours are only part of the board quite often(lower line with pictures in example)

    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;
        }
    }

这三种方法都可以提供正确的图像,但是不够可靠.欢迎您对参数,图像预处理,不同方法或可能改善检测效果的任何想法=)

providing the right picture all three the methods work but not good enough to be reliable. any thoughts on parameters, image pre-processing, different approaches or anything that might improve the detection are welcome=)

链接到图片

2016年3月31日

31-03-2016

检测线条和石头几乎可以解决,因此我将结束这个问题. ​​创建了一个新的用于准确检测和变形.

detecting lines and stones is pretty much solved so i will close this question. created a new one for detecting and warping accurately.

任何对我的进度感兴趣的人:这是我的GOSU Snap Alpha频道现在不要期望太多!

anybody interested in my progress: this is my GOSU Snap Alpha channel don't expect to much of it right now!

2016年10月16日

16-10-2016

更新:我看到有些人仍然在关注这个问题. 我测试了更多的东西并开始使用Tensorflow,我的神经网络看起来很有希望,您可以在这里看看. 仍然需要做很多工作,我当前的图像数据集很糟糕,现在我正在努力获取一个大数据集.

Update: i saw some people are still following this question. I tested some more stuff and started using Tensorflow, my neural network looks promising, you can have a look at it here. A lot of work has to be done still, my current image dataset is awful and right now i am working on getting a big dataset.

该应用程序最好使用带有粗线和像样的闪电的方形板.

the app works best using a square board with thick lines and decent lightning.

推荐答案

假设您不想强迫"最终用户拍摄最干净的照片(例如使用诸如QR码扫描仪之类的覆盖层)

Assuming that you don't want to "force" your end user to take a cleanest pictures (like using an overlay like some of the QR code scanner for example)

也许您可以对不同的内核使用一些形态转换:

Perhaps you could use some morphological transformations with differents kernels :

  • 使用矩形核打开和关闭线条
  • 用椭圆形内核打开和关闭以获取结石(应该可以在某个时候反转图像以取回白色或黑色)

看看 http://docs.opencv. org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html (很抱歉,这是C ++,但我认为Java几乎相同)

Take a look at http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html (sorry this one is in C++ but I think this is almost the same in Java)

我尝试了这些操作,从数独中删除了一个网格,以避免细胞提取过程中产生噪音,并且它就像一个魅力.

I had try these operations to remove a grid from a Sudoku to avoid noise in cell extraction and it worked like a charm.

让我知道这些信息对您有用(肯定是一个非常有趣的情况)

Let me know of these informations were usefull for you (this is for sure a very interesting case)

这篇关于OpenCV检测围棋板的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆