2012-02-21 1 views
4

私はopenCVとC++を使用してウォーキングのモーション認識を行っています。提供された画像に見られるような効果を得るために、マスクまたはコピーされたイメージを作成したいと思います。 extracted human。以下は、画像の説明です。 人間の歩行の結果の塊が見えます。次に、元のフレームのマスク画像またはコピーされた画像が作成され、バイナリの人間のブロブがマスクされ、マスクされていないピクセルがゼロに設定されます。結果は黒い背景の抽出された人体です。下の図は、人間のブロブをどのように抽出してからマスクするかを示しています。 これは、ビデオシーケンスの5番目のフレームごとに行われます。これまでのところ私のコードは5フレームごとに取得し、グレースケール化して、すべてのブロブの領域を見つけ出し、閾値を適用してバイナリイメージを取得しました。多少のところ、人間のブロブだけが白で残りのイメージは黒。さて、私は人体を抽出しようとしていますが、どのように進むべきかわかりません。私を助けてください。バイナリイメージからブロブをマスキングする

#include "cv.h" 
#include "highgui.h" 
#include "iostream" 

using namespace std; 
int main(int argc, char* argv) { 

CvCapture *capture = NULL; 
capture = cvCaptureFromAVI("C:\\walking\\lady walking.avi"); 
if(!capture){ 
    return -1; 
} 

IplImage* color_frame = NULL; 
IplImage* gray_frame = NULL ; 

int thresh_frame = 28; 
CvMoments moments; 

int frameCount=0;//Counts every 5 frames 
cvNamedWindow("walking", CV_WINDOW_AUTOSIZE); 

while(1) { 
    color_frame = cvQueryFrame(capture);//Grabs the frame from a file 
    if(!color_frame) break; 
    gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height), color_frame->depth, 1); 
    if(!color_frame) break;// If the frame does not exist, quit the loop 


    frameCount++; 
    if(frameCount==5) 
    { 
     cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY); 
     cvThreshold(gray_frame, gray_frame, thresh_frame, 255, CV_THRESH_BINARY); 
     cvErode(gray_frame, gray_frame, NULL, 1); 
     cvDilate(gray_frame, gray_frame, NULL, 1); 

     cvMoments(gray_frame, &moments, 1); 
     double m00; 
     m00 = cvGetCentralMoment(&moments, 0,0); 

     cvShowImage("walking", gray_frame); 
     frameCount=0; 
    } 
    char c = cvWaitKey(33); 
    if(c == 27) break; 
} 

double m00 = (double)cvGetCentralMoment(&moments, 0,0); 
cout << "Area - : " << m00 << endl; 
//area of lady walking = 39696. Therefore, using new threshold area as 30 for this video 
//area of walking man = 67929 

cvReleaseImage(&color_frame); 
cvReleaseImage(&gray_frame); 
cvReleaseCapture(&capture); 
cvDestroyWindow("walking"); 

return 0; 
} 

私はまた、コード内で私が使用していたビデオをアップロードしたいと思いますが、私はここでそれをアップロードする方法がわからないので、誰もがあまりにもそれと私を助けることができるかどうか。できるだけ多くの情報を提供したいと思います。私の質問。

+2

サイドノートでは、 while do {}を使ってチェックしてください。 –

+0

@MartinKristiansen私はopenCVとC++を初めて使いました。コードがいったん動くと、私はそれに満足していました。そこでの使用のために受け入れられない休憩ですか? –

+0

それは、コントロールフローをより透明にしないようにします。whileループが終了するタイミングを実際には明らかにしておらず、コードが大きくなると明らかになりません。 –

答えて

1

最も簡単な方法は、イメージ内の最大のブロブを探すことです(cvfind輪郭が必要な機能になります)。次に、他のすべてのブロブをblacに設定します(すべての輪郭をスキャンし、cvfloadfillを使用します)。 最後に、対象となるピクセルが白であれば、バイナリイメージ全体をスキャンします。何もしない場合、ピクセルが黒であれば、5番目のフレームの対応するピクセルを黒に設定します。

+0

私はcvBlobLibというライブラリをインストールする必要はありませんか?ブロブを抽出する方法を研究するとき、私は数回言及しましたが、O'ReillyもopenCVリファレンスマニュアルもそれについて何も持っていなかったので、私はそれを少し疑問に思っていました。私は実際には、そのcvBlobLibに頼るのではなく、輪郭の方法を好むでしょう。私は本当にこれがうまくいくことを願っています –

+1

私はそれについては分かりませんが、私はCvBlobがOpencvの最後のバージョンに含まれていると思います。 (それでもチェックする) – andrea

関連する問題