Time delay in VideoCapture opencv due to capture buffer
I use a camera to get frames continuesly.In my code,i have use VideoCapture to do that. But when i debug,i find that the frame i got is the old frame. I have asked some guys, they told me that some old frames will store in the buffer and i should use a worker thread to get the latest frame.Also there is a similar question here. Similar question
Here, i have two questions,
If the buffer can store 5 frames and now have stored 5 frames, When does the buffer update?After 5 frames have been got out or just 1 frame? Because i want to know whether i got old frames all the time or i got one new frame then four old frames then change to one lastest frame...
I have debug my code, set a breakpoint at cap >> frame. First frame(loop) Put my hand in and second loop put my hand out of the camera, I found that the image will changed after few frames. Does it mean i got one new frame then four old frames then change to one lastest frame...?
2.Because it's my first time to use thread, i am not sure my code is wrong or not, here is my code,
void task(VideoCapture cap, Mat& frame) { while (true) { cap >> frame; } }
int main() {
Mat frame, image;
VideoCapture cap;
cap.open(0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1600);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
cap >> frame;
thread t(task, cap, frame);
while (true) {
initUndistortRectifyMap(
cameraMatrix, // computed camera matrix
distCoeffs, // computed distortion matrix
Mat(), // optional rectification (none)
Mat(), // camera matrix to generate undistorted
Size(1920 * 1.3, 1080 * 1.3),
// image.size(), // size of undistorted
CV_32FC1, // type of output map
map1, map2); // the x and y mapping functions
remap(frame, frame, map1, map2, cv::INTER_LINEAR);
frame.copyTo(image);
...//image processing loop
}
}
I also have set breakpoint in task() to check the frame, but is the same condition. The image will changed after few frames.I don't know why. Is my code wrong or I can not set breakpoint to check like this as using thread? Can somebody help?Thank you very much.
I think you have a problem with frame.copyTo(image) You cannot copy frame while acquiring a new image you will need a mutex. In your link that's not exactely same problem because it's IP cam. Answer given is for IEEE 1394 Have you got a such cam?
Add in your thread
and in your main
@LBerger Thank you for your comment.Because It's my first time to use thread, i don't know why i need to use mutex here? frame.copyTo(image) just copy the latest frame to image.Also,can you explain that why i need to use imshow?If i use imshow do i needn't use mutex?
Problem occur when thread and main try to access data at same time : main start a copy at same time a new image is ready (cap >>frame) What will be data in image? You can have bus error too.
Now I have try to have an error with your code I didn't succeed.
I can set breakpoint using VS2013 in thread and in main without problem. There is no latency
Thanks for your question I have learnt something don't use reference in argument for thread
@LBerger Thank you for your answer.You mean that my code is right?I haven't get error.But i'm not sure my code is right or not?Also i want to know do i need to use imshow or mutex here?If i use imshow do i needn't use mutex?Sorry for so many question.
may be like this
@Thank you very much!I think this would be help.But in your code when program exits,error happened.It said "mutex destroyed while busy".I tried to solve it,but failed,can you give me some advice?Also, i have question,i have edited my code in my question.When i use remap(), the frame haven't updated.The frame is always the first frame, while i use metux,the result is same.I don't know why
A small sidenote, we also have a camera here with a buffer of 5 frames. To avoid this issue we simply use the native SDK of the camera to disable camera frame buffering, then all your misery is gone.
I think you have to terminate thread before leaving your program. And about update problem I don't know and you should follow @StevenPuttemans comments