実験データの動画解析を行っています.動画から輪郭を取得し,スライドに示した箇所の速度を求めようとしています.
速度を求めたい箇所の特定の方法,また,速度を求める方法が分からず苦戦しています.この箇所の速度を求める方法が知りたいです.よろしくお願いします.
輪郭を検出した動画,速度を求めたい箇所を示したスライドのグーグルドライブのリンクです.
リンク内容
輪郭検出に用いたコード
import
1import cv2 2 3#動画読み込み 4cap = cv2.VideoCapture('D:/github/sample/python/opencv/video/test2.avi') 5 6 7#背景差分のアルゴリズム?を取得。KNNやMOG2 8fgbg = cv2.createBackgroundSubtractorKNN() 9#fgbg = cv2.createBackgroundSubtractorMOG2() 10 11# 動画書き込み変数設定 12width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 13height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) 14fps = cap.get(cv2.CAP_PROP_FPS) 15fourcc = cv2.VideoWriter_fourcc(*'XVID') 16writer = cv2.VideoWriter('D:/github/sample/python/opencv/video/output_test2.mp4', fourcc, fps, (width, height)) 17 18while(1): 19 ret, frame = cap.read() 20 21 if frame is None: 22 break 23 24 gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) 25 26 #grayを閾値処理 27 thresh = cv2.threshold(gray, 210, 255, cv2.THRESH_BINARY)[1] 28 29 dst = cv2.Laplacian(thresh, cv2.CV_32F, ksize=3) 30 31 #dstをFloat64からuint8に変換 32 dst_uint8 = dst.astype(np.uint8) 33 34 #dst_uint8から輪郭検出 35 _,contours,hierarchy = cv2.findContours(dst_uint8.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 36 37 #輪郭をそのまま書き込み 38 areaframe = cv2.drawContours(frame,contours,-1,(0,255,0),1) 39 40 #ウィンドウサイズ変更して表示 41 areaframe2 = cv2.resize(areaframe , (int(width*1.0), int(height*1.0))) 42 cv2.imshow('frame',areaframe2) 43 writer.write(areaframe2) 44 45 k = cv2.waitKey(30) & 0xff 46 if k == 27: 47 break 48 49 50cap.release() 51writer.release() 52cv2.waitKey(0) 53cv2.destroyAllWindows() 54コード
* 「速度」はフレーム間の時間と移動量から求めればよいのではないかと思うので,主たる問題とは対象の箇所の特定方法ということになりますか?
* 「速度を求めたい箇所」でない部分にも何らかの動きがあり得るものでしょうか?
* 「速度を求めたい箇所」に関する何らかの前提知識を利用できないのでしょうか? (例えば,必ずこういう形状をしているだとか, 画素値(画素値そのものだったり,周辺領域との相対的な関係性だったり)から判定できるかもだとか,他の何か特徴的な対象を見るけることができればそこからの相対的な位置やサイズが推定できるだとか,etc...)
* 最初に人が場所を指定する等,何らかの情報入力を行うことは許容できないのでしょうか?
* 現状「輪郭を取得」しているのは何故でしょうか?(それをどう使う想定なのか)
何の考えも示されないと「丸投げ」にも見えてしまいます.
回答ありがとうございます.
*主たる問題は対象箇所の特定方法ですね,ご指摘のおかげで気づけました.
*「速度を求めたい箇所」でない部分にも動きがあります.二つの気泡の挙動の可視化した動画を解析しようとしているので,気泡の振動が見られます.「速度を求めたい箇所」は気泡の輪郭のうちのある一点です.
*「速度を求めたい箇所」は気泡の重心のy軸上にあります.また,形状は下に凸な形状をしています.
*条件の異なる多数の実験データを整理したいと考えておりますので,特定のピクセルを指定するなどの情報入力は難しいと考えています.
*輪郭を取得している理由には,「速度を求めたい箇所」は気泡の輪郭上にあり,この輪郭データから,何らかの方法で「速度を求めたい箇所」の特定をできないか,と考え取得しています.
まだまだプログラミング勉強中の身で,丸投げになってしまっていましたね...
また,何らかの方法など教えていただければ幸いです.よろしくお願いします.
まずは「とりあえず」,
{気泡の重心のy軸上,形状は下に凸,輪郭上,…} といった既知の条件(のうちのいくつか:とりあえず何らかの判定方法が思いつく条件)に見合う箇所を画像上で「かたっぱしから」見つけるような方法を何か実際にやってみてはどうでしょうか.
「輪郭」のうち「明らかに対象箇所でないだろうとわかる部分」を除く的な方向でもよいでしょうし,とにかく何かを.
ただ考えているよりも,実際に何かをやってみた結果を見てみることで,
「この状態から,もしもこういうことができれば,もっと結果がマシになる」といった具体的な課題が明確になる可能性があるのではないかと.
「振動」が実際どの程度のどういった動きなのかわかりませんが,例えば複数フレームにわたって観測したデータを平均化等すれば「振動」の影響を軽減できるのかもしれません.
輪郭よりもその輪郭を得たときの2値化結果か何かを,フレーム間で比較(差分するとか)してみることで「動き」を見れるのかもしれません.
「凸」な部分というのは輪郭上の各所に関して曲率的なものを計算すれば見つけられるのかもしれません.
返信ありがとうございます.
ご指導を参考にまずやってみようと思います.
また,不明な点が出てきましたら頼らせていただくかもしれませんので,よろしくお願いします.
あなたの回答
tips
プレビュー