目录
四边形:
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)
1万+

被折叠的 条评论
为什么被折叠?



