5

GO ボードを認識し、そのSGF ファイルを作成するAndroid アプリに取り組んでいます。

ボードを検出し、パースペクティブをワープして正方形にすることができるバージョンを作成しました(下のコードとサンプル画像)残念ながら、石を追加すると少し難しくなります(下の画像)

平均的な碁盤に関する重要事項:

  • 丸い黒と白の石
  • ボード上の黒い線
  • ボードの色は白から明るい茶色まであり、時には木目があります
  • 石は2本の線の交点に置かれます

私が間違っている場合は修正してください。ただし、現在のアプローチは適切ではないと思います。石と線を写真の残りの部分からどのように分離できるかについて、誰かが一般的な考えを持っていますか?

私のコード:

    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

埋め板
(出典:eightytwo.axc.nl

編集: 2016年5月3日

わーい!ラインストーンと色を正しく検出できました。前提として、写真はボード自体のみで、他の背景が見えないようにする必要があります。
私は houghLinesP (60lines) と houghCircles (17circles) を使用し、携帯電話 (第 1 世代の Moto G) で約 5 秒持続します。
ボードとワープを検出することは、さまざまな角度や雷の条件下で作業する必要がある場合、非常に困難であることが判明しました..まだそれに取り組んでいます

さまざまなアプローチの提案は大歓迎です!!

埋め板
(出典:eightytwo.axc.nl

編集: 15-03-2016

私はクロスタイプの形態学的変換と交差する線を取得する良い方法を見つけました。写真がボードの真上で撮影された場合、残念ながら斜めではありません(以下を参照) (ソース:eightytwo.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;
        }
    }

適切な画像を提供すると、3 つの方法すべてが機能しますが、信頼できるほど十分ではありません。パラメータ、画像の前処理、さまざまなアプローチ、または検出を改善する可能性のあるものについての考えは大歓迎です =)

画像へのリンク

比較

編集: 31-03-2016

線と石の検出はほとんど解決されたので、この質問を閉じます。検出とワープを正確に行うための新しいものを作成しました。

私の進歩に興味がある人:これは私の GOSU Snap Alpha チャンネルです。今はあまり期待しないでください!

編集: 16-10-2016

更新: 何人かの人々がまだこの質問に従っているのを見ました. 私はさらにいくつかのことをテストし、Tensorflow の使用を開始しました。私のニューラル ネットワークは有望に見えます。ここで見ることができます。 まだ多くの作業を行う必要があります。現在の画像データセットはひどく、現在、大きなデータセットの取得に取り組んでいます。

アプリは、太い線とまともな稲妻のある正方形のボードを使用すると最適に機能します.

4

2 に答える 2

3

エンドユーザーに最もきれいな写真を撮ることを「強制」したくないと仮定します (たとえば、QR コードスキャナーのようなオーバーレイを使用するなど)。

おそらく、異なるカーネルでいくつかの形態学的変換を使用できます。

  • ラインの長方形カーネルで開閉
  • 石を取得するために楕円カーネルで開いたり閉じたりします(ある時点で画像を反転して、白または黒に戻すことができるはずです)

http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.htmlをご覧ください(これは C++ で申し訳ありませんが、Java でもほぼ同じだと思います)。

これらの操作を試して、数独からグリッドを削除して、セル抽出のノイズを回避しましたが、それは魅力のように機能しました。

これらの情報があなたにとって役に立ったことを教えてください (これは確かに非常に興味深いケースです)

于 2016-02-15T19:03:38.173 に答える
0

私は同じプログラムに取り組んでいます。私は行を見つけることをまったく避けます。最初に透視変換を使用して、ボードを正方形にします。19x19 グリッドの端を見つけます。次に、ボードが 19x19 であると仮定すると、線の位置を計算できます。これは私にとってはうまくいきます。次に、石の中心の最も近い交点を計算して、石がどの行と列の線にあるかを判断します。私にとってはかなりうまくいきます。おそらく、さまざまな照明条件とさまざまな色の石とボードのプログラムを調整するだけです.

于 2016-12-06T18:23:31.350 に答える