Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 视频图像处理基础操作 之 视频捕获/存储/提取/合成/合并
目录
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 视频图像处理基础操作 之 视频捕获/存储/提取/合成/合并
一、简单介绍
二、视频处理流程和原理
三、视频的捕获和存储
四、提取视频中的某些帧
五、将图片合成为视频
六、多个视频合并
一、简单介绍
Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。
这里使用 Python 基于 OpenCV 进行视觉图像处理,......
二、视频处理流程和原理
视频处理的基本原理涉及到图像处理和计算机视觉领域的很多概念和算法。在处理视频时,常见的算法包括帧间差分、光流法、背景建模、物体检测和跟踪等。这些算法的原理涉及到像素级别的操作、特征提取、模型训练等。
视频有各种格式,比如AVI和MP4等,在播放视频时需要编解码,不同的播放器都有自己的编解码器。OpenCV目前对于AVI和MP4读取正常,但是有大小限制,不能超过2GB。OpenCV集成了视频处理的各种函数,处理视频的流程就是读取完一段视频后将视频切分成一张张图片,对视频处理基本上是对图像本身处理的一个遍历。另外,基于视频流可以做出各种效果,比如视频追踪、计算视频帧间处理的效果等,主要应用于图像目标检测领域。
通过对比相邻帧间的图像差异,可以计算出图像中的运动目标。
- 物体检测:首先使用目标检测算法(如Haar级联检测器、YOLO、Faster R-CNN等)在每一帧中检测出感兴趣的目标物体,这些算法通常会使用预训练好的模型来识别目标。
- 物体跟踪:一旦检测到目标,跟踪算法会跟踪目标物体在连续帧中的位置,常见的跟踪算法包括基于卡尔曼滤波、均值漂移、核相关滤波等。
OpenCV 提供了一些基本的流程,下面是一个简要的概述:
视频捕获(Video Capture):
- 首先,需要使用 OpenCV 的
cv2.VideoCapture()
函数打开视频文件或者连接到摄像头。- 这个函数返回一个
VideoCapture
对象,你可以使用它来逐帧读取视频。逐帧处理(Frame Processing):
- 使用
VideoCapture
对象的read()
方法逐帧读取视频。- 对于每一帧,你可以应用图像处理或计算机视觉算法。
图像处理和计算机视觉算法:
- OpenCV 提供了丰富的图像处理和计算机视觉函数,比如图像滤波、边缘检测、目标检测、跟踪等。
- 你可以根据你的需求选择合适的函数来处理每一帧,例如使用
cv2.cvtColor()
进行颜色空间转换、cv2.Canny()
进行边缘检测、cv2.findContours()
进行轮廓检测等。显示处理后的帧(Display Processed Frames):
- 处理后的帧可以通过
cv2.imshow()
显示出来,也可以保存为视频文件。- 如果你在处理视频时想要实时显示处理后的帧,可以使用
cv2.imshow()
和cv2.waitKey()
结合起来。释放资源(Release Resources):
- 在处理完所有帧后,记得释放资源,关闭视频文件或释放摄像头。
三、视频的捕获和存储
视频的读取可以通过读取已经存储好的视频。可以通过打开Camera摄像头读取视频图像。OpenCV中获取摄像头视频使用VideoCapture类,其构造参数为摄像头的Index,一般的笔记本计算机只有一个摄像头,因此其Index一般为0。获取视频属性(码率\尺寸)使用VideoCapture的get()方法。
将视频帧写入文件使用VideoWriter类,其构造参数分别为写入的文件路径名、编码格式、帧率及视频尺寸,可以通过VideoCapture获取。
当使用 OpenCV 处理视频时,有几个关键函数在代码中被频繁使用。下面是其中一些函数的简要说明:
cv2.VideoCapture():
- 这个函数用于从视频文件或者摄像头中读取视频流。
- 参数可以是视频文件的路径,也可以是摄像头的索引(通常为 0 表示默认摄像头)。
- 返回一个 VideoCapture 对象,可以用来逐帧读取视频。
cv2.VideoWriter():
- 这个函数用于创建一个用于保存视频的 VideoWriter 对象。
- 参数包括输出视频文件的名称、视频编码器的四字符编码(fourcc)、帧率(fps)、视频帧大小等。
- 返回一个 VideoWriter 对象,可以用来逐帧写入视频。
cv2.putText():
- 这个函数用于在图像上绘制文本。
- 参数包括输入图像、要绘制的文本、文本位置、字体、字体大小、颜色、线条粗细等。
import cv2
def vedioCaptureWrite(saveName):
"""
视频捕捉与保存
:param saveName: 类似 output.avi
:return:
"""
# 打开摄像头
cap = cv2.VideoCapture(0)
# 定义视频编码器
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# 创建 VideoWriter 对象,用于保存视频
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
# 循环读取摄像头帧
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 在视频上绘制一个简单的示例文本
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, 'Recording...', (10, 50), font, 1, (0, 255, 255), 2, cv2.LINE_AA)
# 写入帧到输出视频
out.write(frame)
# 显示帧
cv2.imshow('frame', frame)
# 按 'q' 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()
四、提取视频中的某些帧
视频可以视为连续帧图像的集合,可以对图像的帧进行计数,也可以通过视频的时间来提取视频中的某些帧。
当从视频中提取特定帧时,有几个关键函数在代码中被频繁使用。下面是其中一些函数的简要说明:
cv2.VideoCapture():
- 这个函数用于从视频文件中读取视频流。
- 参数可以是视频文件的路径,也可以是摄像头的索引(通常为 0 表示默认摄像头)。
- 返回一个 VideoCapture 对象,可以用来逐帧读取视频。
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_index):
- 这个方法用于设置视频帧的位置。
- 第一个参数是帧的索引位置,第二个参数是要设置的帧索引。
- 这个方法可以让你定位到视频的特定帧,以便读取或处理。
cv2.imwrite():
- 这个函数用于将图像保存为文件。
- 第一个参数是输出文件的路径,第二个参数是要保存的图像数组。
- 支持的图像格式包括 JPEG、PNG、BMP 等。
cap.read():
- 这个方法用于逐帧读取视频。
- 返回一个布尔值和帧。布尔值表示帧是否成功读取,帧是一个 NumPy 数组,包含当前读取的帧图像的像素值。
import cv2
def videoExtraction(videoName):
"""
提取视频中的某一帧保存为图片
:param videoName: 类似 TwoPeopleRunning.mp4
:return:
"""
# 打开视频文件
cap = cv2.VideoCapture(videoName)
# 检查视频是否成功打开
if not cap.isOpened():
print("Error: Unable to open video.")
exit()
# 选择要提取的帧索引
frame_index = 100 # 例如,提取第 100 帧
# 设置视频帧索引
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
# 读取帧
ret, frame = cap.read()
# 检查帧是否成功读取
if not ret:
print("Error: Unable to read frame.")
exit()
# 保存帧为图像文件
cv2.imwrite('Images/videoExtraction.jpg', frame)
# 关闭视频文件
cap.release()
print(f"Frame {frame_index} extracted and saved as output_frame.jpg")
五、将图片合成为视频
将图片合成为视频意味着将一系列图片按照一定的顺序和帧率组合成视频文件。
当将图片合成为视频时,有几个关键函数在代码中被频繁使用。下面是其中一些函数的简要说明:
cv2.VideoWriter():
- 这个函数用于创建一个用于保存视频的 VideoWriter 对象。
- 参数包括输出视频文件的名称、视频编码器的四字符编码(fourcc)、帧率(fps)、视频帧大小等。
- 返回一个 VideoWriter 对象,可以用来逐帧写入视频。
cv2.imread():
- 这个函数用于从图像文件中读取图像。
- 参数是图像文件的路径。
- 返回一个 NumPy 数组,包含图像的像素值。
cv2.imwrite():
- 这个函数用于将图像保存为文件。
- 第一个参数是输出文件的路径,第二个参数是要保存的图像数组。
- 支持的图像格式包括 JPEG、PNG、BMP 等。
os.listdir():
- 这个函数用于获取指定路径下的所有文件和文件夹的名称。
- 参数是要列出的目录的路径。
- 返回一个包含目录中所有条目的列表。
os.path.join():
- 这个函数用于将多个路径组合成一个路径。
- 参数是要组合的路径元素。
- 返回组合后的路径字符串。
os.path.isfile():
- 这个函数用于检查路径是否是一个文件。
- 参数是要检查的路径。
- 如果路径指向文件,则返回 True,否则返回 False。
import cv2
import os
def imagesCompositingVideo(imageFolder, frame):
"""
图片合成图片
:param imageFolder: 图片文件夹,例如 'Images'
:param frame: 每秒多少帧,例如 30帧每秒,1帧每秒
:return:
"""
# 图片所在文件夹
images_folder = imageFolder
# 读取文件夹中的所有图片文件名
image_files = [f for f in os.listdir(images_folder) if os.path.isfile(os.path.join(images_folder, f))]
# 指定输出视频文件名
output_video = 'Videos/imagesCompositingVideo.mp4'
# 定义视频编码器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 获取第一张图片的尺寸
first_image = cv2.imread(os.path.join(images_folder, image_files[0]))
height, width, _ = first_image.shape
# 创建 VideoWriter 对象
out = cv2.VideoWriter(output_video, fourcc, frame, (width, height))
# 逐张读取图片并写入视频
for image_file in image_files:
image_path = os.path.join(images_folder, image_file)
img = cv2.imread(image_path)
out.write(img)
# 释放资源
out.release()
imagesCompositingVideo()
六、多个视频合并
多个视频合并是指将多个视频文件合并成一个视频文件的过程。在这个过程中,多个视频文件的内容会按照一定的顺序连接起来,形成一个新的视频文件。合并多个视频可以用于将不同的视频片段拼接成一个完整的视频,或者将多个视频源合并为一个视频文件。
通常,多个视频合并可以分为两种情况:
-
简单拼接:将多个视频按照顺序连接在一起,形成一个长视频。这种合并方式不对视频进行任何处理,只是将它们连接起来。
-
混流合并:将多个视频文件进行混流,即将它们的视频流和音频流合并到一个视频文件中。这种合并方式通常需要对视频进行解码、编辑和编码等操作。
在实现多个视频合并时,可以使用视频编辑软件(如Adobe Premiere、Final Cut Pro等)或编程语言中的相应库(如OpenCV、FFmpeg等)来完成。
将两个视频文件合并为一个视频文件。下面是关键函数的简要说明:
cv2.VideoCapture():
- 这个函数用于从视频文件中读取视频流。
- 参数可以是视频文件的路径,也可以是摄像头的索引(通常为 0 表示默认摄像头)。
- 返回一个 VideoCapture 对象,可以用来逐帧读取视频。
cv2.VideoWriter():
- 这个函数用于创建一个用于保存视频的 VideoWriter 对象。
- 参数包括输出视频文件的名称、视频编码器的四字符编码(fourcc)、帧率(fps)、视频帧大小等。
- 返回一个 VideoWriter 对象,可以用来逐帧写入视频。
cap.get():
- 这个方法用于获取视频的属性,如帧率、宽度、高度等。
- 参数是属性的标识符,比如
cv2.CAP_PROP_FPS
用于获取帧率。- 返回属性的值。
cap.isOpened():
- 这个方法用于检查视频是否成功打开。
- 如果视频成功打开,则返回 True;否则返回 False。
cap.read():
- 这个方法用于逐帧读取视频。
- 返回一个布尔值和帧。布尔值表示帧是否成功读取,帧是一个 NumPy 数组,包含当前读取的帧图像的像素值。
out.write():
- 这个方法用于将帧写入到视频文件中。
- 参数是要写入的帧图像。
- 每次调用这个方法都会将一帧图像写入到输出视频文件中。
cap.release():文章来源:https://www.toymoban.com/news/detail-846247.html
- 这个方法用于释放 VideoCapture 对象占用的资源。
- 调用这个方法后,你就不能再使用这个 VideoCapture 对象了。
out.release():文章来源地址https://www.toymoban.com/news/detail-846247.html
- 这个方法用于释放 VideoWriter 对象占用的资源。
- 调用这个方法后,你就不能再使用这个 VideoWriter 对象了。
import cv2
def mergeVideo(videoName1, videoName2):
"""
合并视频
:param videoName1: 视频名称,类似 'Videos/CatRun.mp4'
:param videoName2: 视频名称,类似 'Videos/TwoPeopleRunning.mp4'
:return:
"""
# 打开第一个视频文件
cap1 = cv2.VideoCapture(videoName1)
# 打开第二个视频文件
cap2 = cv2.VideoCapture(videoName2)
# 获取视频信息
fps = int(cap1.get(cv2.CAP_PROP_FPS))
width = int(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 定义视频编码器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 创建 VideoWriter 对象
out = cv2.VideoWriter('Videos/mergeVideo.mp4', fourcc, fps, (width, height))
# 逐帧读取并写入第一个视频文件
while cap1.isOpened():
ret, frame = cap1.read()
if not ret:
break
out.write(frame)
# 逐帧读取并写入第二个视频文件
while cap2.isOpened():
ret, frame = cap2.read()
if not ret:
break
out.write(frame)
# 释放资源
cap1.release()
cap2.release()
out.release()
到了这里,关于Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 视频图像处理基础操作 之 视频捕获/存储/提取/合成/合并的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!