2011-08-16 4 views
0

OpenCVの2.2 のWindows 7cvCreateVideoWriterは - フレームのアレイ(IplImageへ*)からAVIファイルを作成

I(下記)C++メソッドを有する後続の呼び出しにファイル名を変更することはできません。ファイル名は、2つのスレッド(「左」と「右」と呼ぶ)がどちらを書き込んでいるかに基づいています。

コード:

void AvtCameraCapture::save_as_video(IplImage **frames,const char * fname, int num_frames, int playback_fps,CvSize &size) 
{ 
    //EnterCriticalSection(&cs); 

    CvVideoWriter *writer = cvCreateVideoWriter(fname,CV_FOURCC('D', 'I', 'B', ' '),playback_fps,size); 
    printf("Writer is %x\n", writer); 
    for (int i=0; i < num_frames; i++) 
    { 
     printf("Wrote frame %d to file %s\n",i,fname); 
     cvWriteFrame(writer,frames[i]); 
    } 
    cvReleaseVideoWriter(&writer); 

    //LeaveCriticalSection(&cs); 
} 

ファイルは、メソッドを実行する最初のスレッドの罰金作成されます。しかし、2番目のスレッドではファイルが作成されません。

私は両方のスレッドのプリントを見て、それぞれに正しいファイル名を付けています。 CvVideoWriter *がnullでないことに注意してください。

writing to file c:\flyball_passes\Left_dog_2.avi 
Writer is 4dabf60 
Wrote frame 0 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 1 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 2 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 3 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 4 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 5 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 6 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 7 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 8 to file c:\flyball_passes\Left_dog_2.avi 
writing to file c:\flyball_passes\Right_dog_2.avi 
Writer is 4d2a930 
Wrote frame 0 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 1 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 2 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 3 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 4 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 5 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 6 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 7 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 8 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 9 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 10 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 11 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 12 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 13 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 14 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 15 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 16 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 17 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 18 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 19 to file c:\flyball_passes\Right_dog_2.avi 
video written to file c:\flyball_passes\Right_dog_2.avi 
Masking for 2.696000 seconds in lane Right. 
Wrote frame 9 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 10 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 11 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 12 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 13 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 14 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 15 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 16 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 17 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 18 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 19 to file c:\flyball_passes\Left_dog_2.avi 
video written to file c:\flyball_passes\Left_dog_2.avi 

私は入力/出口クリティカルセクションのコメントを解除した場合、あるスレッドが他の開始前に書き込みを終了し、まだ何のファイルがあり、最後の取得スレッドのために作成されていない:場合でも

writing to file c:\flyball_passes\Left_dog_2.avi 
Writer is 4f5d298 
Wrote frame 0 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 1 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 2 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 3 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 4 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 5 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 6 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 7 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 8 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 9 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 10 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 11 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 12 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 13 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 14 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 15 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 16 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 17 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 18 to file c:\flyball_passes\Left_dog_2.avi 
Wrote frame 19 to file c:\flyball_passes\Left_dog_2.avi 
video written to file c:\flyball_passes\Left_dog_2.avi 
Masking for 2.570000 seconds in lane Left. 
writing to file c:\flyball_passes\Right_dog_2.avi 
Writer is 4f5d298 
Wrote frame 0 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 1 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 2 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 3 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 4 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 5 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 6 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 7 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 8 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 9 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 10 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 11 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 12 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 13 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 14 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 15 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 16 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 17 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 18 to file c:\flyball_passes\Right_dog_2.avi 
Wrote frame 19 to file c:\flyball_passes\Right_dog_2.avi 
video written to file c:\flyball_passes\Right_dog_2.avi 

をI 2番目のファイルの書き込みをトリガーするイベントを開始するまで数秒間待ってください。それは決して表示されません。

右レーンのファイルの書き出しをトリガーするイベント(左レーンの事前コールcvCreateVideoWriterはありません)を発生させると、右のレーンのaviファイルが表示されます。

洞察力があれば幸いです!

おかげで、

デイブ・トーマス

答えて

1

あなたは別のスレッドからOpenCVの関数を呼び出しています。 OpenCVがではなく、でスレッドセーフなので、システムが正常に動作するという保証はありません。

スレッドで実行されているOpenCV呼び出しを保護するために、mutexなどのメカニズムを使用します。

あなたが同時に実行されてから、コードのこのブロック全体を保護する必要があります。

// lock global mutex 

CvVideoWriter *writer = cvCreateVideoWriter(fname,CV_FOURCC('D', 'I', 'B', ' '),playback_fps,size); 
printf("Writer is %x\n", writer); 
for (int i=0; i < num_frames; i++) 
{ 
    printf("Wrote frame %d to file %s\n",i,fname); 
    cvWriteFrame(writer,frames[i]); 
} 
cvReleaseVideoWriter(&writer); 

// unlock mutex 
+0

おかげで、私は、私は入力/出口クリティカルセクションのコメントを解除した場合、あるスレッドが他の開始前に書き込みを終了しますが、」述べたようにそれでも最後に取得したスレッドのファイルは作成されません。 " –

+0

ワーカースレッドがメインスレッドに信号を送り、ワーカースレッドではなくメソッドを呼び出すようにコードを変更しました。これで問題は解決しました。しかし、私はまだ何が起こっているのか理解したいと思います。実際には意味がありません。別のファイルを書き込む前に、呼び出しの作成/呼び出しを非同期で実行しなければなりません。 –

+1

あなたが本当に理解したいのであれば、これらの機能がOpenCVソースにどのように実装されているかを見てみることをお勧めします。前に述べたように、OpenCVはスレッドセーフではありません。セットアップしているシナリオでは、その関数のほとんどが正常に呼び出せません。期待通りに動かなかったのは驚きではない。 – karlphillip

関連する問題