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 の使用を開始しました。私のニューラル ネットワークは有望に見えます。ここで見ることができます。 まだ多くの作業を行う必要があります。現在の画像データセットはひどく、現在、大きなデータセットの取得に取り組んでいます。
アプリは、太い線とまともな稲妻のある正方形のボードを使用すると最適に機能します.
