ビデオキャプチャから画像を取得して文字認識(OCR)させる方法を紹介します。
いわゆる「ゲーム画面の文字をリアルタイムに取得するやつ」です。
今回はWPF(C#)の最小構成で組みました。プログラムのサンプルコードもGithubに上げているのでとりあえず動くところまでは確認できると思います。
(デバイスの環境依存でハマることもあるので上手くいかない場合は助けになるようなコメントはできないと思います。)
サンプルプログラム
https://github.com/kame-chan/WPF/tree/master/VideoCaptureOCR
コメントアウトで解説を付けていますが詰まりそうなところをちょこっと解説します。
プログラム概要
- OpenCvSharp4でビデオキャプチャがら画像取得
- 画像をImageSourceに変換出力
- 画像をBitmapに変換、切り取り処理
- BitmapをImageSourceに変換
- TesseractでBitmap画像を認識
.Net Frameworkで新規作成したWPFのMainWindow.xamlとMainWindow.xaml.cs書き換えるだけでは動かないのでNugetでパッケージを4つ入れておきましょう。
- Nuget: OpenCvSharp4(4.5.1.20201229)
- OpenCvSharp4.runtime.win(4.5.1.20201229)
- OpenCvSharp4.WpfExtensions(4.5.1.20201229)
- Tesseract(4.1.1)
バージョンはLatestで問題ないと思いますが上手く行かない場合は合わせてください。
あとはOpenCVが.Net Coreだと使えない関数があるので.Net Frameworkで。
コード解説
ビデオデバイスの選択
var camera = new VideoCapture(0) // 0番目のデバイスを指定、一覧を取得する方法は色々
{
// キャプチャする画像のサイズフレームレートの指定
FrameWidth = 1280,
FrameHeight = 720,
// Fps = 60
};
数値で指定します。どのデバイスが何番目か分からないので手入力で変えます。
本当はデバイス一覧を取得してリストに表示させて選択する、みたいなのが好ましいですがそんなの付けていません。
DirectShowを使った方法などがすぐに見つかると思います。
OpenCvSharp4にその機能があるのかもしれませんがドキュメントも読んでいないので。
画像(Mat)をImageSourceに変換する
this._Image.Source = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(img);
OpenCvSharp3と4でやり方が異なるのでハマりました。
同時にBitMapも残しておくとOCRするときに便利です。
img.ToBitmap();
BitmapからImageSourceに変換
public BitmapImage ConvertBitmapToIS(Bitmap src)
{
MemoryStream ms = new MemoryStream();
((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
return image;
}
とりあえずこれで変換できました。パフォーマンスは確認していません。
Tesseract-OCRの精度について
パッケージ化されているのはv4なので英語でも微妙でした。
学習させたり除外指定したり、判別用のコードを自作する工夫は必要ですね。
むしろそこが一番大切なんでしょうけど知識がないのでサッパリです。
基本の精度はv5 alphaの方が高いです。
切り取りで範囲を上手く調整すれば使えなくもないので私はこのまま使う予定ですが、日本語を高い精度で読み取りたい場合はv5を直接動かす方が良いと思います。
こちらも役に立つと思います。
そんな感じで以上です。あとはhyperSSCに組み込んでアーツ継承を自動化するも!
> コメント0件!書き込みのチャンス! <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄