YOLOv8 实时检测视频并将结果处理为 httpflv
1364人浏览 / 0人评论
参考
yolov8-opencv-ffmpeg-mediamtx实现视频中实时检测安全帽_yolov8头盔-CSDN博客
yolo_test.py
from ultralytics import YOLO
import cv2
import subprocess
import matplotlib
matplotlib.rc("font", family='Microsoft YaHei')
class StreamPusher:
def __init__(self, rtmp_url, width, height): # 接受一个参数rtmq_url 该参数受用于指定rtmq服务器地址的字符串
# 创建FFmpeg命令行参数
ffmpeg_cmd = ['ffmpeg',
'-y', # 覆盖已存在的文件
'-f', 'rawvideo', # 指定输入格式为原始视频帧数据
'-pixel_format', 'bgr24', # 指定输入数据的像素格式为BGR24(一种图像颜色编码格式)
'-video_size', '{}x{}'.format(width, height), # 指定输入视频的尺寸
'-i', '-', # 从标准输入读取数据
'-c:v', 'libx264', # 指定视频编码器为libx264(H.264编码器)
'-preset', 'ultrafast', # 使用ultrafast预设,以获得更快的编码速度
'-tune', 'zerolatency', # 使用zerolatency调整 以降低延迟
'-pix_fmt', 'yuv420p', # 指定输出视频像素格式为yuv420p
'-f', 'flv', # 指定输出格式为FLV
rtmp_url] # 指定输出目标为‘rtmp_url' 即RTMP服务器地址
print('ffmpeg_cmd:', ffmpeg_cmd)
# 启动 ffmpeg
self.ffmepg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)
def streamPush(self, frame): # 用于推送视频帧数据到FFmpeg进程
self.ffmepg_process.stdin.write(frame)
self.ffmepg_process.stdin.flush()
def main():
model = YOLO('D:/Projects/python/ultralytics/runs/detect/train5/weights/best.pt')
def predict(frame):
results = model.predict(frame)
# 解析结果:[左上横坐标,左上竖坐标,右下横坐标,右下竖坐标,标签名称,匹配度]
result = results[0]
output = []
for box in result.boxes:
x1, y1, x2, y2 = [
round(x) for x in box.xyxy[0].tolist()
]
class_id = box.cls[0].item()
prob = round(box.conf[0].item(), 2)
output.append([
x1, y1, x2, y2, result.names[class_id], prob
])
return output
cap = cv2.VideoCapture('D:/Downloads/Edge/AI/road signs3.mp4')
# cap = cv2.VideoCapture('rtsp://localhost:8554/test')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
rtmp_server = "rtmp://192.168.1.63:1935/liveapp/test"
pusher = StreamPusher(rtmp_server, width, height)
font = cv2.FONT_HERSHEY_DUPLEX
font_thickness = 3
font_color = (0, 0, 255)
box_color = (0, 255, 0)
while cap.isOpened():
ret, frame = cap.read()
if frame is None:
break
results = predict(frame)
for box in results:
cv2.rectangle(frame, (box[0], box[1]), (box[2], box[3]), color=box_color, thickness=2)
font_scale = min(box[2] - box[0], box[3] - box[1]) / 100
if font_scale < 1:
font_scale = 1
font_text = box[4] + ": " + str(box[5])
size = cv2.getTextSize(font_text, font, font_scale, font_thickness)
cv2.rectangle(frame, (box[0], box[1] - size[0][1] - 4), (box[0] + size[0][0] - 4, box[1]), color=box_color,
thickness=-1)
cv2.putText(frame, font_text, (box[0], box[1] - 4), font, font_scale, font_color, thickness=font_thickness)
pusher.streamPush(frame)
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
带 nginx-flv-module 的 nginx
下载:https://gitee.com/isyuesen/nginx-flv-file
或者:https://pan.jbritian.com/share/764e22d2fa2e4f6c95ae2be571f42b97
注释掉 nginx.conf 文件中如下两行:
on_publish http://localhost:8888/rstp/auth;
on_publish_done http://localhost:8888/rstp/auth;
启动:
start /b nginx.exe -c conf\nginx.conf
停止:
nginx.exe -s stop
使用 flvjs.js 播放
flv_play.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>播放http-flv</title>
</head>
<body>
<video id="videoElement" muted="muted"></video>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
<script>
if (flvjs.isSupported()) {
const videoElement = document.getElementById('videoElement');
const flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://127.0.0.1:18080/live?port=1935&app=liveapp&stream=test'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html>
全部评论