视频流画线 视频流画多边形

目录

四边形:

视频流画多边形:


四边形:


import cv2
import json
import av

# 全局变量
polygon_points = []      # 四边形点
current_pos = None       # 鼠标当前位置
finished = False         # 是否完成绘制


# ------------------------------------------
# 鼠标绘制四边形回调函数
# ------------------------------------------
def mouse_draw_quad(event, x, y, flags, param):
    global polygon_points, current_pos, finished

    if finished:
        return

    if event == cv2.EVENT_LBUTTONDOWN:
        # 点击添加一个点
        if len(polygon_points) < 4:
            polygon_points.append((x, y))
            print(f"添加点: {polygon_points[-1]}")

        # 4 个点完成 → 自动闭合
        if len(polygon_points) == 4:
            polygon_points.append(polygon_points[0])
            print("✅ 四边形完成:", polygon_points)
            finished = True

    elif event == cv2.EVENT_MOUSEMOVE:
        current_pos = (x, y)


# ------------------------------------------
# 保存四边形到 JSON
# ------------------------------------------
def save_quad_json(points, filename="roi.json"):
    if len(points) < 4:
        print("⚠️ 点不足 4 个,不保存")
        return

    data = {
        "polygon": [{"x": p[0], "y": p[1]} for p in points]
    }

    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

    print("✅ ROI 已保存到:", filename)


# ------------------------------------------
# RTSP 绘制四边形主函数
# ------------------------------------------
def draw_quad_rtsp(rtsp_url, filename="roi.json"):
    global polygon_points, current_pos, finished

    # 打开 RTSP 视频
    container = av.open(rtsp_url, timeout=8)
    stream = next(s for s in container.streams if s.type == 'video')

    window = "Draw Quad ROI"
    cv2.namedWindow(window)
    cv2.setMouseCallback(window, mouse_draw_quad)

    print("🎬 进入四边形绘制模式:")
    print("✅ 左键点击 4 次画四边形")
    print("✅ 第 4 个点自动闭合并保存")
    print("✅ 按 Q 退出")

    for packet in container.demux(stream):
        if finished:
            break

        for frame in packet.decode():
            img = frame.to_ndarray(format='bgr24')
            img = cv2.resize(img, (960, 544))

            # 绘制已有点
            for p in polygon_points:
                cv2.circle(img, p, 4, (0, 255, 0), -1)

            # 绘制线段
            if len(polygon_points) > 1:
                for i in range(len(polygon_points) - 1):
                    cv2.line(img, polygon_points[i], polygon_points[i + 1], (0, 255, 0), 2)

            # 鼠标预览线
            if current_pos and 0 < len(polygon_points) < 4:
                cv2.line(img, polygon_points[-1], current_pos, (0, 255, 255), 1)

            cv2.imshow(window, img)

            if cv2.waitKey(1) == ord("q"):
                finished = True
                break

    cv2.destroyAllWindows()

    # 保存结果
    if len(polygon_points) >= 4:
        save_quad_json(polygon_points, filename)

    return polygon_points


def save_quad_json(points, filename="roi.json"):
    # points 形式为:p1, p2, p3, p4, p1(最后一个是闭合点)
    if len(points) < 4:
        print("⚠️ 点不足 4 个,不保存")
        return

    # ✅ 去掉重复的闭合点
    if len(points) == 5 and points[0] == points[-1]:
        points = points[:-1]  # 去掉最后一个

    data = {
        "polygon": [{"x": p[0], "y": p[1]} for p in points]
    }

    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

    print("✅ ROI 已保存到:", filename)


if __name__ == "__main__":
    rtsp = "rtsp://admin:Zenking306$@192.168.8.240:554/unicast/c5/s0/live"
    points = draw_quad_rtsp(rtsp)

    print("绘制结果:", points)

    save_quad_json(points,filename="roi.json")

视频流画多边形:

import cv2
import json
import av
import time

# -----------------------------
# 全局变量(鼠标交互)
# -----------------------------
polygon_points = []      # 保存多边形顶点
current_pos = None       # 鼠标当前坐标(用于预览)
finished = False         # 是否完成绘制


def mouse_draw_polygon(event, x, y, flags, param):
    global polygon_points, current_pos, finished

    if finished:
        return

    if event == cv2.EVENT_LBUTTONDOWN:
        # 添加一个多边形点
        polygon_points.append((x, y))
        print("添加点:", (x, y))

    elif event == cv2.EVENT_RBUTTONDOWN:
        # 删除最近一个点
        if polygon_points:
            removed = polygon_points.pop()
            print("删除点:", removed)

    elif event == cv2.EVENT_MOUSEMOVE:
        current_pos = (x, y)


def save_polygon_json(points, filename="polygon.json"):
    data = {"polygon": [{"x": p[0], "y": p[1]} for p in points]}
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)
    print("✅ 已保存多边形 ROI 为:", filename)


# ----------------------------------------
# RTSP 视频读取 + 多边形绘制主函数
# ----------------------------------------
def draw_polygon_roi_rtsp(rtsp_url, window_name="RTSP Polygon ROI"):
    global polygon_points, current_pos, finished

    container = av.open(rtsp_url, timeout=10)
    video_stream = next(s for s in container.streams if s.type == 'video')

    cv2.namedWindow(window_name)
    cv2.setMouseCallback(window_name, mouse_draw_polygon)

    print("🎥 开始显示 RTSP 视频,左键添加点,右键删除点,按 Enter 完成多边形。")

    for packet in container.demux(video_stream):
        if finished:
            break

        for frame in packet.decode():
            img = frame.to_ndarray(format='bgr24')
            img = cv2.resize(img, (960, 544))

            # 显示多边形点
            for p in polygon_points:
                cv2.circle(img, p, 4, (0, 255, 0), -1)

            # 展示动态连线
            if len(polygon_points) > 0:
                for i in range(len(polygon_points) - 1):
                    cv2.line(img, polygon_points[i], polygon_points[i+1], (0, 255, 0), 2)

                # 鼠标移动预览
                if current_pos is not None:
                    cv2.line(img, polygon_points[-1], current_pos, (0, 255, 255), 1)

            cv2.imshow(window_name, img)

            key = cv2.waitKey(1)

            if key == 13:  # Enter 键
                if len(polygon_points) >= 3:
                    finished = True
                    print("✅ 绘制完成")
                else:
                    print("⚠️ 至少需要 3 个点")
                break

            elif key == ord('q'):
                print("退出")
                finished = True
                break

    cv2.destroyAllWindows()

    if finished and len(polygon_points) >= 3:
        # 闭合多边形(可选)
        polygon_points.append(polygon_points[0])

        save_polygon_json(polygon_points)
        return polygon_points

    return None
if __name__ == "__main__":
    rtsp = "rtsp://admin:Zenking306$@192.168.8.240:554/unicast/c5/s0/live"
    polygon = draw_polygon_roi_rtsp(rtsp)

    if polygon:
        print("最终多边形 ROI 点:", polygon)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值