安装ffmepg并添加到环境变量中,流媒体使用m7s
运行效果 SSD:检测在10ms左右,yolov5在100ms左右

app.py

#!/usr/local/bin/python3
# encodin: utf-8
import subprocess
import threading
import time
import cv2
import os
from OpenVinoYoloV5Detector import OpenVinoYoloV5Detector
from OpenVinoSSDDetector import OpenVinoSSDDetector
class RTSCapture(cv2.VideoCapture):
_cur_frame = None
_reading = False
_frame1 = None
# 视频播放质量 值越大越模糊
# _quality = 2.5 # 1;1.5;2;2.5
# _interval_check = 1000 # 检测间隔 0 不跳帧 1秒10帧
_quality = 1
_interval_check = 0
_recvtime = 0
@staticmethod
def get_even(num):
if (num % 2) != 0:
num = num + 1
return num
@staticmethod
def create(srcstream, dststream):
rtscap = RTSCapture(srcstream)
rtscap.frame_receiver = threading.Thread(target=rtscap.recv_frame, daemon=True)
rtscap.frame_processer = threading.Thread(target=rtscap.prcoess_frame, daemon=True)
rtscap.frame_sender = threading.Thread(target=rtscap.send_frame, daemon=True)
fps = int(rtscap.get(cv2.CAP_PROP_FPS))
rtscap.width = rtscap.get_even(int(rtscap.get(cv2.CAP_PROP_FRAME_WIDTH) / rtscap._quality))
rtscap.height = rtscap.get_even(int(rtscap.get(cv2.CAP_PROP_FRAME_HEIGHT) / rtscap._quality))
rtscap.command = ['G:\\ZLMediaKit_Release\\ffmpeg.exe',
'-y',
'-f', 'rawvideo',
'-vcodec', 'rawvideo',
'-pix_fmt', 'bgr24',
'-s', "{}x{}".format(rtscap.width, rtscap.height),
'-r', str(fps),
'-i', '-',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'rtsp', # flv rtsp
'-rtsp_transport', 'udp', # 使用TCP推流,linux中一定要有这行
dststream]
# 管道配置
rtscap._reading = True
# 加载算法
rtscap.box_color = (0, 255, 0)
# yolov5
# conf = {
# # "weight_file": "weights/yolov5n_openvino_model/yolov5n.xml",
# "weight_file": "weights/yolov5n_openvino_model/yolov5n.xml",
# "device": "CPU"
# }
# rtscap.detector = OpenVinoYoloV5Detector(IN_conf=conf)
#ssd
conf = {
"model_xml": "./weights/ssdlite_mobilenet_v2/FP16/ssdlite_mobilenet_v2.xml",
"model_bin": "./weights/ssdlite_mobilenet_v2/FP16/ssdlite_mobilenet_v2.bin",
"device": "CPU"
}
rtscap.detector = OpenVinoSSDDetector(IN_conf=conf)
return rtscap
def get_milsecond(self):
t = time.time()
return (int(round(t * 1000)))
def isOK(self):
status = self.isOpened() and self._reading
return status
def recv_frame(self):
while self.isOK():
time.sleep(0.01)
ok, frame = self.read()
if not ok:
break
self._cur_frame = frame
#self.p.stdin.write(frame.tostring())
self._reading = False
def prcoess_frame(self):
while self.isOK():
time.sleep(0.01)
try:
ok, frame = self.read_latest_frame()
if not ok:
continue
# 算法解析
# 跳帧检测
if self.get_milsecond() - self._recvtime > self._interval_check:
starttime = self.get_milsecond()
detect_num, detect_data = self.detector.detect(frame)
if len(detect_data):
for m in detect_data:
classname = m.get('class_name')
score = m.get('score')
location = m.get('location')
box_l, box_t = int(location.get('x1')), int(location.get('y1'))
box_r, box_b = int(location.get('x2')), int(location.get('y2'))
frame = cv2.rectangle(frame, (box_l, box_t), (box_r, box_b), self.box_color, 2)
frame = cv2.putText(frame, classname, (box_l, box_t + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
self._recvtime = self.get_milsecond()
endtime = self.get_milsecond();
print('检测耗时:' + str(endtime - starttime))
self._frame1 = cv2.resize(frame, (self.width, self.height)) # 图像压缩
#self.p.stdin.write(frame1.tostring())
except Exception as e:
ss = str(e)
def send_frame(self):
timeout = 3
self.p = subprocess.Popen(self.command, shell=False, stdin=subprocess.PIPE)
while self.isOK():
time.sleep(0.01)
try:
if self._frame1 is not None:
self.p.stdin.write(self._frame1.tostring())
except Exception as e:
ss = str(e)
def read2(self):
frame = self._cur_frame
self._cur_frame = None
return frame is not None, frame
def start_read(self):
self.frame_receiver.start()
self.frame_processer.start()
self.frame_sender.start()
self.read_latest_frame = self.read2 if self._reading else self.read
def stop_read(self):
self._reading = False
if self.frame_receiver.is_alive():
self.frame_receiver.join()
if self.frame_processer.is_alive():
self.frame_processer.join()
if self.frame_sender.is_alive():
self.frame_sender.join()
if __name__ == '__main__':
url = src = '0'
if src.isdigit():
url = int(src)
rtscap1 = RTSCapture.create(url, "rtsp://127.0.0.1:554/live/test0") # test.mp4 0
rtscap1.start_read()
os.system('pause')



















