【OpenCV 入门到精通 04】视频入门与绘图交互:从摄像头到鼠标画笔
标签 :OpenCV VideoCapture 绘图 鼠标事件 轨迹栏
难度 :⭐ 入门 | 阅读时长 :约 55 分钟 | 系列 :第 04/12 集
前置 :03 图像入门 | 下一集 :05 核心操作
写在前面
图像处理不止静态照片------监控、直播、自动驾驶都涉及 视频流 。本集覆盖视频读写、基本绘图、鼠标交互和轨迹栏,对应官方 2_2 视频入门 和 2_3~2_5 GUI 特性。
本集学习目标
文章目录
- [【OpenCV 入门到精通 04】视频入门与绘图交互:从摄像头到鼠标画笔](#【OpenCV 入门到精通 04】视频入门与绘图交互:从摄像头到鼠标画笔)
-
- 写在前面
- 本集学习目标
- [4.1 视频读取 VideoCapture](#4.1 视频读取 VideoCapture)
-
- [4.2 视频保存 VideoWriter](#4.2 视频保存 VideoWriter)
- [4.3 绘图函数](#4.3 绘图函数)
-
- [4.4 鼠标作为画笔](#4.4 鼠标作为画笔)
-
- [4.5 轨迹栏调色板](#4.5 轨迹栏调色板)
- [4.6 踩坑指南](#4.6 踩坑指南)
- [4.7 本集小结](#4.7 本集小结)
4.1 视频读取 VideoCapture
读取视频文件
import cv2
cap = cv2.VideoCapture("video.mp4")
while cap.isOpened():
ret, frame = cap.read() # ret=是否成功, frame=当前帧
if not ret:
break
cv2.imshow("Video", frame)
if cv2.waitKey(25) & 0xFF == ord('q'): # 约40fps
break
cap.release()
cv2.destroyAllWindows()
读取摄像头
cap = cv2.VideoCapture(0) # 0=默认摄像头,1=外接
# 获取属性
fps = cap.get(cv2.CAP_PROP_FPS)
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"分辨率: {w}x{h}, FPS: {fps}")
| 属性常量 |
含义 |
CAP_PROP_FRAME_WIDTH |
帧宽度 |
CAP_PROP_FRAME_HEIGHT |
帧高度 |
CAP_PROP_FPS |
帧率 |
CAP_PROP_FRAME_COUNT |
总帧数 |
4.2 视频保存 VideoWriter
cap = cv2.VideoCapture(0)
w = int(cap.get(3))
h = int(cap.get(4))
fps = 20.0
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (w, h))
while cap.isOpened():
ret, frame = cap.read()
if not ret: break
out.write(frame)
cv2.imshow("Recording", frame)
if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release()
out.release()
cv2.destroyAllWindows()
| fourcc |
格式 |
'mp4v' |
MP4 |
'XVID' |
AVI |
'MJPG' |
Motion JPEG |
4.3 绘图函数
import cv2
import numpy as np
img = np.zeros((400, 600, 3), dtype=np.uint8)
# 直线
cv2.line(img, (50,50), (200,200), (0,255,0), 2)
# 矩形
cv2.rectangle(img, (250,50), (400,150), (255,0,0), 2)
cv2.rectangle(img, (250,200), (400,300), (0,0,255), -1) # -1=填充
# 圆
cv2.circle(img, (500,100), 50, (0,255,255), -1)
# 椭圆
cv2.ellipse(img, (500,250), (80,40), 0, 0, 360, (255,255,0), 2)
# 多边形
pts = np.array([[100,300],[200,250],[300,300],[200,350]], np.int32)
cv2.polylines(img, [pts], True, (255,0,255), 2)
# 文字
cv2.putText(img, "OpenCV", (100,380), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)
cv2.imshow("Drawing", img)
cv2.waitKey(0)
绘图函数速查
| 函数 |
作用 |
关键参数 |
line |
直线 |
起点、终点、颜色、粗细 |
rectangle |
矩形 |
左上、右下、颜色、粗细(-1填充) |
circle |
圆 |
圆心、半径、颜色 |
ellipse |
椭圆 |
中心、轴长、角度 |
polylines |
多边形 |
顶点数组、是否闭合 |
putText |
文字 |
内容、位置、字体、大小 |
4.4 鼠标作为画笔
import cv2
import numpy as np
drawing = False
color = (0, 0, 255)
def mouse_callback(event, x, y, flags, param):
global drawing, color
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
elif event == cv2.EVENT_MOUSEMOVE and drawing:
cv2.circle(img, (x, y), 5, color, -1)
elif event == cv2.EVENT_RBUTTONDOWN:
color = (np.random.randint(0,255), np.random.randint(0,255), np.random.randint(0,255))
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
img = np.zeros((400, 600, 3), dtype=np.uint8)
cv2.namedWindow("Paint")
cv2.setMouseCallback("Paint", mouse_callback)
while True:
cv2.imshow("Paint", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
鼠标事件
| 事件 |
触发 |
EVENT_LBUTTONDOWN |
左键按下 |
EVENT_LBUTTONUP |
左键释放 |
EVENT_MOUSEMOVE |
鼠标移动 |
EVENT_RBUTTONDOWN |
右键按下 |
4.5 轨迹栏调色板
import cv2
import numpy as np
def nothing(x):
pass
img = np.zeros((300, 512, 3), np.uint8)
cv2.namedWindow("Palette")
cv2.createTrackbar("R", "Palette", 0, 255, nothing)
cv2.createTrackbar("G", "Palette", 0, 255, nothing)
cv2.createTrackbar("B", "Palette", 0, 255, nothing)
while True:
r = cv2.getTrackbarPos("R", "Palette")
g = cv2.getTrackbarPos("G", "Palette")
b = cv2.getTrackbarPos("B", "Palette")
img[:] = (b, g, r) # BGR
cv2.imshow("Palette", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
4.6 踩坑指南
| 坑 |
解决 |
| 摄像头打不开 |
试 0/1/2;检查权限 |
| 视频保存无法播放 |
换 fourcc;确认 release() |
| 绘图颜色不对 |
用 BGR 不是 RGB |
| waitKey(0) 在视频中卡死 |
视频用 waitKey(1) 或 waitKey(25) |
4.7 本集小结
| 功能 |
核心 API |
| 读视频/摄像头 |
VideoCapture + read() |
| 写视频 |
VideoWriter + write() |
| 绘图 |
line/rectangle/circle/putText |
| 鼠标 |
setMouseCallback |
| 滑块 |
createTrackbar |
参考:2_2 视频入门 | 2_3 绘图功能