「うちの夫婦・家族っていいな」と思った瞬間大賞 キャンペーン

VB.netでプログラミングの勉強をしています。

画面上の指定した範囲内に、指定した(5×5くらいの小さな)画像があればTrue、無ければFalseを返したいのですがどのようにすれば良いのでしょうか

考えついたのが画面をキャプチャし、指定の範囲を切り取り、その中に指定した画像があればTrueを返すというプログラムです

まず、画面をキャプチャし、トリミングするというところまではCapture ScreenというAPI等を使い実装できたのですが、そこに同じ画像があるかどうか、どう判定すればいいのかがわかりません。

以前、UWSCのchkimg関数を使って同じような物を作ったのですが、処理もそれなりに早くて使いやすかったように思います。

VBで同じような動作をさせるにはどのようにすればよいのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (1件)

OpenCV や OpenCVCharp などのテンプレートマッチングを使用するのが良さそうに思います。


http://www.geocities.jp/konbiki/tips/opencv/open …

GetPixel を使用して、1 ピクセルずつ比較していく方法もあります。
http://okwave.jp/qa/q3151246.html
    • good
    • 0
この回答へのお礼

!!!
ありがとうございます!まさに求めていたのはこれです!早速試してみます!

お礼日時:2012/01/04 10:55

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QExcelVBAでJPEG画像を比較

ExcelVBAの初心者です。
Excelにイメージコントロールを2つ貼り付け、片方には任意のJPEGファイルを表示させるというVBAを作成しました(やっとの思いで)。JPEGファイルは特定のフォルダに多数存在しています。
片方のJPEGファイルが表示された時、同じ画像の(又は酷似している)ファイルがあれば、その画像をもう1つのイメージコントロールに表示させるという事はできるのでしょうか。もしできるのであれば、その方法と記述を教えて頂きたいのです。
なにぶん初心者です...よろしくお願いします。
ちなみに、Excel2000です。

Aベストアンサー

過去ログの一例。
http://okwave.jp/qa3151246.html
http://okwave.jp/qa3660798.html

検証してませんし初級者ですが、たぶん読み込んだ画像に対して実行するのではないかと。
であれば全てのファイルを順次読み込んで比較する事になるのかな。

ただ「酷似」と言うのは、「目で見て似ている」のと「データの羅列が類似している」
のとでは違いますし、羅列であればその許容範囲をどのように求めるつもりなのかなって
ちょっと疑問に思いました。

専門ではないので、的はずれの可能性は大きいですけど。

QBitmap.GetPixelより高速なもの

いまVBでBitmap.GetPixelを使って、グレースケールの画像のRGBを取得しています。
まあグレースケールなんでRGB同じなのでとりあえずRの値を使うとして、
200*300の画像をFor文でBitmap.GetPixelを使うととてもじゃないぐらい遅いです。
ある程度調べると、LockBits()というものが見つかったのですが使い方がわかりません。 教えてください。

Aベストアンサー

補足されたコードをもう一度見直したほうがいいように思います

for LY ...
 for LX ...
  myBitmapの構築
  色情報の取得
  if 色判定 then
   Graphicsオブジェクトの生成
   描画
  end if
 next ' LX
next ' LY
といった構成になっています

2重ループの内側で myBitmapを毎回作成するのは無駄です
Graphicsオブジェクトの生成もループの内側でやった場合
連続して判定がTrueを返した場合毎回生成しなおします

変化しないものはループの外へ追い出して見ましょう

' Create a Bitmap object from an image file.
Dim myBitmap As New Bitmap(".\Test01.jpg")
Dim P As Graphics = PictureBox2.CreateGraphics

Dim LY As Long
' イメージ全体で行うなら 299をmyBitmap.Heightに
' 199を myBuitmp.Widthに変更したほうがいいでしょう
' 1行おきの処理なら Stepで調整する
For LY = 0 To 299 Step 2
  Dim LX As Long
  For LX = 0 To 199
    Try
      ' Get the color of a pixel within myBitmap.
      Dim pixelColor As Color = myBitmap.GetPixel(LX, LY)
      Red = pixelColor.R
      Label1.Text = "R" + Red
      If (Red > 40) Then
        P.FillRectangle(Brushes.White, LX, LY, 1, 1)
      End If
    Catch ex As Exception
    End Try
  Next
  ' 1行おきの処理をしたいのであれば For文にStepをつけましょう
  ' Forなど自動でカウントアップ(またはダウン)するものを
  ' コード内でいじってしまうのはあまり行儀がよくありません
  ' LY = LY + 1
Next

といった具合で 速度がずいぶん改善されるように思います

補足されたコードをもう一度見直したほうがいいように思います

for LY ...
 for LX ...
  myBitmapの構築
  色情報の取得
  if 色判定 then
   Graphicsオブジェクトの生成
   描画
  end if
 next ' LX
next ' LY
といった構成になっています

2重ループの内側で myBitmapを毎回作成するのは無駄です
Graphicsオブジェクトの生成もループの内側でやった場合
連続して判定がTrueを返した場合毎回生成しなおします

変化しないものはループの外へ追い出して見ましょう

' Cre...続きを読む

QVBA内でのGetPixelを使用した時のRGB値取得の方法

初めまして、
現在、ExcelVBAを勉強中です。
表題の通りですが、LoadPicture関数でbmpを読み込み、ピクセルのRGB値を取得しようとしているのですがうまくいきません。色々と検索して回ったのですが、探し方が悪いのか見つかりませんでした。
以下はソースになります。
Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long
Sub Sample(bmpfile as String)
bmpdata = LoadPicture(bmpfile)
'デバッグ用表示
MsgBox (Hex(GetPixel(bmpdata, 1, 1)))
End Sub
サンプルで使用した画像データは10x10のすべて黒(#000000)で塗りつぶしたデータですが、デバッグ表示で見てみると何故かFFFFFFFFと表示されます。ほかの色も試しましたがデバッグ表示結果は同じでした。
どなたか詳しい方、原因などを教えて頂けますでしょうか。
よろしくお願いいたします。

初めまして、
現在、ExcelVBAを勉強中です。
表題の通りですが、LoadPicture関数でbmpを読み込み、ピクセルのRGB値を取得しようとしているのですがうまくいきません。色々と検索して回ったのですが、探し方が悪いのか見つかりませんでした。
以下はソースになります。
Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long
Sub Sample(bmpfile as String)
bmpdata = LoadPicture(bmpfile)
'デバッグ用表示
MsgBox (Hex(GetPixel(bmpdata, 1...続きを読む

Aベストアンサー

LoadPictureの戻り値はデバイスコンテキストハンドルでは無いのでエラーになっているのだと思います

LoadPictureの戻り値をLong型の変数に格納するとこれはビットマップハンドルが帰ってくるのだろうと思います
これを デバイスコンテキストハンドル(HDC)にそのまま変換する方法はありません

UserFormのImageコントロールにしてもHDCを取得する術がありません

やるなら GDIのGetObjectでビットマップ構造体のデータを取得
この構造体のメンバーからイメージバッファを計算して Byte型配列にデータを GetBitmapBitsで取得
データの欲しい座標から配列の位置を特定
といった手順が必要でしょう

QVBAで画像のドット位置を探す。

ビットマップ等の画像上にドットがいくつかあるとします。
このドットの位置を解析したいです。
あくまでこれをエクセルのVBAで実現させたいです。(VBはもっていないため)

私の考える流れは、(1)画像を取り込む。(2)黒色のドットを探す。(3)黒色ドットの位置を取得する。

上記をもとに、具体的に知りたいことを記載します。
(1)画像ファイルをどこにとりこめばよいかを知りたいです。エクセル上?ユーザーフォーム上?
(2)ドットを探すにあたり黒色ドットの定義をどのように記述したらよいか知りたいです。
その定義にあう画像領域内のドットを探すことが目的です。
また検索する画像領域の範囲の定義の仕方を知りたいです。
(3)見つかったドットの位置の抽出の仕方を知りたいです。

そもそも、別のアプローチ方法などあればご教授していただきたいです。
ちなみにですが、画像処理についての知識はまったくない素人です。。

Aベストアンサー

> 内容に関してですが、bData(19) bData(23)は何を意味しているのでしょうか?
> ヘッダーの解説には、19と23についての記載がありませんでした。

ヘッダの解説をよく見てみてください。
[18]からの4byte(18~21)が画像の幅[ピクセル]
[22]からの4byte(22~25)が画像の縦[ピクセル] です。

ですから、本当は4byte分でピクセルサイズを求めるべきなのですが、私のコードは予めお断りしている通り手抜き版なので「そんなに大きな画像は読み込まないだろう」とたかをくくって2byte(18と19、22と23)だけ使ってピクセルサイズを求めています。
どの辺りが手抜きなのか説明するべきでしたね。失礼しました。

BMPは1ピクセルごとに情報が取り出せるので簡単ですが、PNGやJPEGは圧縮されているのでそう簡単にはいきません。
私なら他のアプリでBMPに変換してしまいます(^^;

Q画像から文字を認識してテキストに変換したいです。

bitmap型のデータを渡すと認識されたstringが返されるようなdllがあったら教えてください。

Aベストアンサー

#1 さん同様、商売のキモですから甘いもんじゃないと思います。
オープンソース系コミュニティをあたってみて自作するとか。

ちなみに以下は Office 2003 に付属している Microsoft Office Document Imaging (MODI) をオートメーションでコントロールして OCR 機能を拝借する手法が書かれているようです。
C# ですが VB.NET なら移植も問題ないでしょう。
http://www.codeproject.com/KB/office/modi.aspx

参考URL:http://www.codeproject.com/KB/office/modi.aspx

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

Q画像ファイルを配列に格納する方法

http://oshiete.goo.ne.jp/qa/8852322.html


このページで、
配列から直接圧縮画像ファイルを出力する方法を教えていただきました。

次は圧縮画像ファイルから配列を読み取るプログラムを作りたいと考えています。

http://tanlab.blog.fc2.com/blog-entry-31.html

このページで画像ファイルをメモリに読み込む方法は書かれていて、
GdipCreateBitmapFromFile(ByVal StrPtr(file1), image)

で変数imageに読み込むことができます。

このimageを上記のページの変数pDstBitmapに回すことで、
読み込んだ画像を別の画像として出力できることがわかりました。

いまやりたいことは
変数imageあるいは変数pDstBitmapを配列に書き出すことなのですが
どうやれば良いでしょうか?

これらの変数はLongとして定義されていて、
型が配列ではないのですが
どのようにして扱えば良いのでしょうか?

一応、検索などして調べてみましたが
分かりませんでしたので教えてください。

http://oshiete.goo.ne.jp/qa/8852322.html


このページで、
配列から直接圧縮画像ファイルを出力する方法を教えていただきました。

次は圧縮画像ファイルから配列を読み取るプログラムを作りたいと考えています。

http://tanlab.blog.fc2.com/blog-entry-31.html

このページで画像ファイルをメモリに読み込む方法は書かれていて、
GdipCreateBitmapFromFile(ByVal StrPtr(file1), image)

で変数imageに読み込むことができます。

このimageを上記のページの変数pDstBitmapに回すことで、
読み込んだ画像を別...続きを読む

Aベストアンサー

http://oshiete.goo.ne.jp/qa/8852322.html
(http://oshiete.goo.ne.jp/qa/8852322.html)
で回答した者ですが、実はあの#1-2のコードには前半があって、ファイルからセル色に取り込んでいるのです。その部分を投稿しますので改造して下さい。

'(2) ファイルから画像を読み込みbitmapオブジェクトに変換する
If GdipCreateBitmapFromFile(ByVal StrPtr(strInName), pSrcBitmap) <> 0 Then
Exit Sub
End If
'(3) 読み込んだ画像のサイズを取得
'画素数は480x360程度でないと、書式が多すぎるというエラーが発生する
GdipGetImageWidth pSrcBitmap, lngWidth
GdipGetImageHeight pSrcBitmap, lngHeight

'(4) bitmapオブジェクトから1画素ずつ読み込んで、エクセルのセルのColorに設定
'GDI+から取得する色は透明度を含むARGBであるが、セルに設定する場合はBGRに変換する必要がある
Application.ScreenUpdating = False
For y = 0 To lngHeight - 1
For x = 0 To lngWidth - 1
'画素の色を取り出し、文字列に変換する
'ビットシフトは面倒そうなので、スピードは犠牲にして?文字列に変換して処理
GdipBitmapGetPixel pSrcBitmap, x, y, myARGB
strARGB = Hex(myARGB&)
With ActiveSheet
Range(.Cells(1, 1), .Cells(1, lngWidth)).ColumnWidth = 1.63
'ARGB->BGRに変換してセル色に変換
.Cells(y + 1, x + 1).Interior.color = RGB(CInt("&H" & Mid(strARGB, 3, 2)), CInt("&H" & Mid(strARGB, 5, 2)), CInt("&H" & Mid(strARGB, 7, 2)))
End With
Next x
Next y
Application.ScreenUpdating = True

>これらの変数はLongとして定義されていて、
>型が配列ではないのですが
>どのようにして扱えば良いのでしょうか?
ここでのimage、pDstBitmapは「ハンドル」と言われるものです。画像ファイルが読み込まれ、ビットマップオブジェクトが生成された時に、Windowsによってつけられた管理番号といった感じでしょうか。

ついでに、先のQAのARGBのオーバーフローについてですが、下記をご参照下さい。
http://support.microsoft.com/kb/189323/en-us
機械翻訳したページもありますが、よけいに分かり難いような...
http://support.microsoft.com/kb/189323

http://oshiete.goo.ne.jp/qa/8852322.html
(http://oshiete.goo.ne.jp/qa/8852322.html)
で回答した者ですが、実はあの#1-2のコードには前半があって、ファイルからセル色に取り込んでいるのです。その部分を投稿しますので改造して下さい。

'(2) ファイルから画像を読み込みbitmapオブジェクトに変換する
If GdipCreateBitmapFromFile(ByVal StrPtr(strInName), pSrcBitmap) <> 0 Then
Exit Sub
End If
'(3) 読み込んだ画像のサイズを取得
'画素数は480x360程度でないと、書式が多すぎるという...続きを読む

Qフルパスから最後のディレクトリ名を取得したい。

vb.netなのですが、例えば
c:\aaa\bbb\ccc\ddd\eee\fff.exe
というフルパスがあったとして、
eeeというディレクトリ名を取得したいのですが、
何か良い方法はないでしょうか。
それぞれのディレクトリ名の文字数や階層数は
決まっていないのですが、オススメの方法が
ありましたら、教えて頂けると助かります。

Aベストアンサー

MessageBox.Show(IO.Path.GetFileName(IO.Path.GetDirectoryName(myPath)))

IO.Path の GetDirectoryName でフォルダのフルパスを取得して、さらに IO.Path の GetFileName で最終フォルダ(またはファイル)の名前を取得。

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

QForm間の値の渡し方

1つのForm上のコマンドボタンで別のFormを表示、そこで変数に値を入れ、そのFormを閉じ、元のFormでその変数を使いたいのですが、どうもうまくいきません。
実施したやり方は、一方のFormの宣言領域で、”Public abc As String”を宣言、両方のFormの(変数に値を入れた方と変数を使う方の)プロシージャーの宣言では引数として(abc As String)と記述しました。
因みに、両プロシージャーともイベントプロシージャーです。何か基本的なことができていないのだとは思いますが、どなたか教えていただけませんか?よろしくお願いします。

Aベストアンサー

すでに何件か回答があがっていますので、少し変わった方法をご参考までに。

あまり使われませんが、Formにはtagというプロパティがあります。
これは「文字列形式であれば何でも格納できる」という、上手く使えば便利なプロパティです。

FormAからFormBを呼び出し、FormBで変更した値をFormA.tagにセットします。
ここでFormBをUnloadしてもFormA.tagの値は影響を受けないので自由に使えます。

複数の値を呼び出し元に戻してやる場合に、区切り文字(カンマなど)で連結した文字列をtagに格納し、呼び出し元で区切り文字でsplitして、複数の値を受け渡すという手法をよく使っています。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報