部屋の直ぐ前の電線に時々リスが通ります。カメラを準備している間にいなくなってしまいます。そこでPCカメラ(ネットカメラ)の画像をVBに取り込んで画像の中でリスの通る一部分の色を常時比較しておけば警報装置になると考えました。その方法として ①VBでカメラ画像をそのまま取り込めるのか? ②現在あるソフトで表示されている画像を定期的にVBに取り込む ③現在の表示ソフトでMpeg画像をファイルに落してそれをVBソフトで読みこむ などの方法があるかと考えましたが実際にはどうしたらよいかわかりません。 リスの動きを見ているとそれほど早くもないので取り込む頻度は1秒間に②画像以上あれば良いかと思います。 なお現在の添付ソフトで表示されている画像は280x320程度です。 どのような方法が一番簡単か? また画像を(例えば)Picture1に表示させる具体的方法などご教示ください。
まだレスがありませんので質問を絞らせていただきます。
「現在画面に表示されているスクリーン全体の画像をVBに取りこむ」方法はあるのでしょうか? 例えば「PrintScreen」ボタンを(VBで自動的に)押して画面全体の画像をクリップボードに自動的に取りこむということが出来ればそれでもOKなのですが。 宜しくお願いします。
DirectShowを使えばVBからでもPCカメラの画像を取り込むことができます。
環境にもよりますが、ビットマップでも取り込めるので
PictureBox等へ描画して保存するなり、
一つ前の画像と比較するなりできますね。
ただリスとかだと動きが速いかと思いますので
画像比較を工夫しないと連続的には撮れないかも・・・
黒猫トラさん、ありがとうございます。DirectShowなどという便利なものを利用できるとは思っても見ませんでしたので大いに期待しています。PictureBoxに取り込むことができるとは大変ありがたい機能です。
電線を伝わるリスはそれほどの速度もありません。また通過位置も極めて限られていますのでPicture1.Point(x,y)で多くても20点比較すれば間違いなく捕捉できると思います。
そこで早速「DirectShow」の出ている本はないかと「技」シリーズや「極意」シリーズを見渡しましたが残念ながらどこにも出ていませんでした。 お手数ですが具体的なサンプルコードなどの情報をご存じでしたら教えてください。
DirectShowとは何かをWEBで探して見ましたところ「DirectX」の環境で動くもののようであることがわかりました。 これは一寸ハードルが高いと直感しました。自分用に簡単に作って・・・と思っていましたので手に負えそうにないかと落胆しているところです。
そこで現在のカメラソフトを動かして画像を表示させておき、「PrintScreen」キーを押す動作(イベント)をタイマーを使ってVBのソフトから実行してクリップボードにスクリーンの画像をコピーし、それをPicture1に取り込む、というアイデアを考えました。 こんなことは可能でしょうか?
オーバーレイとかして動画を画面に表示するソフトだったら
PrintScreenでは絵がとれないと思うんですが。
そのカメラソフトを動かしながら手動でPrintScreenを押して
ちゃんと絵はとれてますか?
くまさんの言うとおりPrintScreen方式の方が難しいでしょう。(^^;
普通のツールだったらデフォルトでオーバーレイのレンダラを使いますから。
DirectShowを使って、ピクチャーボックスに表示させるならこんな感じです。
(一年前ぐらいにDirectShowを試したときに作った奴を修正して
ダイエットしたやつなのでエラー処理なんぞほとんどしてません。
またWindowsXPで画面モードが32ビットでないと動かないかも)
(1)「ActiveMovie control type library」を参照設定
(2)フォームにPictureBox(名前:Picture1)を配置
(3)下記コードをコピペ&ゴー
Option Explicit
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Declare Function SetDIBitsToDevice Lib "gdi32" ( _
ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, _
ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, _
BitsInfo As BITMAPINFOHEADER, ByVal wUsage As Long) As Long
Private mGraph As FilgraphManager
Private Sub Form_Load()
Set mGraph = New FilgraphManager
'キャプチャフィルタを探してグラフに追加
Dim regflt As IRegFilterInfo
Dim flt As IFilterInfo
For Each regflt In mGraph.RegFilterCollection
If regflt.Name = "PC Camera (6005 CIF)" Then 'カメラのフィルタ名
regflt.Filter flt
Exit For
End If
Next
'グラフ作成(手抜き)
Dim pp As IPinInfo
flt.Pins.Item 0, pp
pp.Render
'PictureBoxのサイズを変更
Dim bv As IBasicVideo
Dim vx As Long, vy As Long
Me.ScaleMode = vbPixels
Set bv = mGraph
bv.GetVideoSize vx, vy
With Picture1
.BorderStyle = 0
.Move 0, 0, vx, vy
.AutoRedraw = True
End With
'ビデオレンダラウィンドウを隠す
Dim vw As IVideoWindow
Set vw = mGraph
vw.Owner = Me.hWnd
vw.SetWindowPosition -vx, -vy, vx, vy
'カメラ起動
mGraph.Run
End Sub
Private Sub Timer1_Timer()
If mGraph Is Nothing Then Exit Sub
'ビデオサイズ取得
Dim bv As IBasicVideo
Dim vx As Long, vy As Long
Set bv = mGraph
bv.GetVideoSize vx, vy
'ビットマップ読み込み
Dim sz As Long
Dim img() As Long
sz = 10 + vx * vy
ReDim img(sz - 1)
bv.GetCurrentImage sz * 4, img(0)
'描画準備
Dim bi As BITMAPINFOHEADER
With bi
.biSize = Len(bi)
.biWidth = vx
.biHeight = vy
.biPlanes = 1
.biBitCount = 32
End With
'描画
SetDIBitsToDevice Picture1.hdc, 0, 0, vx, vy, 0, 0, 0, vy, img(0), bi, 0
Picture1.Refresh
End Sub
カメラのフィルタ名はカメラ毎に違いますから
お使いのカメラに合わせて変更する必要があります。
名前は・・・DirectX SDK付属ツールのGRAPHEDITあたりで調べてください(^^;
ちなみにDirectShow関係の書籍を探されるもいいですが、
DirectX-8 SDKのVC用ヘルプにVB用の記述がありますよ。
Googleで「VB DirectShow」で検索すれば
サンプルコードだって見つかりますし。
くまさん、黒猫トラさん ありがとうございました。
1.PrintScreenはお説の通りダメでした。 カメラの絵だけが出ていて肝心の絵の部分は真っ黒でした。(PrintScreenは何でも取り込んでいるものと思っていました。)難解なDirectXを回避してできればと内心期待していたのですが・・・
2.膨大なサンプルコードをありがとうございました。 今コードをコピーして開発用のマシンにコピーしましたのでこれから試してみます。実はこのハードルを越えると僕のやりたいことが幾つも解決出来るのですが・・・ 今まではチンプンカンプンで挫折していました。 今回こそ乗り越えたいです。
なおカメラなどのスペックは
①カメラ 多摩電子 (型番不明)
②表示ソフト VP-EYE 4.0
③ドライバー名 PC Camera (6005CIF)
です。
頂いたコードは理解できておりませんが貼り付けてやってみます。 これを機に新しい技術を吸収したいものです。 ありがとうございました。
黒猫トラさん、やってみました。 どうやらカメラも同じなので頂いたコードのままで良さそうでした。Form1にPicture1とTimer1を配置しました。 なおTimer1のIntervalは30にしてみました。
その結果 Private mGraph As FilgraphManager のところで「コンパイルエラー ユーザー定義型は定義されていません」というメッセージが出てしまいました。 Typeで宣言すればよいのではないかと思いましたが何しろ当方はど素人なので理解できないままの完全コピーですので対応が取れません。 おんぶにダッコに肩車で申し訳ありませんが対応策を教えてください。 上手く動いたら・・・と思うと胸が高鳴ります。 宜しくお願いします。
ここは技術者の掲示板なので余計な修飾語は不要と思います。
論旨を明確にしてください。
で、参照設定がうまくいってないのではないですか?
できました。ありがとうございました。参照設定が上手くいっていないことが原因でした。(修飾語は申し訳ありませんでした)
経過をご報告しますと
①最初はTimer1のインターバルを30にしていましたが画面は真っ黒でした。
②しかし何度もRunさせていましたが最初の一瞬だけチラッと画面が見えるような気がしたので試しにインターバルを1000にしましたら画面が出ました。
③どこまで早くできるかスクロールバーでインターバルを可変にしてみましたがこのカメラ(6005CIF)だと500程度が限界のようです。
現在は道路を走る車の検出でテストしていますが画像が正確に表示されている限り問題なく移動物体を検出できていますが問題があります。
①「画面が急に真っ暗になりその後段々回復していく」という現象が繰り返し発生します。 これはソフトの問題なのでしょうか(回避策はあるのでしょうか)、それともカメラを変えればなおるものなのでしょうか? (なお、この現象はカメラに付属しているVB-EYEというソフトでも時々発生します)
②タイマーのインターバルを早くすると画面が真っ黒になりますが「If mGraph Is Nothing Then Exit Sub」によるトラップに問題があるのでしょうか?
以上宜しくお願いします。
前回の質問は次のように解決しました。 いろいろありがとうございました。
①PCカメラの画面が急に暗くなってしまう→外景を写しているため露出オーバーとなってしまいカメラが補正しきれない?→かなり濃いフィルターで強制的に暗くしてコントロール範囲に納めたらほぼこの現象はなくなりました。(カメラは元々室内用?
②急に暗くなった場合は画面全体が変化するので複数の場所の変化が同時に起きた時は「発見」の情報を流さない。
などにより当初の目的である「リスが通過した時の警報」は完全なものになりましたので解決にチェックを入れました。大感謝です。
---解決のチェックを入れた後ですが分かりましたら解説をお願いします。---
当方で持っているカメラに付属していたソフトでは殆ど「動画」で写りますがVBでは一秒に1.5回程度しか画面が変わりません。(Timerのインターバルを変化させても。 また「AutoRedraw=FalseにしたりRefreshなど、時間の掛かりそうなものを排除しても変りありませんでした。) これはVBだから遅いのでしょうか? VBで早くする方法はあるのでしょうか? 宜しくお願いします。
> ---解決のチェックを入れた後ですが分かりましたら解説をお願いします。---
> 当方で持っているカメラに付属していたソフトでは殆ど「動画」で写りますがVBでは一秒に1.5回程度しか画面が変わりません。
それは先に示したサンプルコードがそういうものだからで、
PictureBoxに描画させる為にその遅さになっているんです。
単に表示させるならば、先のサンプルの「ビデオレンダラウィンドウを隠す」ってところをコメントアウトしてみてください。
(タイマーの処理も止めないと、ウィンドウが出たり消えたりするかもしれんです。
あと余談ですが、こういう高速で書き換えが必要なためにPrintScreenで取得できないような技術が必要になるんです)
また当方と同じチップのカメラを使ってるみたいですが、そのチップだと最大で30fpsまでいけます。
しかし、fpsの設定をしていないためデフォの設定で遅くなってるんでしょう。
(それとレンジが結構狭いんで、暗いとフレームレートが落ちますね)
その辺の設定をするには、タイプライブラリとか作らないと無理ですね。
あとイメージを取得するにはサンプルのようなやり方ではなく
「サンプルグラバ」というのを使うのが普通だと思います。(だたこれだとVBから使えない)
この辺については下記のページが参考になると思いますよ。
http://www.geocities.co.jp/SiliconValley/7406/tips/dshow/index.html
黒猫トラさん 各種の情報をありがとうございました。
ご推奨のDirectShowのサイトを見ました。実に色々なTOOLが用意されていることが分かりました。そして見慣れた(?)コードが出てきました。お送り頂いたコードは現在理解できませんがこれを見ていると「理解」よりもある程度定型化されたコードを何度も打って失敗しながら試していくことにより慣れてしまうことが大事で、それにより少しづつ理解が進むのではないかと感じました。
いずれにせよ今回の経験により曲がりなりにも今回自分のPCでDirectShowの片鱗を活用できるようになったことは大きなステップアップになったと感じます。天体望遠鏡への適用など夢が広がります。 感謝あるのみです。
ツイート | ![]() |