文章目录
- import cv2 # 创建VideoCapture对象 # 参数0表示默认摄像头,如果有多个摄像头可以尝试1,2等 cap = cv2.VideoCapture(0) while True: # 读取一帧 ret, frame = cap.read() # 显示帧 cv2.imshow(‘Camera Feed’, frame) # 按’q’键退出 if cv2.waitKey(1) & 0xFF == ord(‘q’): break # 释放资源 cap.release() cv2.destroyAllWindows()
- 关键方法 作用 返回值 VideoCapture() 创建视频捕获对象 视频流对象 cap.read() 读取一帧 (bool, numpy.ndarray) cv2.imshow() 显示图像窗口 无 cv2.waitKey() 等待键盘输入 按键的ASCII码 cap.release() 释放摄像头 无
- import cv2 import time cap = cv2.VideoCapture(0) prev_time = 0 while True: ret, frame = cap.read() # 计算帧率 current_time = time.time() fps = 1 / (current_time – prev_time) prev_time = current_time # 在帧上显示FPS cv2.putText(frame, f”FPS: {int(fps)}”, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow(‘Camera with FPS’, frame) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap.release() cv2.destroyAllWindows()
- import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() # 转换为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 边缘检测 edges = cv2.Canny(gray, 100, 200) # 水平拼接原图和边缘检测结果 combined = cv2.hconcat([frame, cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)]) cv2.imshow(‘Original vs Edges’, combined) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap.release() cv2.destroyAllWindows()
- import cv2 # 打开两个摄像头(根据实际情况调整索引) cap1 = cv2.VideoCapture(0) cap2 = cv2.VideoCapture(1) while True: ret1, frame1 = cap1.read() ret2, frame2 = cap2.read() if not ret1 or not ret2: break # 垂直拼接两个摄像头画面 combined = cv2.vconcat([frame1, frame2]) cv2.imshow(‘Dual Camera’, combined) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap1.release() cap2.release() cv2.destroyAllWindows()
- import cv2 cap = cv2.VideoCapture(0) # 定义视频编解码器并创建VideoWriter对象 fourcc = cv2.VideoWriter_fourcc(*’XVID’) out = cv2.VideoWriter(‘output.avi’, fourcc, 20.0, (640, 480)) 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()
- 检查摄像头索引: # 测试不同索引 for i in range(3): cap = cv2.VideoCapture(i) if cap.isOpened(): print(f”摄像头 {i} 可用”) cap.release() else: print(f”摄像头 {i} 不可用”) 检查权限问题(Linux/Mac): # 确保用户有访问视频设备的权限 ls -l /dev/video* 尝试其他后端: # 使用不同的API后端 cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # Windows DirectShow cap = cv2.VideoCapture(0, cv2.CAP_V4L2) # Linux V4L2
- 1.降低分辨率: cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) 2.使用多线程: from threading import Thread import queue class VideoStream: def __init__(self, src=0): self.stream = cv2.VideoCapture(src) self.q = queue.Queue() self.stopped = False def start(self): Thread(target=self.update, args=()).start() return self def update(self): while True: if self.stopped: return ret, frame = self.stream.read() if not ret: self.stop() return if not self.q.empty(): try: self.q.get_nowait() except queue.Empty: pass self.q.put(frame) def read(self): return self.q.get() def stop(self): self.stopped = True self.stream.release()
- import cv2 import numpy as np cap = cv2.VideoCapture(0) _, first_frame = cap.read() first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY) first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0) while True: _, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (21, 21), 0) # 计算当前帧与第一帧的差异 frame_diff = cv2.absdiff(first_gray, gray) _, threshold = cv2.threshold(frame_diff, 25, 255, cv2.THRESH_BINARY) # 更新背景帧 first_gray = gray cv2.imshow(“Motion Detection”, threshold) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap.release() cv2.destroyAllWindows()
- import cv2 # 加载预训练的人脸检测模型 face_cascade = cv2.CascadeClassifier( cv2.data.haarcascades + ‘haarcascade_frontalface_default.xml’) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 检测人脸 faces = face_cascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30) ) # 绘制人脸矩形框 for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) cv2.imshow(‘Face Detection’, frame) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap.release() cv2.destroyAllWindows()
- 仅在需要时处理: process_frame = False while True: ret, frame = cap.read() if process_frame: # 耗时的图像处理 processed = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) processed = cv2.Canny(processed, 100, 200) cv2.imshow(‘Processed’, processed) cv2.imshow(‘Original’, frame) key = cv2.waitKey(1) if key == ord(‘q’): break elif key == ord(‘p’): process_frame = not process_frame 调整图像质量: # 设置JPEG压缩质量(仅影响保存的图像) encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 70] _, buffer = cv2.imencode(‘.jpg’, frame, encode_param)
- # 检查可用的硬件加速后端 print(“可用后端:”, cv2.videoio_registry.getBackendName()) # 尝试使用不同的硬件加速API cap = cv2.VideoCapture(0, cv2.CAP_MSMF) # Windows Media Foundation cap = cv2.VideoCapture(0, cv2.CAP_GSTREAMER) # GStreamer cap = cv2.VideoCapture(0, cv2.CAP_FFMPEG) # FFMPEG
目录
- 一、环境准备与基础配置
- 1.1 安装OpenCV库
- 1.2 验证安装
- 二、基础视频捕获实现
- 2.1 最简单的摄像头捕获
- 2.2 代码解析
- 三、视频流增强处理
- 3.1 添加实时帧率显示
- 3.2 实时图像处理示例
- 四、高级功能实现
- 4.1 多摄像头同步捕获
- 4.2 视频录制功能
- 五、常见问题解决方案
- 5.1 摄像头无法打开的排查
- 5.2 提高视频捕获性能
- 六、应用案例扩展
- 6.1 运动检测实现
- 6.2 人脸检测示例
- 七、性能优化技巧
- 7.1 减少图像处理开销
- 7.2 使用硬件加速
- 八、完整项目示例
# 使用pip安装OpenCV
pip install opencv-python
# 如果需要完整版(包含contrib模块)
pip install opencv-contrib-python
import cv2
# 打印OpenCV版本
print(cv2.__version__)
# 检查摄像头是否可用(返回可用摄像头数量)
print("可用摄像头数量:", cv2.cv2.getNumberOfCameras())
import cv2
# 创建VideoCapture对象
# 参数0表示默认摄像头,如果有多个摄像头可以尝试1,2等
cap = cv2.VideoCapture(0)
while True:
# 读取一帧
ret, frame = cap.read()
# 显示帧
cv2.imshow('Camera Feed', frame)
# 按'q'键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
| 关键方法 | 作用 | 返回值 |
|---|---|---|
| VideoCapture() | 创建视频捕获对象 | 视频流对象 |
| cap.read() | 读取一帧 | (bool, numpy.ndarray) |
| cv2.imshow() | 显示图像窗口 | 无 |
| cv2.waitKey() | 等待键盘输入 | 按键的ASCII码 |
| cap.release() | 释放摄像头 | 无 |
import cv2
import time
cap = cv2.VideoCapture(0)
prev_time = 0
while True:
ret, frame = cap.read()
# 计算帧率
current_time = time.time()
fps = 1 / (current_time - prev_time)
prev_time = current_time
# 在帧上显示FPS
cv2.putText(frame, f"FPS: {int(fps)}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow('Camera with FPS', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
# 转换为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 边缘检测
edges = cv2.Canny(gray, 100, 200)
# 水平拼接原图和边缘检测结果
combined = cv2.hconcat([frame, cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)])
cv2.imshow('Original vs Edges', combined)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
# 打开两个摄像头(根据实际情况调整索引)
cap1 = cv2.VideoCapture(0)
cap2 = cv2.VideoCapture(1)
while True:
ret1, frame1 = cap1.read()
ret2, frame2 = cap2.read()
if not ret1 or not ret2:
break
# 垂直拼接两个摄像头画面
combined = cv2.vconcat([frame1, frame2])
cv2.imshow('Dual Camera', combined)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap1.release()
cap2.release()
cv2.destroyAllWindows()
import cv2
cap = cv2.VideoCapture(0)
# 定义视频编解码器并创建VideoWriter对象
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
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()
检查摄像头索引:
# 测试不同索引
for i in range(3):
cap = cv2.VideoCapture(i)
if cap.isOpened():
print(f"摄像头 {i} 可用")
cap.release()
else:
print(f"摄像头 {i} 不可用")
检查权限问题(Linux/Mac):
# 确保用户有访问视频设备的权限 ls -l /dev/video*
尝试其他后端:
# 使用不同的API后端 cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # Windows DirectShow cap = cv2.VideoCapture(0, cv2.CAP_V4L2) # Linux V4L2
1.降低分辨率:
cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
2.使用多线程:
from threading import Thread
import queue
class VideoStream:
def __init__(self, src=0):
self.stream = cv2.VideoCapture(src)
self.q = queue.Queue()
self.stopped = False
def start(self):
Thread(target=self.update, args=()).start()
return self
def update(self):
while True:
if self.stopped:
return
ret, frame = self.stream.read()
if not ret:
self.stop()
return
if not self.q.empty():
try:
self.q.get_nowait()
except queue.Empty:
pass
self.q.put(frame)
def read(self):
return self.q.get()
def stop(self):
self.stopped = True
self.stream.release()
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
_, first_frame = cap.read()
first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0)
while True:
_, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
# 计算当前帧与第一帧的差异
frame_diff = cv2.absdiff(first_gray, gray)
_, threshold = cv2.threshold(frame_diff, 25, 255, cv2.THRESH_BINARY)
# 更新背景帧
first_gray = gray
cv2.imshow("Motion Detection", threshold)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
# 绘制人脸矩形框
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('Face Detection', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
仅在需要时处理:
process_frame = False
while True:
ret, frame = cap.read()
if process_frame:
# 耗时的图像处理
processed = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
processed = cv2.Canny(processed, 100, 200)
cv2.imshow('Processed', processed)
cv2.imshow('Original', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('p'):
process_frame = not process_frame
调整图像质量:
# 设置JPEG压缩质量(仅影响保存的图像)
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 70]
_, buffer = cv2.imencode('.jpg', frame, encode_param)
# 检查可用的硬件加速后端
print("可用后端:", cv2.videoio_registry.getBackendName())
# 尝试使用不同的硬件加速API
cap = cv2.VideoCapture(0, cv2.CAP_MSMF) # Windows Media Foundation
cap = cv2.VideoCapture(0, cv2.CAP_GSTREAMER) # GStreamer
cap = cv2.VideoCapture(0, cv2.CAP_FFMPEG) # FFMPEG
带GUI控制的摄像头应用
import cv2
import numpy as np
def nothing(x):
pass
# 创建控制窗口
cv2.namedWindow('Controls')
cv2.createTrackbar('Brightness', 'Controls', 50, 100, nothing)
cv2.createTrackbar('Contrast', 'Controls', 50, 100, nothing)
cv2.createTrackbar('Flip', 'Controls', 0, 1, nothing)
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# 获取控制参数
brightness = cv2.getTrackbarPos('Brightness', 'Controls') - 50
contrast = cv2.getTrackbarPos('Contrast', 'Controls') / 50
flip = cv2.getTrackbarPos('Flip', 'Controls')
# 应用调整
frame = cv2.convertScaleAbs(frame, alpha=contrast, beta=brightness)
if flip:
frame = cv2.flip(frame, 1)
# 显示处理后的帧
cv2.imshow('Camera', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
本教程涵盖了从基础到高级的OpenCV视频捕获技术,包括:
- 基础摄像头捕获与显示
- 实时视频处理与增强
- 多摄像头与视频录制
- 常见问题解决方案
- 实际应用案例
- 性能优化技巧
建议读者根据实际需求选择合适的实现方式,并注意资源释放以避免内存泄漏。对于更复杂的应用,可以考虑结合深度学习模型进行高级计算机视觉任务。
到此这篇关于Python使用OpenCV捕获摄像头视频流的完整教程的文章就介绍到这了,更多相关Python OpenCV获取摄像头视频流内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Python使用OpenCV捕获摄像头视频流并在窗口中显示
- Python如何将OpenCV摄像头视频流通过浏览器播放
- Python开发中OpenCV视频流的多线程处理方式详解
- OpenCV视频流Python多线程处理方法详细分析
- python基于OpenCV模块实现视频流数据切割为图像帧数据(流程分析)
- python环境下OPenCV处理视频流局部区域像素值