OpenCV 2.2 Windows 7
我有一个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
如果我取消注释Enter / Exit关键部分,一个线程在另一个线程开始之前完成写入,但仍然没有为最后到达的线程创建文件:
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文件。
非常感谢任何见解!
谢谢,
戴夫托马斯答案 0 :(得分: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