Reputation: 696
I'm reading video frames from a webcam and storing them in a std::vector < cv::mat > variable.
Each time I want to calculate the frame difference between two consecutive frames, I use the following code but the result is always zero and I get a zero matrix !! I have two threads in my program, one for reading video frames and one for processing the video frames. whenever I'm going to write into the vector I use a mutex in order to prevent any further problems in pushing back or removing frames.
Here is my pseudo code :
std::vector<cv::Mat> IMAGE_VEC;
Qmutex IMAGE_VEC_MUTEX;
Main_Thread()
{
while(1)
{
cv::Mat Frame,Reserved_Frame;
Camera.read(Frame);
Frame.copyTo(Reserved_Frame);
QMutexLocker Locker(&IMAGE_VEC_MUTEX);
IMAGE_VEC.pushback(Reserved_Frame);
Locker.unlock();
cv::imshow("Frame",Frame);
cv::waitKey();
}
}
And My process Thread is:
Process_Thread()
{
for (; IMAGE_VEC.size() > 1 ;)
{
cv::Mat frame1;
IMAGE_VEC[0].copyTo(frame1);
cv::Mat frame2;
IMAGE_VEC[1].copyTo(frame2);
cv::subtract(frame1,frame2,result);
QMutexLocker Locker(&IMAGE_VEC_MUTEX);
IMAGE_VEC[0].release();
//qDebug()<<"IMAGE_VEC Step2 size is: "<<IMAGE_VEC.size()<<"\n";
IMAGE_VEC.erase(IMAGE_VEC.begin());
Locker.unlock();
}
}
I calculated the mean and standard deviation of each frame in Process thread and they were always the same ! I could solve this problem by changing the thread process code to this code
Process_Thread()
{
for (; IMAGE_VEC.size() > 1 ;)
{
cv::Mat frame1;
IMAGE_VEC[0].copyTo(frame1);
QMutexLocker Locker(&IMAGE_VEC_MUTEX);
IMAGE_VEC[0].release();
//qDebug()<<"IMAGE_VEC Step2 size is: "<<IMAGE_VEC.size()<<"\n";
IMAGE_VEC.erase(IMAGE_VEC.begin());
Locker.unlock();
delay_ms(1000); // more than 1 second delay !!!
cv::Mat frame2;
IMAGE_VEC[0].copyTo(frame2);
cv::subtract(frame1,frame2,result);
}
}
why this happens ? why a delay more than 1 second should be used to make this code work ? I tried it with a delay less than 1 second and the result were as previous step ...
I'd appreciate your comments on this.
Upvotes: 0
Views: 486
Reputation: 14053
You may need to copy or clone your frame to another Mat, then push to your vector, change your code like
cv::Mat Frame;
Camera.read(Frame);
Mat tmp=Frame.clone(); //clone frame to new Mat
IMAGE_VEC.pushback(tmp);
Otherwise you are passing same pointer on each pushback.
Upvotes: 1