OpenCV不仅提供了丰富的图像处理功能,还能够帮助我们轻松实现视频的加载、播放以及各种控制。
通常,我们必须用摄像头捕捉实时流。OpenCV提供了一个非常简单的接口。让我们从摄像头中捕捉视频(我正在使用笔记本电脑的内置摄像头),将其转换为灰度视频并显示。只是一个简单的任务开始。
要捕捉视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像头的号码。通常一个相机将被连接(就像我的情况)。所以我只是通过0(或-1)。您可以通过传递1等来选择第二台相机。之后,您可以逐帧捕捉。但最后,不要忘记释放捕获。
import cv2
import tkinter as tk
from functools import partial
def capture_video():
# 打开默认摄像头(索引0)
cap = cv2.VideoCapture(0)
# 检查摄像头是否成功打开
if not cap.isOpened():
print("无法打开摄像头")
return
# 创建一个窗口
cv2.namedWindow("mycamera", cv2.WINDOW_NORMAL)
# 获取屏幕分辨率
root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
root.destroy()
# 获取视频窗口的大小
ret, frame = cap.read()
if ret:
frame_height, frame_width = frame.shape[:2]
else:
frame_width, frame_height = 640, 480 # 默认值
# 计算窗口位置,使其居中
window_x = (screen_width - frame_width) // 2
window_y = (screen_height - frame_height) // 2
# 设置窗口位置
cv2.moveWindow("mycamera", window_x, window_y)
while True:
# 从摄像头读取帧
ret, frame = cap.read()
# 如果读取帧失败,退出循环
if not ret:
break
# 显示彩色帧
cv2.imshow("mycamera", frame)
# 检测是否按下了关闭窗口的按键(例如,点击窗口的关闭按钮)
if cv2.waitKey(1) & 0xFF == 27: # 按下ESC键也可以退出
break
# 检查是否关闭了窗口
if cv2.getWindowProperty("mycamera", cv2.WND_PROP_VISIBLE) < 1:
break
# 释放摄像头资源并关闭所有OpenCV窗口
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
capture_video()
把设备索引号改成文件名即可。在播放每一帧时,使用cv2.waitKey()适当持续时间,如果它太少,视频会非常快,如果它太高,视频会很慢(那么,这是如何以慢动作显示视频)。正常情况下,25-28ms即可。
以下是OpenCV播放视频的函数封装。该函数提供了两个参数:第一参数是播放视频的路径,第二个参数是播放视频的缩放比率。
import cv2
def play_video(video_path, scale_factor):
"""
使用 OpenCV 播放视频文件,并支持缩放功能。
参数:
video_path (str): 视频文件的路径。
scale_factor (float): 视频帧的缩放比例,大于0的浮点数。
"""
# 检查缩放比例是否有效
if scale_factor <= 0:
raise ValueError("缩放比例必须大于0")
# 打开视频文件
cap = cv2.VideoCapture(video_path)
# 检查视频是否成功打开
if not cap.isOpened():
print(f"无法打开视频文件: {video_path}")
return
try:
while True:
# 读取视频帧
ret, frame = cap.read()
# 如果读取帧失败,退出循环
if not ret:
break
# 对帧进行缩放
resized_frame = cv2.resize(frame, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
# 显示缩放后的帧
cv2.imshow('Video Player', resized_frame)
"""
# 按下 'q' 键退出播放
if cv2.waitKey(25) & 0xFF == ord('q'):
break
"""
# 检测是否按下了关闭窗口的按键(例如,点击窗口的关闭按钮)
if cv2.waitKey(28) & 0xFF == 27: # 按下ESC键也可以退出
break
# 检查是否关闭了窗口
if cv2.getWindowProperty("Video Player", cv2.WND_PROP_VISIBLE) < 1:
break
finally:
# 释放视频对象和窗口
cap.release()
cv2.destroyAllWindows()
# 使用示例
# play_video('your_video.mp4', 0.5) # 将视频缩小为原来的一半
if __name__ == '__main__':
video_path = './video/nvidia01.mp4'
scale_factor = 0.5
play_video(video_path, scale_factor)

OpenCV本身并不支持音频播放功能,它主要用于处理视频帧和图像。要实现带有声音的视频播放,你需要使用其他库来处理音频部分,例如 pygame 或 sounddevice 等。
首先安装pygame库。
pip install pygame
以下是一个结合 OpenCV 和 pygame的示例代码,用于播放视频并同时播放音频。
import cv2
import pygame
import threading
def play_audio(audio_path):
"""
播放音频文件
"""
pygame.init()
# 加载 MP3 文件
pygame.mixer.music.load(audio_path)
# 播放音频
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
pygame.quit()
def play_video_with_audio(video_path, scale_factor, audio_path=None):
"""
使用 OpenCV 播放视频文件,并支持缩放功能,同时播放音频。
参数:
video_path (str): 视频文件的路径。
scale_factor (float): 视频帧的缩放比例,大于0的浮点数。
audio_path (str, optional): 音频文件的路径。如果为None,则不播放音频。
"""
# 检查缩放比例是否有效
if scale_factor <= 0:
raise ValueError("缩放比例必须大于0")
# 打开视频文件
cap = cv2.VideoCapture(video_path)
# 检查视频是否成功打开
if not cap.isOpened():
print(f"无法打开视频文件: {video_path}")
return
# 如果提供了音频路径,则启动音频播放线程
if audio_path:
audio_thread = threading.Thread(target=play_audio, args=(audio_path,))
audio_thread.daemon = True
audio_thread.start()
try:
while True:
# 读取视频帧
ret, frame = cap.read()
# 如果读取帧失败,退出循环
if not ret:
break
# 对帧进行缩放
resized_frame = cv2.resize(frame, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
# 显示缩放后的帧
cv2.imshow('Video Player', resized_frame)
"""
# 按下 'q' 键退出播放
if cv2.waitKey(25) & 0xFF == ord('q'):
break
"""
if cv2.waitKey(28) & 0xFF == 27: # 按下ESC键也可以退出
break
# 检查是否关闭了窗口
if cv2.getWindowProperty("Video Player", cv2.WND_PROP_VISIBLE) < 1:
break
finally:
# 释放视频对象和窗口
cap.release()
cv2.destroyAllWindows()
# 使用示例
if __name__ == '__main__':
play_video_with_audio('./video/nvidia01.mp4', 0.5, './video/nvidia01.MP3')
注意事项: - pygame 需要 ffmpeg 来处理音频文件。如果你的系统中没有安装 ffmpeg,可能需要单独安装它。 - 音频和视频的同步可能会有问题,尤其是在不同硬件和操作系统上。如果需要更精确的同步,可能需要更复杂的处理逻辑。 - 如果视频不包含音轨,你需要用专业的视频处理工具,把音轨部分分离出来,单独保存为MP3文件。 - 如果视频文件本身包含音频轨道,你可以直接提取音频部分进行播放,而无需单独提供音频文件。
所以我们拍摄一个视频,逐帧处理,我们要保存视频。对于图像来说,这非常简单,只是使用cv2.imwrite()。 但是视频需要更多的工作。
创建一个VideoWrite的对象,确定输出文件名,指定FourCC编码,播放频率和帧的大小,最后是isColor标签True为彩色。 FourCC是一个4字节码,用来确定视频的编码格式。
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('./output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
#摄像头垂直翻转
#frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()