VB6です。
スクリーンをキャプチャしてそこに書いてある数字をテキストとして取り出すことは出来ないでしょうか?
ぶっちゃけるとゲームの画面から数字を抜き出したいのです。
ウィンドウからハンドルを使って文字を取得する方法が困難な相手なのでいわゆるOCRするしか無いのかな、というところです。
OCRするにもググっても利用or参考になるものが見当たりません。
ライセンスフリーのプログラムにしたいと考えていますが、文字認識エンジンはたいがい有料のようです。
無料のソフトが以前あったようですが公開停止のようですし・・・
もともと日本語ではなく数字が認識できればいいのですが、適したOCRライブラリは無いかご存知無いでしょうか。
場合によっては人気のOCRソフトの付属ライブラリを使う方法もありかなと。
数字ということはたかだか10個なのでパターンマッチングする方法もあるかとも思いますが、参考となるような情報またはサンプルは無いでしょうか。
スクリーンからじゃなくても画像(BMP・JPEG等)から文字を抜き出す方法でも可です。
VBはじめて半年、なかなかスキルが身につかない・・・
。・ ゜・。* 。 +゜。・.。* ゜ + 。・(ノД`)
プログラムからの制御が可能かどうかはわかりませんが、
Office 2003 付属の Document Image Writer には OCR の機能があり、
画像の内容をテキストとして取得することが可能です。
http://office.microsoft.com/ja-jp/assistance/ch010000951041.aspx
> スクリーンからじゃなくても画像(BMP・JPEG等)から文字を抜き出す方法でも可です。
そのゲームの画面を BMP として切り出すところまでは実装可能ですか?
ええ、確かにDocument Imageがあるのは知っていましたが、office2003がない環境でも動かしたいなというのと、
おっしゃるとおりプログラムからの制御が可能かどうかはわからないので具体的な情報待ちです。(ノ∀`)ペチ
気にはなってます。
> そのゲームの画面を BMP として切り出すところまでは実装可能ですか?
もともとゲーム側にスクリーンキャプチャ機能があるので、
最悪ソレを手動で押して保存されたファイルを捕まえて読み込めばいいかなと考えてました。
でも、欲しい機能としては一定時間経過ごとにキャプチャしたいので、手抜きはよくないですね。(´▽`*)アハハ
ということで急遽(勉強して)試してみました。
CaptureWindowの方法とkeybd_eventでプリントスクリーンを送る方法と両方試してみたところ、
なぜかkeybd_eventのほうは失敗。
他のキーを送っても受け取ってくれないです。ナニユエ
サンプルコードが悪いのかな?
CaptureWindowは成功ししました。
まぁOCRしたい領域は狭いので必要な部分だけ取り込んだほうがいいのかなと思っいます。
結論として、切り出すところまでは実装可能です。
まぁここからが問題なわけですけど・・・
方法は、あるのでしょうか。
壁|д゜*)
文字の形がきまっている
文字の大きさがきまっている
文字の位置(切り出した後の)がきまっている
であれば、単に全ピクセルの比較でもいいようなきがしますが
(極端に大きい文字だと処理時間の問題がありますが)
>結論として、切り出すところまでは実装可能です。
位置と大きさが決まっているなら、読み込んだbmpを2値化して、
チェックポイントを10箇所位決めておき、あらかじめ1はここが
黒、2はここが黒等と設定しておいて、いちばん多くヒットした
数字に決めるとか。
回答アリガト(^▽^)ゴザイマース
全ピクセル比較ってXYでピクセル値を比較するんですかね?
ガクガク((゜Д゜;))ブルブル
んー、文字が10×10ぐらいだったら無理じゃないね。
でも大体の開始位置しかわからない・・・
(桁数が不定)
10ポイントチェックは簡単そうなのですが、開始位置がわからないのと、
汎用性がちょっと少ないかなということでもう少し手間をかけざるをえないかなと。
(ノ_・、)シクシク
今のところ2箇所認識したい場所があるのですが、
ひとつはこのサイトの←のフレームの上の方にある「HOME」みたいな文字で、
ひとつはごく普通のゴシック文字です。でも可変ピッチ文字・・・
まぁサイズはさっきのとおり10×10以下。
ところでパターンマッチングすると考えたとき、
画像転送のときに、XORしたときには同色ピクセルのところは何色になるんでしょう?
黒?白?
また、イメージBOXが白か黒になったことを評価出来るでしょうか?
全ピクセル色を加算するのは手間がかかりそうですし・・・
それから、すいません。
こういう方法でと教えていただけるのは大変ありがたいのですが、お勧めのコマンドをもあわせて記していただけるとなおありがたいです。
標準のコマンドよりAPIを使ったほうが早いとか何とかありますし、APIでも同じようなコマンドがあるようですし。
ペコm(_ _;m)三(m;_ _)mペコ
というか、OCRにチャレンジしてる人々って少ないのですかね?
そのもので無くても近いことをやっていてもおかしく無いかなーと思ったんですが。
調べて見てもぜんぜんヒットしませんしね・・・
無きゃ無いでがんばるしか無いのですけど。
始めて画像を扱ってのOCRはハードルが高すぎる米。
(;´ρ`) グッタリ
あ、それから配列に無作為に入っている数値を小さいものの順で並び替えたいのですがうまいやり方はないですかね?
a(0)=100: a(1)=15: a(2)=23: a(3)=1: a(4)=99
というのがあったら、
b(0)=3: b(1)=1: b(2)=2: b(3)=4: b(4)=0
みたいな。
#VBは詳しくないので一般的な話しかできませんが
>まぁサイズはさっきのとおり10×10以下。
と言うことはキャプチャされた画像がJPGだったりしてノイズがのってしまうと
OCRする上で致命的な問題になりそうですね。
切り出して出力された画像が同じ文字であれば(ほぼ)同じになるのなら、
パターンマッチングでかなりの認識率が出ると思います。
いずれにせよ、画像処理の基礎くらいは抑えておかないと一筋縄ではいかないと思います。
> うまいやり方はないですかね?
何を持って”うまい”のか教えてもらえますか?
(速度がはやいなどなど)
> a(0)=100: a(1)=15: a(2)=23: a(3)=1: a(4)=99
> というのがあったら、
> b(0)=3: b(1)=1: b(2)=2: b(3)=4: b(4)=0
スレと関係ない質問をなされるのは関心しませんが、
配列aとbの関連が全くわかりません。
並び替えでもないし、順位かと思ったら違うみたいだし。
ビットマップを1列ずつ255(白)→0(黒) 0(黒)→255(白)に変わってるポイントの個数を1列づつスキャンしてn%以上適合したらその文字みたいな感じは
どうでしょ?
自分でキャプチャするのでBMPで間違いないですね。とりあえず。
うまいやり方というのはプログラムの手数が少なくて時間が早いやり方ということで。
順位でいいですよ。a()が並び替えれればなんでもいいんです。
自分的に残念なのがあながちすれ違いというわけではないところです。
経験者が徘徊してないようなのですが、パターンマッチングしようとしたときに並び替えが必要なのかなーと。
わたしが考えてるアルゴリズムとしては、
1)0〜9に相当する基準パターン画像を用意します。
仮に5×10とします。
2)アクティブウインドウからキャプチャする領域を仮に50×10とします。
3)キャプチャした領域から左から順に5×10で画像をコピーして基準画像とマッチングします。
DIM 位置記録(20)
DIM パターン記録(20)
認識個数 = 0
For パターン = 0 To 9
For X位置 = 1 To 50−5
パターンマッチング ・・・方法未定
一致度評価 ・・・方法未定
IF 評価値 > 閾値 Then
位置記録(認識個数) = X位置
パターン記録(認識個数) = パターン
認識個数 = 認識個数+1
END IF
NEXT
NEXT
4)記録配列から数値を並び替え
X位置の昇順の配列番号を取得
5)並び替えた配列の順に結合
昇順にパターン記録を結合、数値化
・・・と思ったんです。
昨日までは。
よくよく考えるとこれでいいですね。 o /rz
3)’ For X位置=1 To 50−5
For パターン=0 To 9
パターンマッチング ・・・方法未定
一致度評価 ・・・方法未定
IF 評価値 > 閾値 Then
認識文字列 = 認識文字列 & Str(パターン)
X位置 = X位置+5
Exit For
END IF
NEXT
NEXT
というか、そもそもこんなんでいいのかなぁ・・・
誰かやってないんですかね?
紅閃光さんへ
VBで
ゲームの画像の一部を取り出して、数字を判断するのは遅すぎて難しいかもしれません。
とある人が作成したPerlモジュールを改良して
画像の読み込み、画像と画像の比較を行うDllを作成したところです。
ただし、Perlモジュールです。
画像比較の速度はOSによって変わります、サンプルtest.plで8*16ですが
16*16の画像でも速度は変わりません。
大体1秒間に500〜1000回比較可能です。CPUの使用率は10%以下に抑えています。(Sleep(1);使用時)
宣伝みたいな感じでとらわれてしまうかもしれません、申し訳ございません
とりあえず、アドレスを載せておきますのでご確認ください。
サンプルのtest.plは画面左下の時計「分」の画像をファイルに保存します
その画像と、今現在の画像を比較して、変化したらStopするプログラムです。
http://key.nusutto.jp/
私もゲームにおいて、
0〜9までの画像をそれぞれ保存しておき
該当する画像数字から、文字に変換してファイルに保存する
ということをこのモジュールを使用して行っていたことがあります。
参考にならないかもしれませんがよろしくお願いします。
紅閃光さんへ
ごめんなさい
フォルダーの中に
STCOM というフォルダーがあるのですが
フォルダー名をbinに変更してください
Cmd_Start.batのバッチファイルを起動して
キーフックを利用していますのでCtrl+F11でサンプルプログラムが動きます。
右下の時計が表示される状態で動かしてください。
よろしくお願いします。
VBでは遅くて使い物にならないと思いますが、暇なときVBで挑戦してみます
・取り出したいのは数字だけである=パターンはたったの10種類
・自前でBMPキャプチャする=画像は劣化しない
以上から、自前で比較するのは簡単だと思いますよ
最初に黒背景に白文字の数字のBMPを用意しておき、それと比較するだけですよね
比較用のBMPの黒の部分は比較をしないで飛ばすから、時間もそんなにかからないはずですが・・・
VB梅さま
同じようなことはやっている人はやっぱりいるんですね。
安心しました。(?)
Perlで作成したDLLモジュールとのことですが、VB6から実行できるということでしょうか?
リンクのサイトにおいてあるプログラムを見てみても使い方がよく理解できませんでした。
o⌒Y⌒ /rz
で、話もどって、VBで全部やるとして、
パターンマッチをするにはどんなコマンドを使えばいいのでしょうか?
ちなみにカラーの絵数字です。
ピクチャBOXのピクセル値を比較して行くのはあまりにもダメプログラムかなと。
APIでピクセル値比較なら少しは早そうなのですが(GetPixel?)、もう少しうまいソフトにしたいです。
そこでBitBltでXORコピーしたら、ひょっとして?
試してみたらマッチングした部分は黒になるようです!
ヾ(●⌒∇⌒●)ノ わーい
問題はXORで重ね合わせた画像が黒いかどうかを評価する方法ですね・・・
1ピクセルずつ色を調べていくのならやっぱりうまく無いなぁ。
指定エリアの色評価を一括で出来ないものですかねぇ。
それからDIBなるものを使えば劇的に処理が早くできるようですね。
ググってみたら少しはヒットするのですが、使い方がサッパリわかりませんねぇ。
情報があっても役に立たないとはこれいかに。
もっとも、認識エンジンを組み込んだソフトにはあまり速度を求めてはいません。
バックグラウンドで実行するので、負荷が少なければ数秒かかってもまったく問題ありません。
DIBに手を出すよりのろのろもとい手堅くやったほうがいいのでしょうか・・・
Q1)パターンマッチのいい方法はありませんか?
Q2)指定エリアの色評価を一括で出来ないか?
Q3)DIBでの画像比較の具体的なやり方は?
Q4)もっといい方法はないのか?
あー、ひそかに土日は巡回者が少ないのかなぁ?
>あまりにもダメプログラムかなと。
とりあえずそのダメプログラムとやらをつくってみてから次を考えてみては?
それが既に「手間」ですか?
新しいことをするのにその程度の手間を惜しむのはプログラマじゃないですよね
頭でっかちでは否定するだけで、何もできないですから
ちなみに私は、ダメプログラムからいいプログラムってのは生まれると思っていますよ
>あー、ひそかに土日は巡回者が少ないのかなぁ?
とりあえず、巡回者はあなた専用ザクではありません
VBで使用可能なMscom.dllは作る予定でいるけど
口だけで痛い人だね
解決しました。
後で詳しく書きます。
>プログラマじゃないですよね
おっしゃることはもっともです。
でも目的と手段が逆になってませんか。
当然スキルの向上は各自で取り組まないいけない事ですが、
ここではまず情報の入手を優先してますので。
急がば回れということは理解できます。
また、ダメプログラムと書いたのは画像を操作するコマンドがいくつもあって簡便な手法では目的の達成が難しいと判断したからです。
わたしの目的にとってダメプログラムであっても、同じ手法を使っている人をダメプログラマというつもりで言っているわけではありません。
気を悪くした方がいたらごめんなさい。
さて、皆さんの助言のおかげでなんとか目的を達成できました。
大変勉強にもなり、満足度100%+20−8です。(謎
今回、画像ファイルから文字を認識するにあたり情報があまりにも少なく暗中模索で足小指をぶつけた思いです。
後続の方々の一助となるべくここに成果を記載しておきます。
今回の目的は、ゲームソフトの画面に表示されている数字を認識することです。
一般的なWindowsアプリケーションならオブジェクトを検索してメッセージを取得することは可能かもしれません。
しかし、こののゲームソフトはタスクマネージャーのプロセスからも姿を隠しており、チート対策のプロテクトソフトも走っているため敷居が高くなっています。
そこで画像をキャプチャして文字認識してやろうと考えたわけです。
ちなみに、なぜかkeybd_eventでキーコードを送ってみても受け取ってくれませんでした。
まず、フリーのOCRエンジンがほとんど無ありませんでした。
一般的なOCRをしたいなら、有料ソフトでVBから制御できるものが必要だということですね。
手書き数字認識ならフリーのが数個ありましたけどVBで制御は至難の業です。
フリーの日本語OCRソフト「SmartOCR Lite Edition」が現在も公開されていれば何とかなったかも知れませんが、公開中止になっているのが残念です。
無料で実現できるソフトとしたかったので、OCRエンジンの組み込みはあきらめました。
今回は文字というより、数字を認識するのが目的だったので、数文字のパターンを用意して(0〜9の10個)パターンマッチングすることにしました。
読み取りたい数文字が2箇所で、フォントが異なっているので10+1個(終り記号含む)×2で 合計22個のパターンを持ちます。
以下にそのだいたいのアルゴリズムを書いて見ます。
・起動時にデータ化
基準パターン画像22個をファイルから読込み
※ファイルは一個にまとめることも考えましたが、
等ピッチではない場合に対応しにくくなるので分けました。
基準パターン画像をDIB化してRGBTRIPLE構造体でデータを保持
※「CreateCompatibleDC」&「CreateCompatibleBitmap」を使って作業用ビットマップを作成し、
「BitBlt」で基準パターン画像を転送し、「GetDIBits」でRGBQUAD構造体のDIBを取得
・パターンマッチング
検査画像から検査領域(基準パターン画像の大きさ)をコピーしてRGBTRIPLE構造体でデータを取得
※基準パターン画像と同じ方法
縦横全ピクセルのRGB各色で基準画素と検査画素との輝度差を閾値と比較して一致度を算出
※背景に色ムラがあるので輝度差を許容する必要がありました。(16程)
For 検査エリア=0 To 2箇所
For X座標=0 To 検査エリアサイズ
検査領域RGB取得
For パターン=0 to 10個
For Xピクセル=0 To 基準画像Xサイズ
For Yピクセル=0 To 基準画像Yサイズ
IF Abs(基準R−検査R)<= 輝度閾値 Then カウント+1
IF Abs(基準G−検査G)<= 輝度閾値 Then カウント+1
IF Abs(基準B−検査B)<= 輝度閾値 Then カウント+1
Next
Next
一致度 = カウント ÷ ( Xピクセル数 × Yピクセル数 ×3色素 )
IF 一致度 > 一致度閾値 Then
IF パターン=10 Then Goto エリアEND
認識文字列=認識文字列+パターン
X座標=X座標+基準画像Xサイズ−1
End IF
Next パターン
DoEvents&Sleep 'わざわざ遅くしている(50m秒)
Next X座標
エリアEND:
Next 検査エリア
ちなみに画像の大きさ等の条件はこんな感じでした。
検査エリア1のサイズ =42×13ピクセル
検査エリア1の基準パターンサイズ =11×13ピクセル(平均)
検査エリア1の文字桁数 =2〜4
検査エリア2のサイズ =95×9ピクセル
検査エリア2の基準パターンサイズ =7×9ピクセル(平均)
検査エリア2の文字桁数 =2〜11
一致度閾値はほとんど100%ですが念のため97.5%にしています。
検査エリアのY方向も4ピクセル程余計に広くして融通をもたせようかなとも思いましたが、遅くなる以上の意味が無いのでYは固定にしました。
見ての通り(?)検査エリアからBitBltする以外は物理オブジェクトにアクセスしていません。
上記条件の場合は変な画像を持ってきてもウエイト抜けば認識時間が0.15秒程しかかかりません。
全エリア、全パターンマッチングするので、1400回以上マッチングしています。
ということは8500回/秒(≒720kピクセル/秒)ほどですか。
「ちょwおまっw早すぎw」
とにかく予想以上の高速になりました。
VB6でもやり方次第なんですねぇ。
検査エリアも読み込んだ時に1回だけ全体をDIB化すればまだまだ早くなります。
わざわざカラーでマッチングしているのも、
グレースケールもとい2値化すれば・・・
1/3以下になる・・・か・・・も・・・ _ノフ○ バタリ
これならひらがな&カタガナ&アルファベットでOCRも結構いけそうですね。(250パターン程)
でもフォント画像をどうしようという問題はありますし、結局漢字が認識できないなら使えない、かな。
いろんなフォント、サイズ、傾きがあると考えると、やはりOCRという技術はいろいろと難しいですね。
この程度ならまだまだ中級の下レベルですか・・・やはりプロアプリは恐ろしい・・・
ガクガクブルブル(((((((( ;゜Д゜))))))))ガタガタブルブル
白黒2値化で文字領域抽出してハッシュ値比較でメモリアドレスアクセスで・・・ナニガナニヤラ・・・
ツイート | ![]() |