1.迟滞
海康的摄像头迟滞大概会到1秒的量级,一般如果你自己搭个框架做转发,迟滞有时会达到20秒,这是为什么呢?请看例程:
class VideoCamera(object):
def __init__(self):
# 打开系统默认摄像头
self.cap = cv2.VideoCapture(rtsp_url)
if not self.cap.isOpened():
raise RuntimeError('Could not open camera.')
# 设置帧宽和高度
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 640)
...
#other init-process.
# main loop
while self.isRunning:
ret, self.frame = self.cap.read()
...
注意,cv2的输入流是在 cv2.VideoCapture(rtsp_url)处就打开了。你转换后实际输出的视频,大概率就从这个时候开始,然后在漫长的初始化工作完成后才开始接收。所以,你的输出视频的时间起点,人为地拉长了。
修正原则:对于视频流这类资源,什么时候用,什么时候开闸。
2.花屏
导致花屏的错误代码参见:
while self.isRunning:
ret, self.frame = self.cap.read()
else:
flagNotHandle = False
ret = True
if ret:
if(self.queueFrameDone.qsize()>5):
continue;
self.frame = self.frame[zone[1]:zone[1]+zone[3], zone[0]:zone[0]+zone[2]]
self.image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
self.image = cv2.resize(self.image, (640,640))
self.outputs = self.rknn_lite.inference(inputs=self.image) #self.gp_inference(self.image)
self.frame = process_image(self.image, self.outputs) #image in...image out.
self.frame = self.image
#print(type(self.image), type(self.outputs), type(self.frame))
rtsp_out.rtsp_out_push(self.out, self.frame, 640, 640)
ret, image = cv2.imencode('.jpg', self.frame) #to bytes
if ret:
arByte = image.tobytes()
#self.queueFrameDone.put(arByte);
self.resultImage = bytearray(arByte);
self.out.release()
self.rknn_lite.inference和接下来的process_image是高耗时的计算单元。它一定不能阻塞输入流。这是花屏的根本原因。
完全没有技术含量,对吧,是个人都能想到。但程序的bug就是这么造成的。一旦所做的事情比较新,你会很容易丧失掉一些关注点。会犯低级错误。它其实很类似弹吉他。弹吉他没有什么特别大的窍门,但是你是无法自如地弹奏的,你的错误会极顽固。
所以,结对儿编程,代码互检,真的很必要。