YOLOv8 实时检测视频并将结果处理为 httpflv

772人浏览 / 0人评论

参考

yolov8-opencv-ffmpeg-mediamtx实现视频中实时检测安全帽_yolov8头盔-CSDN博客

rtsp 转 httpflv (jbritian.com)

YOLOv8_ByteTrack车辆计数 - 知乎 (zhihu.com)

使用OpenCV和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>

相关文章

全部评论