2016-02-15 27 views
4

我正在開發一個Android應用程序,它將識別GO board並創建一個SGF fileOpenCV檢測棋盤上的不同方法

我犯了一個版本,其能夠檢測板和翹曲的角度,使其平方(下面代碼和示例圖像)不幸的是它加入石子時變得有點困難。(下圖)

重要的事情關於平均棋盤:

  • 圓形黑色和白色石
  • 黑線在板
  • 板的顏色範圍從白色至淺棕色,有時帶有木紋
  • 石頭被放置在交叉的兩條線

糾正我,如果我錯了,但我認爲我目前的做法是不是一個好。 有人有關我如何從圖片的其餘部分分離石頭和線的一般想法?

我的代碼:

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

一些圖片:

empty board http://roelept82.eightytwo.axc.nl/pic/device-2016-02-15-130011.png filledboard http://roelept82.eightytwo.axc.nl/pic/device-2016-02-15-131431.png

編輯: 2016年5月3日

耶!設法正確地檢測線條石塊和顏色。先決條件是圖片必須只是板子本身,沒有任何其他背景可見。
我使用houghLinesP(60lines)和houghCircles(17圈),持續時間在我的手機上(第1代摩托G)約5秒鐘。
探測板和扭曲事實證明是相當大的挑戰,當它以不同的角度和閃電條件是工作..仍在努力對

建議不同的方法,仍然歡迎!

filledboard http://roelept82.eightytwo.axc.nl/pic/detect.png

編輯:當圖片被直接採取上述板不幸 15-03-2016

我發現了一個很好的方式來獲得符合十字型形態的轉換交叉,令人驚歎的作品而不是在一個角度(見下文) morph http://roelept82.eightytwo.axc.nl/pic/morph.png

在我上次更新我顯示線和石頭檢測與直接從上面拍攝的照片自那時起我一直以來通過檢測電路板並翹曲,以便我的線條和石材檢測變得有用。

Harris角點檢測
我掙扎着正確的參數設置和我仍然不知道他們是最佳的,無法找到如何使用哈里斯角之前優化圖像多的信息。現在它檢測到許多角落是有用的。儘管它覺得它可以工作。 (與實施例中的照片上面的線)

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

輪廓和houghlines
如果有在外boardline沒石子和光照條件不苛刻的它工作得很好。輪廓僅是主板的一部分,經常(與示例圖片下行)

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

提供合適的圖片全部三種方法的工作,但還不夠好是可靠的。對參數的任何想法,圖像預處理,可能提高檢測的不同方法或任何歡迎=)

link to picture

comparison http://roelept82.eightytwo.axc.nl/pic/comparison.png

編輯: 31-03-2016

檢測線和石頭已經解決了,所以我會關閉這個問題。 created a new one用於檢測和準確翹曲。

任何對我進步感興趣的人:this is my GOSU Snap Alpha channel現在不要期望太多!

編輯: 16-10-2016

更新:我看到有些人還在關注此問題。 我測試了一些東西,並開始使用Tensorflow,我的神經網絡看起來很有希望, you can have a look at it here. 還有很多工作要做,我當前的圖像數據集非常糟糕,現在我正在努力獲得一個大數據集。

該應用程序最好使用粗線和體面閃電的方形板。

回答

2

假設你不希望「強制」最終用戶採取乾淨的照片(如使用覆蓋像一些QR碼掃描儀例如)

也許你可以使用一些形態轉換型動物的內核:

  • 開口與矩形內核關閉的線路
  • 開幕式,並與橢圓的內核,以獲得寶石關閉(它應該有可能在某個時候將圖像反拿回白或黑色)

再看看http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html(抱歉,這個人是在C++中,但我認爲這幾乎是在Java中一樣)

我曾嘗試這些操作,從一個數獨中刪除網格,以避免細胞提取噪音它像一個魅力一樣工作。

讓我知道,這些信息都是有用的,你(這是肯定的一個非常有趣的案例)

+0

謝謝!我明白這個主意。必須進行測試,並將結果返回給您。 – MaMiFreak

+0

我對這個建議感到非常滿意,不幸的是,對於與此不同的項目更是如此。我設法刪除線(見鏈接),但我不能刪除的石頭,而不刪除線。 https://www.dropbox.com/s/hdvtshj1e481u4c/lineremoval.png?dl=0 旁邊,它不是一個非常快速的轉換,最後我希望能夠處理至少2張圖片a秒(而不是當前的每3秒1次)以獲得正在進行的遊戲的連續註冊 – MaMiFreak

+0

根據您的編輯,我發現您可以檢測到您想要的內容。對於處理時間,我能想到的最簡單的事情就是在處理之前減少圖像分辨率。嘗試將分辨率除以1.5,2,2.5,3等,觀察結果和處理時間。這些轉換必須檢查每個像素,將初始分辨率除以2會將處理時間減少近4秒。 – RossierFl

0

我工作的程序相同。我完全避免找到線條。 首先使用透視變換將棋盤變成方塊,就像你所做的一樣。找到19x19網格的邊緣。然後假設電路板是19x19,您可以計算線的位置。這對我很好。然後計算石材中心的最接近的交點,以確定石材所在的行和列線。對我來說工作得很好。只可能是針對不同的照明條件和不同顏色的石塊和木板校準程序。

+0

如何定位板以便執行正確的透視變換? – MaMiFreak

+0

基本上打電話找輪廓,以獲得所有的板的輪廓。 – sammy

+0

然後找到最大面積輪廓,然後找到該輪廓的凸包。這通常起作用。 – sammy