I've integrated an IP camera with OpenCV in Python to get the video processing done frame by frame from the live stream. I've configured camera FPS as 1 second so that I can get 1 frame per second in the buffer to process, but my algorithm takes 4 seconds to process each frame, causing stagnation of unprocessed frame in the buffer, that keeps growing by time & causing exponentially delay. To sort this out, I have created one more Thread where I'm calling cv2.grab() API to clean the buffer, it moves pointer towards latest frame in each call. In main Thread, I'm calling retrieve() method which gives me the last frame grabbed by the first Thread. By this design, frame stagnation problem is fixed and exponential delay is removed, but still constant delay of 12-13 seconds could not be removed. I suspect when cv2.retrieve() is called its not getting the latest frame, but the 4th or 5th frame from the latest frame. Is there any API in OpenCV or any other design pattern to get this problem fixed so that I can get the latest frame to process.
Asked
Active
Viewed 3,092 times
11
user202729
- 2,782
- 3
- 19
- 30
Hemant Mahsky
- 121
- 1
- 7
-
2Why do you want a big buffer when your algorithm consumes at slower rate than information is produced. My suggestion would be to use buffer with only two image slots. One of writing from camera(write buffer, one image only) and other reading for processing(read buffer, one image only). Overwrite the write buffer on new image from camera. – harshkn Aug 09 '17 at 10:56
-
1@harshkn can you please tell how to reduce buffersize? I tried "video.set(cv2.CAP_PROP_BUFFERSIZE, 1)" on my Raspberry Pi with Ubuntu 16.04. It resulted in a message saying "VIDEOIO ERROR: V4L2: setting property #38 is not supported True" – Muhammad Abdullah Oct 31 '17 at 11:03
-
There are some good answers with detailed explanations (and workarounds) in [c++ - OpenCV VideoCapture lag due to the capture buffer - Stack Overflow](https://stackoverflow.com/questions/30032063/opencv-videocapture-lag-due-to-the-capture-buffer); **however** the answers are in C++ and you have to port it to Python. – user202729 Aug 14 '21 at 00:13
1 Answers
2
If you don't mind compromising on speed. you can create a python generator which opens camera and returns frame.
def ReadCamera(Camera):
while True:
cap = cv2.VideoCapture(Camera)
(grabbed, frame) = cap.read()
if grabbed == True:
yield frame
Now when you want to process the frame.
for frame in ReadCamera(Camera):
.....
This works perfectly fine. except opening and closing camera will add up to time.
amitnair92
- 447
- 6
- 18