最近做了一个需求是接收到请求后,从摄像头里截取实时的图片。
最开始的思路是写一个全局变量cap = cv2.VideoCapture(url),然后在flask的方法里执行cap.read()取出当前的帧,但是发现这样取到的图片不是实时的,基本上是和摄像头建立连接时的截图。原因是,每次执行read时,取到的是上一次截图的下一帧,而不是当前时间里视频流里的图片。
后面改成了每次接收到请求后,都执行一次cap = cv2.VideoCapture(url),然后执行cap.read(),再cap.release()。这样能够取到实时的截图,缺点是每次都需要重新建立一次连接,耗时要1秒左右。
要想解决耗时问题,需要在后台执行一个线程,不停地read视频流,把当前帧记录下来,在接收到请求后,直接返回这个帧。
这里有段代码可以参考 https://www.v2ex.com/t/594221
import threading
import cv2
class NewVideoCapture:
def __init__(self, url, *args, **kwargs):
self.frame_receiver_thread = threading.Thread(target=self.recv_frame)
self._cur_frame = None
self._reading = False
if isinstance(url, str) and url.startswith(("rtsp://", "rtmp://")):
self._reading = True
else:
raise ValueError('url格式不对')
self