2011-08-16 15 views
0

的OpenCV 2.2 視窗7cvCreateVideoWriter - 不能在後續調用改變文件名

我有(下圖)一個C++方法,其從框架的陣列(的IplImage *)創建一個avi文件。文件名基於兩個線程中的哪一個(讓我們稱他們爲「左」和「右」)來完成寫作。

代碼:

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); 
} 

文件獲取用於執行該方法的第一個線程創建的罰款。但是,沒有爲第二個線程創建文件。

我看到兩個線程的打印,每個線程都有正確的文件名。請注意,CvVideoWriter *非空。

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 

即使我等待幾秒鐘以啓動觸發寫入第二個文件的事件,它永遠不會顯示。

如果我只發射觸發右車道文件寫入的事件(在左車道上沒有事先呼叫cvCreateVideoWriter),我會看到右車道的avi文件。

任何有識之士將不勝感激!

感謝,

戴夫托馬斯

回答

1

要調用從單獨的線程OpenCV的功能。由於OpenCV不是而不是線程安全,因此不能保證您的系統能夠正常工作。

使用互斥鎖或其他一些機制來保護正在線程上完成的OpenCV調用。

你應該保護的代碼,這整個塊被同時執行:

// 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

我更改了代碼,因此工作線程發信號通知主線程調用方法,而不是在工作線程中執行。這解決了這個問題。但是,我仍然想知道發生了什麼,沒有什麼意義,除非在寫入不同的文件之前,必須執行與調用create/release調用異步的內容。 –

+1

如果你真的想了解我建議你看看這些函數是如何在OpenCV源代碼上實現的。正如我之前所說的,OpenCV不是線程安全的。在您設置的場景中,可以成功調用其中很少的功能。我不驚訝它沒有按預期工作。 – karlphillip