C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

画面の一部の変化を監視したい /鳥取県 (17/11/06(Mon) 11:07) #85564
Re[1]: 画面の一部の変化を監視したい /ぶなっぷ (17/11/06(Mon) 13:58) #85565
Re[1]: 画面の一部の変化を監視したい /furu (17/11/06(Mon) 17:09) #85567
  └ Re[2]: 画面の一部の変化を監視したい /鳥取県 (17/11/06(Mon) 20:02) #85569
    ├ Re[3]: 画面の一部の変化を監視したい /774RR (17/11/07(Tue) 06:20) #85572
    └ Re[3]: 画面の一部の変化を監視したい /furu (17/11/07(Tue) 09:55) #85574
      └ Re[4]: 画面の一部の変化を監視したい /鳥取県 (17/11/07(Tue) 14:49) #85577 解決済み


親記事 / ▼[ 85565 ] ▼[ 85567 ]
■85564 / 親階層)  画面の一部の変化を監視したい
□投稿者/ 鳥取県 (1回)-(2017/11/06(Mon) 11:07:38)

分類:[.NET 全般] 



画面の一部の変化を監視し、
もし、変化があったら、アクションを起こすプログラムを作りたいと考えています。

それで画面の一部を監視する方法に関して教えてください。

画面の一部をキャプチャーするには以下のコードで書くことができます。

Dim myBitmap As Bitmap = New Bitmap(1, 1)
Dim g As Graphics = Graphics.FromImage(myBitmap)
g.CopyFromScreen(New Point(X, Y), New Point(0, 0), New Size(1, 1))



それで後は

Dim PixColor As Color = myBitmap.GetPixel(0, 0)

でそれぞれのピクセルの色を取得することができます。

監視するには、毎回Forループで監視する場所のピクセルを一つずつ比較するしかないですか?


If myBitmap = myBitmap2 Then


End If


のように一度に画像を比較できれば良いのですが、このようなことはできないでしょうか?


あと、検索してみると
https://oshiete.goo.ne.jp/qa/7221405.html

GetPixel を使用して1ピクセルずつ比較するよりも
OpenCV や OpenCVCharp などのテンプレートマッチングというものを使った方が高速であるというページが見つかりました。

読んでみましたが、具体的にどのように使えば良いのか分かりませんでした。

どなたか最善の方法をお教えくださいませ。





[ □ Tree ] 返信 編集キー/

▲[ 85564 ] / 返信無し
■85565 / 1階層)  Re[1]: 画面の一部の変化を監視したい
□投稿者/ ぶなっぷ (134回)-(2017/11/06(Mon) 13:58:56)
最善な方法が何かは分かりませんが、
単にピクセルの色比較をするだけにしても高速化の方法はたくさんあります。

ノイズのような画像を除けば、普通にちまたにあふれている画像は、
あるピクセルの隣のピクセルの色は同じか近い色でることが多いです。

なので、色比較をする際に、ピクセルの並び順に比較するのではなく、
ある程度、とびとびに比較した方が、違いのある画像であることを
早い段階で検出できる可能性が高まります。

また、対象とする画像をカラーでなく白黒で比較しても問題ない場合は、
RGBの平均値をとって、白黒比較にすれば速くなります。

あと、画像以外で使われることの方が多い手法ですが、チェックサムという
手法もあります。
例えば、3*3,10*10,...などのピクセル範囲で、各ピクセルのXORをとり、
その値をチェックサムとします。
で、元画像と比較画像のチェックサムを比較するとか。
完全比較でなく、99%程度の確率で検出するなら、これで十分です。
https://ja.wikipedia.org/wiki/%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%B5%E3%83%A0
完全比較する場合は、チェックサム一致を確認後、全ピクセルの再比較に
なりますが、そもそも比較対象に不一致画像の方が明らかに多いなら、
チェックサム時点で弾かれる画像が多いので高速化につながります。

などなど

[ 親 85564 / □ Tree ] 返信 編集キー/

▲[ 85564 ] / ▼[ 85569 ]
■85567 / 1階層)  Re[1]: 画面の一部の変化を監視したい
□投稿者/ furu (128回)-(2017/11/06(Mon) 17:09:13)
No85564 (鳥取県 さん) に返信

1ビットの変化でもアクションを起こすには
全ビットを比較する必要があります。

変化を待つので、一致する場合の方が多いと思いますので
最初からデータを一連のメモリにして全比較した方がいいと思います。

参考
 http://www.geocities.jp/tinqwill/cs.html#imagecomp
 http://tinqwill.blog59.fc2.com/blog-entry-46.html

MD5を使用する方法も書かれていますが
うまくいかない場合もあるので、私は好きではありません。

[ 親 85564 / □ Tree ] 返信 編集キー/

▲[ 85567 ] / ▼[ 85572 ] ▼[ 85574 ]
■85569 / 2階層)  Re[2]: 画面の一部の変化を監視したい
□投稿者/ 鳥取県 (2回)-(2017/11/06(Mon) 20:02:55)
ありがとうございます。

うまくいきました

ちなみに、MD5がうまくいかない場合があるというのはどういう場合でしょうか?

https://ja.wikipedia.org/wiki/MD5
2^128通りあるので、
普通なら画像が異なる限り異なる値になるはずですが。

[ 親 85564 / □ Tree ] 返信 編集キー/

▲[ 85569 ] / 返信無し
■85572 / 3階層)  Re[3]: 画面の一部の変化を監視したい
□投稿者/ 774RR (573回)-(2017/11/07(Tue) 06:20:48)
md5 であれ sha であれ、計算するには元データを全部読み取る必要があるのに対して
memcmp 等であれば不一致な箇所が見つかったらそこで終わりにしてよいので
差が発生しやすい場面では、性能面で memcmp のほうが高速。
差が発生しにくい場面では、キャッシュヒット率の面でハッシュのほうが高速かもしれない。
でも暗号学的単方向ハッシュよりは単純に CRC のほうが計算量が少ないのでより高速なはず。

というわけでオイラなら普通に memcmp 使うだろうし (C/C++)
Enumerable.SequenceEqual 使うだろう (C#)

ハッシュ法を採用するくらいなら CRC32 で十分
[ 親 85564 / □ Tree ] 返信 編集キー/

▲[ 85569 ] / ▼[ 85577 ]
■85574 / 3階層)  Re[3]: 画面の一部の変化を監視したい
□投稿者/ furu (129回)-(2017/11/07(Tue) 09:55:06)
No85569 (鳥取県 さん) に返信
> ちなみに、MD5がうまくいかない場合があるというのはどういう場合でしょうか?
>
> https://ja.wikipedia.org/wiki/MD5
> 2^128通りあるので、
> 普通なら画像が異なる限り異なる値になるはずですが。
>
2^128通りしかありません。
1ピクセル24ビット、縦横10で100ピクセルの画像で
2^2400通りです。
同じ値になることはいくらでもありますよ。
[ 親 85564 / □ Tree ] 返信 編集キー/

▲[ 85574 ] / 返信無し
■85577 / 4階層)  Re[4]: 画面の一部の変化を監視したい
□投稿者/ 鳥取県 (3回)-(2017/11/07(Tue) 14:49:18)
なるほど、納得しました

ありがとうございました。
 
解決済み
[ 親 85564 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -