しかし、解読できたのは Fix型で作成された、NHK 囲碁講座 テキストに限られ あまりにも狭い範囲 との印象はぬぐえません。
摘要範囲を広げようと
1)NHK 囲碁講座 テキストのより小さな棋譜でも解読できないか
リフロー型対策
2)新聞に載っている囲碁記事の棋譜が解読できないか
等々試しましたが、それぞれ難題にぶつかり、早々に対応できるようには思えません。
対策できればBestですが・・
そこで、囲碁講座テキストをスキャナーで読み込んだイメージデータを入力し、解読する処理を実装することにしました。
1)スキャナーで読み込んだ画像を、回転し傾きを補正する。
このとき図形の拡大・縮小表示も可能とする。
2)棋譜部分を指定し、棋譜部分の画像を取得する。
Window上部の2つのスライダーで画像の大きさ・傾き補正を行い、キャンバスの背景に設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | private void RotateResize() { mat = src.Clone(); if (degreeSlider.Value != 0) { Point2f center = new Point2f(src.Cols / 2, src.Rows / 2); Mat rMat = Cv2.GetRotationMatrix2D(center, -degreeSlider.Value, 1); Cv2.WarpAffine(src, mat, rMat, new OpenCvSharp.Size(src.Cols, src.Rows)); } Mat dest = mat.Clone(); if (sizeSlider.Value != 100) { double ratio = sizeSlider.Value * 0.01; Cv2.Resize(mat, dest, new OpenCvSharp.Size(mat.Width * ratio, mat.Height * ratio), 0, 0, InterpolationFlags.Cubic); } setBackgound(dest); } |
ここで
src:スキャナーで取り込んだ画像
degreeSlider:傾き補正用のスライダー -3° ~ +3°で0.1°刻みで 画像の中央(center)を中心と
して、回転する角度を指定します。
右回転を指示した場合、スライダーの値は(+)なので符号を反転することが必要です。
sizeSlider:大きさ調整用のスライダー 10% ~ 110%で10%刻みで 調整します。
setBackgound(dest):傾き・大きさを調整した結果をキャンバスの背景に設定する処理です。(後述参照)
上図は、スキャナーで取り込んだ画像を1.5°左回りした画像ですが、これをスライダーおよびスクロールバーを調整して下図のようにします。
次に、棋譜図を切り取る左上隅と右下隅を指定して、第一章で作成した棋譜解読処理に棋譜画像を引き渡します。
その結果下図のような解読結果が得られました。
(5,16)(10,7)の白石以外正常に解読できていることが分かります。
ちなみに、ここでテストに使った画像は、スキャナーで解像度を200DPIにして取り込んだ画像で、IrfanView 64を用いてわざと1.5°回転しています。
IrfanView 64での回転処理前の画像を入力にすると、全くノーエラーで解読できました。
さほどシビアに位置調整してスキャンしたわけではありませんが、スキャンが思いのほかうまくいっていたようです。回転処理をおこなうことにより、画像が微妙に劣化したものと思います。
結果紙ベースのテキストをスキャナーで読み取って、そのイメージデータを入力にする方法は、十分実用的な精度で使えることが分かりました。
大きさ・傾きを調整した画像は、Mat形式になっています。ところが、Canvasの背景はImageBrush形式にする必要があります。そのため以下の方法で変換を行いました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | private void setBackgound(Mat pmat) { Bitmap bmp = new Bitmap(pmat.Cols, pmat.Rows); bmp = pmat.ToBitmap(); System.Windows.Media.Imaging.BitmapSource bitmapSource; // *********************************************************** // MemoryStreamを利用した変換処理 using (var ms = new System.IO.MemoryStream()) { // MemoryStreamに書き出す bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // MemoryStreamをシーク ms.Seek(0, System.IO.SeekOrigin.Begin); // MemoryStreamからBitmapFrameを作成 // (BitmapFrameはBitmapSourceを継承しているのでそのまま渡せばOK) bitmapSource = System.Windows.Media.Imaging.BitmapFrame.Create( ms, System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.OnLoad ); } ImageBrush myImageBrush = new ImageBrush(bitmapSource); myCanvas.Width = bitmapSource.PixelWidth; myCanvas.Height = bitmapSource.PixelHeight; myCanvas.Background = myImageBrush; } |
参考にしたサイト
・C#における「ビットマップ形式の画像データを相互変換」まとめ
・C#における「ビットマップ形式の画像データを相互変換」まとめ
開発環境
OS:Windows10
言語:C#(WPF使用)
IDE:VisualStudio2019
仕様Tool:OpenCvSharp v4.2.0.20200208
使用本:NHK 囲碁講座 テキスト2020年3月号
OS:Windows10
言語:C#(WPF使用)
IDE:VisualStudio2019
仕様Tool:OpenCvSharp v4.2.0.20200208
使用本:NHK 囲碁講座 テキスト2020年3月号
0 件のコメント:
コメントを投稿