OpenCV-Python实战(2)——图像与视频文件的处理

article/2025/9/3 22:00:53

OpenCV-Python实战(2)——图像与视频文件的处理

    • 0. 前言
    • 1. 图像与视频文件处理基础
    • 2. 图像的读取与写入
      • 2.1 在 OpenCV 中读取图像
      • 2.2 使用 OpenCV 写入图像
      • 2.3 计算机视觉项目处理流程示例
    • 3. 读取相机画面和视频文件
      • 3.1 读取相机画面
      • 3.2 访问捕获画面对象的属性
      • 3.3 保存相机画面
      • 3.4 读取视频文件
      • 3.5 读取 IP 摄像机
    • 4. 保存视频文件
      • 4.1 计算帧率(FPS)
      • 4.2 写入视频文件的流程
    • 5. 视频属性详解
      • 5.1 获取视频对象的属性
      • 5.2 视频属性的使用——视频的反向播放
    • 小结
    • 系列链接

0. 前言

无论在任何类型的计算机视觉任务中,处理图像或视频都是其中的核心要素,绝大多数计算机视觉都会使用图像或视频作为数据输入的形式。此外,任何项目都应该可以在完成任何类型的处理后生成一些数据,这些数据可以以图像或者其它类型形式的输出。在计算机视觉中,由于这些类型的项目(例如,要处理的图像为输入、由机器学习算法生成的模型处理信息、输出目标信息)的固有特性,因此项目的信息流(输入——处理——输出)间也具有特殊的相关性。
在本文中,将学习使用 OpenCV 处理构建计算机视觉应用程序所必需的图像和视频。

1. 图像与视频文件处理基础

在介绍处理文件和图像之前,首先总结下计算机视觉项目的结构,也可以作为本文的主要体系结构:
计算机视觉项目的结构

在上图中,可以看到计算机视觉项目(例如 OpenCV-Python 项目)处理输入文件(例如图像和视频),经过一些处理,项目可以输出一些文件(例如图像和视频)。因此,在本文中,我们将学习如何应对这些需求以及如何正确实现此流程(输入——处理——输出)。
为了处理不同类型的文件或不同图片,在计算机视觉项目中,图像和不同类型的文件通常作为命令行参数传递给脚本,有关命令行参数的介绍,参考 Python 命令行参数详解。

2. 图像的读取与写入

在下面的部分中,我们将图像用作脚本中的命令行参数,并介绍读取和写入图像。

2.1 在 OpenCV 中读取图像

以下示例 load_image.py 展示了如何使用函数 cv2.imshow() 加载图像:

import argparse
import cv2
parser = argparse.ArgumentParser()
parser.add_argument("path_image", help="path to input image to be displayed")
args = parser.parse_args()
image = cv2.imread(args.path_image)
args = vars(parser.parse_args())
image2 = cv2.imread(args["path_image"])
cv2.imshow("loaded image", image)
cv2.imshow("loaded image2", image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这个例子中,必需的参数是 path_image,它是我们要加载的图像的路径。利用 args.path_imageargs["path_image"] 都可以获取图像的路径(从参数中获取值的两种不同方式),然后将它们用作 cv2.imread() 函数的参数。
通过在命令行中执行以下命令,运行脚本:

python load_image.py sigonghuiye.jpeg

可以看到运行结果如以下屏幕截图所示:

在 OpenCV 中读取图像

2.2 使用 OpenCV 写入图像

以下示例 write_image.py 展示了如何使用函数 cv2.imshow() 加载图像:

import argparse
import cv2
parser = argparse.ArgumentParser()
parser.add_argument("path_image", help="path to input image to be displayed")
parser.add_argument("path_image_output", help="path of the processed image to be saved")
args = parser.parse_args()
image = cv2.imread(args.path_image)
args = vars(parser.parse_args())
cv2.imwrite(args["path_image_output"], image)
cv2.waitKey(0)
cv2.destroyAllWindows()

上述示例中,执行脚本需要的参数是 path_imagepath_image_output,它们分别是我们要加载的图像的路径以及图像要保存的路径。
通过在命令行中执行以下命令,运行脚本:

python load_image.py sigonghuiye.jpeg copy_image.jpg

运行结束后就可以在工作目录中,看到保存的 copy_image.jpg.

2.3 计算机视觉项目处理流程示例

计算机视觉项目的常见处理流程是加载图像,执行某种处理,最后输出这个处理过的图像。处理后的图像可以保存到磁盘或者进行展示。为了对计算机视觉项目处理流程有一个完整的认识,在下面的示例中,介绍了这三个步骤(加载、处理和保存)。为了简单起见,处理步骤仅将图像转换为灰度图像,接下来编写脚本 load_processing_save_image.py

import argparse
import cv2
parser = argparse.ArgumentParser()
parser.add_argument("path_image_input", help="path to input image to be displayed")
parser.add_argument("path_image_output", help="path of the processed image to be saved")
args = vars(parser.parse_args())
image_input = cv2.imread(args["path_image_input"])
cv2.imshow("loaded image", image_input)
gray_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray image", gray_image)
cv2.imwrite(args["path_image_output"], gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

上述示例中,执行脚本需要两个必需的参数。第一个是 path_image_input,它表示要加载的图像的路径。第二个是 path_image_output,它表示要保存的结果图像的路径。处理步骤仅将加载的图像转换为灰度图像:

gray_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)

需要注意的是,cv2.cvtColor 函数第二个参数 cv2.COLOR_BGR2GRAY 假定加载的图像是 BGR 彩色图像。如果已经加载了 RGB 彩色图像并且想要将其转换为灰度,则应该使用 cv2.COLOR_RGB2GRAY
通过在命令行中执行以下命令,运行脚本:

python load_processing_save_image.py sigonghuiye.jpeg gray_image.png

可以看到运行结果如以下屏幕截图所示,同时,在运行结束后就可以在工作目录中,看到保存的灰度图像 gray_image.jpg

计算机视觉项目处理流程示例

3. 读取相机画面和视频文件

在某些需要实时计算机视觉项目中,必须捕捉实时相机画面(例如,使用笔记本电脑的摄像头或监控摄像机捕捉画面)。在 OpenCV 中,使用 cv2.VideoCapture 作为从不同来源捕获视频的类,例如图像序列、视频文件和相机。

3.1 读取相机画面

编写 read_camera.py 用于从连接到计算机的相机读取画面。首先看下完整程序,然后再进行详细解释:

import cv2
import argparseparser = argparse.ArgumentParser()
parser.add_argument("index_camera", help="index of the camera to read from", type=int)
args = parser.parse_args()capture = cv2.VideoCapture(args.index_camera)
if capture.isOpened()is False:print("Error opening the camera")
while capture.isOpened():ret, frame = capture.read()if ret is True:cv2.imshow('Input frame from the camera', frame)gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('Grayscale input camera', gray_frame)if cv2.waitKey(20) & 0xFF == ord('q'):breakelse:break
capture.release()
cv2.destroyAllWindows()

cv2.VideoCapture 所必需的参数是 index_camera,它指示要读取的相机的索引。如果有一个摄像头连接到计算机,则它的索引为 0 ,如果有第二台摄像头,可以通过传递参数值 1 来选择它,以此类推;需要注意的是,该参数的类型是 int 。

parser = argparse.ArgumentParser()
parser.add_argument("index_camera", help="index of the camera to read from", type=int)
args = parser.parse_args()

使用 cv2.VideoCapture 的第一步是创建一个要使用的对象 capture

capture = cv2.VideoCapture(args.index_camera)

如果 index_camera 为 0,则相当于调用 cv2.VideoCapture(0) 。为了检查连接是否已正确建立,需要使用 capture.isOpened() 方法,如果无法建立连接,该方法返回 False;如果正确初始化,则此方法返回 True
要从相机逐帧捕获画面,需要调用 capture.read() 方法,该方法从相机返回帧;同时还将返回一个布尔值,此布尔值指示是否已从 capture 对象正确读取帧。

while capture.isOpened():# 逐帧获取相机画面ret, frame = capture.read()if ret is True:# 显示捕获的帧画面cv2.imshow('Input frame from the camera', frame)

获取的相机帧画面与 OpenCV 读取的图像具有相同的结构,因此可以像处理图像一样处理它。例如,要将帧画面转换为灰度:

		# 将从相机捕获的帧转换为灰度图像gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 显示灰度帧图像cv2.imshow('Grayscale input camera', gray_frame)

接下来,实现按下 q 键退出程序的功能,ord('q') 返回 q 字符对应的 8 位 ASCII 值,而 cv2.waitKey() 与 0xFF 的 按位与 (&) 运算用于仅获取 cv2.waitKey() 的最后 8 位。因此,可以对这两个值进行比较,如果相等则退出程序:

        # 按下 q 键可退出程序执行if cv2.waitKey(20) & 0xFF == ord('q'):break

最后,释放所有内容 (cv2.VideoCapture,并销毁创建的窗口):

capture.release()
cv2.destroyAllWindows()

通过在命令行中执行以下命令,运行脚本:

python read_camera.py 0

可以看到运行结果显示了相机获取的实时画面:

获取相机画面

3.2 访问捕获画面对象的属性

可以使用 capture.get(property_identifier) 访问 capture 对象的某些属性,例如帧宽度、帧高度和每秒帧数 (Frames Per Second, FPS)。如果调用不受支持的属性,则返回值将为 0:

import cv2capture = cv2.VideoCapture(0)# 获取 VideoCapture 的属性 (frame width, frame height and frames per second (fps)):
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)# 打印属性值
print("CV_CAP_PROP_FRAME_WIDTH: '{}'".format(frame_width))
print("CV_CAP_PROP_FRAME_HEIGHT : '{}'".format(frame_height))
print("CAP_PROP_FPS : '{}'".format(fps))# Check if camera opened successfully
if capture.isOpened()is False:print("Error opening the camera")while capture.isOpened():ret, frame = capture.read()if ret is True:cv2.imshow('Input frame from the camera', frame)if cv2.waitKey(20) & 0xFF == ord('q'):breakelse:breakcapture.release()
cv2.destroyAllWindows()

执行此脚本将会打印如下属性信息:

CV_CAP_PROP_FRAME_WIDTH: '640.0'
CV_CAP_PROP_FRAME_HEIGHT : '480.0'
CAP_PROP_FPS : '30.0'

3.3 保存相机画面

可以修改前面的示例以在处理流程中添加其他的功能。例如,我们可能想将一些关键的感兴趣帧保存到磁盘中。在以下示例 read_camera_capture.py 中 ,将添加此示例功能,当按下键盘上的 c 键时,将当前帧保存到磁盘(同时保存 BGR 和灰度帧):

import cv2
import argparsecapture = cv2.VideoCapture(0)
if capture.isOpened() is False:print("Error opening the camera")
frame_index = 0
while capture.isOpened():ret, frame = capture.read()if ret is True:gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 保存相机画面if cv2.waitKey(20) & 0xFF == ord('c'):frame_name = "camera_frame_{}.png".format(frame_index)gray_frame_name = "grayscale_camera_frame_{}.png".format(frame_index)# 将当前帧保存到磁盘(同时保存 BGR 和灰度帧)cv2.imwrite(frame_name, frame)cv2.imwrite(gray_frame_name, gray_frame)frame_index += 1if cv2.waitKey(20) & 0xFF == ord('q'):breakelse:breakcapture.release()
cv2.destroyAllWindows()

当按下 c 键时,首先构造两个文件名;然后,将两个图像保存到磁盘;最后,frame_index 递增,以便为保存下一帧做好准备。

3.4 读取视频文件

cv2.VideoCapture 也可以用于读取视频文件,要读取视频文件,应在创建 cv2.VideoCapture 对象时提供视频文件的路径,编写 read_video_file.py 脚本:

import cv2
import argparseparser = argparse.ArgumentParser()
parser.add_argument("video_path", help="path to the video file")
args = parser.parse_args()
capture = cv2.VideoCapture(args.video_path)
if capture.isOpened() is False:print("Error opening the video file!")while capture.isOpened():ret, frame = capture.read()if ret is True:cv2.imshow('Original frame from the video file', frame)gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('Grayscale frame', gray_frame)if cv2.waitKey(20) & 0xFF == ord('q'):breakelse:break
capture.release()
cv2.destroyAllWindows()

通过在命令行中执行以下命令,运行脚本:

python read_video_file.py xinlingqilv.mp4

可以看到运行结果开始播放视频文件:

播放视频文件

3.5 读取 IP 摄像机

cv2.VideoCapture 也可以从 IP 摄像头读取数据。在 OpenCV 中从 IP 摄像头读取数据与从文件读取数据非常相似。唯一需要修改的是提供给 cv2.VideoCapture 构造函数的参数。可以使用本地网络中的 IP 摄像机或尝试连接公共 IP 摄像机。

4. 保存视频文件

接下来,首先介绍与视频相关的基本概念(例如,fps、编解码器和视频文件格式等),然后将了解如何使用 cv2.VideoWriter 保存视频文件。

4.1 计算帧率(FPS)

FPS 是计算机视觉项目中的一个重要指标,该指标表示每秒处理的帧(画面)数,FPS 越高越好。但是,算法每秒应处理的帧数将取决于需要解决的特定问题。例如,如果算法需要跟踪和检测在街上行走的人,那么 15 FPS 可能就足够了。但是,如果是检测和跟踪高速公路上快速行驶的汽车,则可能需要 20-25 FPS。
因此,计算计算机视觉项目中的 FPS 指标非常重要。编写 read_camera_fps.py 以输出 FPS

import cv2
import argparse
import timecapture = cv2.VideoCapture(0)if capture.isOpened() is False:print("Error opening the camera")while capture.isOpened():ret, frame = capture.read()if ret is True:processing_start = time.time()cv2.imshow("Input frame from the camera", frame)gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('Grayscale input camera', gray_frame)if cv2.waitKey(20) & 0xFF == ord('q'):breakprocessing_end = time.time()processing_time_frame = processing_end - processing_startprint("FPS: {}".format(1.0 / processing_time_frame))else:breakcapture.release()
cv2.destroyAllWindows()

在上述示例脚本中,首先需要获取处理开始的时间:

processing_start = time.time()

然后,获取所有处理完成后的时间:

processing_end = time.time()

接下来,计算时间差:

processing_time_frame = processing_end - processing_start

最后,计算并打印 FPS:

print("FPS: {}".format(1.0 / processing_time_frame))

4.2 写入视频文件的流程

视频编码是一种用于压缩和解压缩数字视频的程序。具体而言,编解码器可用于将未压缩的视频转换为压缩后的视频,或者可用于将压缩的视频转换为未压缩的视频。压缩视频格式通常遵循视频压缩规范或视频编码格式的标准规范。OpenCV 提供了 FOURCC (一个 4 字节编码),用于指定视频编解码器,查看可用编码列表获取更多可用编码。应该注意的是:支持的编解码器是平台相关的,如果想使用特定的编解码器,则应该在系统上安装该编解码器。典型的编解码器包括 DIVX、XVID、X264 和 MJPG。
视频文件格式是一种用于存储数字视频数据的文件格式,典型的视频文件格式包括 AVI(*.avi)、MP4(*.mp4)、QuickTime(*.mov) 和 Windows Media Video(*.wmv)。
最后,应该考虑到视频文件格式和 FOURCC 之间需要进行正确的组合。 在 OpenCV 中创建视频文件时,必须考虑这些因素:

写入视频文件的流程

上图总结了在 OpenCV 中使用 cv2.VideoWriter() 创建视频文件时应考虑的主要因素。在创建的名为 video_example.avi 视频中,FOURCC 值为 XVID,视频文件格式为 AVI(*.avi),同时最后,应设置视频每一帧的 FPS 和尺寸。
脚本 write_video_file.py 演示如何创建视频文件:


# Import required packages
import cv2
import argparseparser = argparse.ArgumentParser()parser.add_argument("output_video_path", help="path to the video file to write")
args = parser.parse_args()capture = cv2.VideoCapture(0)frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)fourcc = cv2.VideoWriter_fourcc(*'XVID')out_gray = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), False)while capture.isOpened():ret, frame = capture.read()if ret:gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)out_gray.write(gray_frame)cv2.imshow('gray', gray_frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:breakcapture.release()
out_gray.release()
cv2.destroyAllWindows()

在上例中,必需的参数是输出视频文件名(例如 video_example.avi):

parser = argparse.ArgumentParser()
parser.add_argument("output_video_path", help="path to the video file to write")
args = parser.parse_args()

从连接到计算机的第一台相机拍摄视频画面。因此,首先创建对象:

capture = cv2.VideoCapture(0)

接下来,从 capture 对象中获取一些关键属性(帧宽度、帧高度和 FPS),用于创建视频文件时使用:

frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)

然后,使用四字节编码 FOURCC 指定视频编解码器,此处将编解码器定义为 XVID :

fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')

也可以使用以下方式指定视频编码器:

fourcc = cv2.VideoWriter_fourcc(*'XVID')

然后,使用与输入相机相同的属性创建 cv2.VideoWriter 对象 out_graycv2.VideoWriter 的最后一个参数值是 False 表示以灰度方式写入视频。如果我们想创建彩色视频,最后一个参数值为 True :

out_gray = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), False)

使用 capture.read()catpure 对象获取相机帧,每一帧都被转换成灰度并写入视频文件,如果按下 q 键,程序结束:

while capture.isOpened():ret, frame = capture.read()if ret:gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)out_gray.write(gray_frame)cv2.imshow('gray', gray_frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break

最后,释放所有内容(包括 cv2.VideoCapturecv2.VideWriter 对象,并销毁创建的窗口):

capture.release()
out_gray.release()
cv2.destroyAllWindows()

通过在命令行中执行以下命令,运行脚本:

python write_video_file.py video_example.avi

在工作目录下可以看到保存的灰度视频文件。

5. 视频属性详解

在上述示例中,我们已经了解了如何从 cv2.VideoCapture 对象中获取一些关键属性。接下来,将介绍所有属性并了解它们的工作原理。最后,我们将使用这些属性来加载视频文件并反向输出(首先显示视频的最后一帧,依此类推)。

5.1 获取视频对象的属性

创建 read_video_file_all_properties.py 脚本来显示所有属性。其中一些属性仅在使用相机时才有效(而在视频文件时无效)。
在脚本中,首先创建 decode_fourcc() 函数,它将 capture.get(cv2.CAP_PROP_FOURCC) 返回的 int 类型的值转换为表示编解码器的字符串值,来正确输出编解码器:

def decode_fourcc(fourcc):fourcc_int = int(fourcc)print("int value of fourcc: '{}'".format(fourcc_int))fourcc_decode = ""for i in range(4):int_value = fourcc_int >> 8 * i & 0xFFprint("int_value: '{}'".format(int_value))fourcc_decode += chr(int_value)return fourcc_decode

下图解释了函数 decode_fourcc 的工作原理:

视频对象的属性

第一步是获取由 capture.get(cv2.CAP_PROP_FOURCC) 返回的值( int 表示的字符串),然后,迭代四次,每次获取八位并将这八位转换为 int 。最后,使用 chr() 函数将这些 int 值转换为 char。也可以只使用一行代码就可以完成此功能:

return "".join([chr((fourcc_int >> 8 * i) & 0xFF) for i in range(4)])

下表显示了视频文件的主要属性和解释:

视频属性解释
CAP_PROP_POS_FRAMES视频文件的当前帧
CAP_PROP_POS_MSEC当前帧的时间戳
CAP_PROP_FPS获取 FPS
CAP_PROP_FRAME_WODTH视频帧的宽度
CAP_PROP_FRAME_HEIGHT视频帧的高度
CAP_PROP_FRAME_COUNT视频文件的总帧数

使用以下代码,可以获取和打印所有属性:

print("CV_CAP_PROP_FRAME_WIDTH:'{}'".format(capture.get(cv2.CAP_PROP_FRAME_WIDTH)))
print("CV_CAP_PROP_FRAME_HEIGHT :'{}'".format(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print("CAP_PROP_FPS : '{}'".format(capture.get(cv2.CAP_PROP_FPS)))
print("CAP_PROP_POS_MSEC :'{}'".format(capture.get(cv2.CAP_PROP_POS_MSEC)))
print("CAP_PROP_POS_FRAMES :'{}'".format(capture.get(cv2.CAP_PROP_POS_FRAMES)))
print("CAP_PROP_FOURCC :'{}'".format(decode_fourcc(capture.get(cv2.CAP_PROP_FOURCC))))
print("CAP_PROP_FRAME_COUNT :'{}'".format(capture.get(cv2.CAP_PROP_FRAME_COUNT)))
print("CAP_PROP_MODE : '{}'".format(capture.get(cv2.CAP_PROP_MODE)))
print("CAP_PROP_BRIGHTNESS :'{}'".format(capture.get(cv2.CAP_PROP_BRIGHTNESS)))
print("CAP_PROP_CONTRAST :'{}'".format(capture.get(cv2.CAP_PROP_CONTRAST)))
print("CAP_PROP_SATURATION :'{}'".format(capture.get(cv2.CAP_PROP_SATURATION)))
print("CAP_PROP_HUE : '{}'".format(capture.get(cv2.CAP_PROP_HUE)))
print("CAP_PROP_GAIN : '{}'".format(capture.get(cv2.CAP_PROP_GAIN)))
print("CAP_PROP_EXPOSURE :'{}'".format(capture.get(cv2.CAP_PROP_EXPOSURE)))
print("CAP_PROP_CONVERT_RGB :'{}'".format(capture.get(cv2.CAP_PROP_CONVERT_RGB)))
print("CAP_PROP_RECTIFICATION :'{}'".format(capture.get(cv2.CAP_PROP_RECTIFICATION)))
print("CAP_PROP_ISO_SPEED :'{}'".format(capture.get(cv2.CAP_PROP_ISO_SPEED)))
print("CAP_PROP_BUFFERSIZE :'{}'".format(capture.get(cv2.CAP_PROP_BUFFERSIZE)))

5.2 视频属性的使用——视频的反向播放

为例更好的了解如何使用上述属性,接下来,我们通过实战使用这些属性。编写 read_video_file_backwards.py 脚本,该脚本使用一些上述属性加载视频并反向播放(首先显示视频的最后一帧,然后播放倒数第二帧,依此类推),为了实现此目的,需要使用属性:cv2.CAP_PROP_FRAME_COUNTcv2.CAP_PROP_POS_FRAMES

import cv2
import argparseparser = argparse.ArgumentParser()
parser.add_argument("video_path", help='path to the video fiel')
args = parser.parse_args()capture = cv2.VideoCapture(args.video_path)if capture.isOpened() is False:print("Error opening vieo stream or file")frame_index = capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1
print("Starting in frame: '{}'".format(frame_index))while capture.isOpened() and frame_index >= 0:capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)ret, frame = capture.read()if ret:cv2.imshow('Original frame', frame)frame_index = frame_index - 1print("next index to read: '{}'".format(frame_index))# Press q on keyboard to exit the program:if cv2.waitKey(25) & 0xFF == ord('q'):break# Break the loopelse:breakcapture.release()
cv2.destroyAllWindows()

第一步是获取最后一帧的索引:

frame_index = capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1

然后,将当前帧设置为所获取帧的位置:

capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)

这样,就可以像读取获取都帧了:

ret, frame = capture.read()

最后,索引值减一以从视频文件中读取下一帧:

frame_index = frame_index - 1

通过运行以下命令就可以看到反向播放的视频:

python read_video_file_backwards.py video_example.avi

反向播放

可以简单修改此脚本以保存反向播放的结果视频。

import cv2
import argparsedef decode_fourcc(fourcc):fourcc_int = int(fourcc)print("int value of fourcc: '{}'".format(fourcc_int))fourcc_decode = ""for i in range(4):int_value = fourcc_int >> 8 * i & 0xFFprint("int_value: '{}'".format(int_value))fourcc_decode += chr(int_value)return fourcc_decodeparser = argparse.ArgumentParser()
# 添加 'video_path' 参数用于输入视频文件名
parser.add_argument("video_path", help="path to the video file")
# 添加 'output_video_path' 参数用于输出视频文件名
parser.add_argument("output_video_path", help="path to the video file to write")
args = parser.parse_args()capture = cv2.VideoCapture(args.video_path)# 获取 VideoCapture 属性
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
codec = decode_fourcc(capture.get(cv2.CAP_PROP_FOURCC))print("codec: '{}'".format(codec))fourcc = cv2.VideoWriter_fourcc(*codec)# 创建 VideoWriter 对象,使用与输入视频文件相同的属性
out = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), True)# Check if camera opened successfully
if capture.isOpened() is False:print("Error opening video stream or file")
frame_index = capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1while capture.isOpened() and frame_index >= 0:capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)ret, frame = capture.read()if ret is True:# 显示处理结果帧cv2.imshow('Original frame', frame)# 将处理结果帧写入视频out.write(frame)frame_index = frame_index - 1# Press q on keyboard to exit the program:if cv2.waitKey(25) & 0xFF == ord('q'):break# Break the loopelse:break# Release everything:
capture.release()
out.release()
cv2.destroyAllWindows()

小结

计算机视觉项目中的常见信息流是先加载一些图像,进行处理,最后输出处理后的图像。因此,处理图像和文件是计算机视觉项目的关键要素。就视频流而言,主要类包括 cv2.VideoCapturecv2.VideoWriter。在编写视频文件时,需要注意视频编解码器和视频文件格式间的匹配,典型的编解码器包括 DIVX、XVID、X264 和 MJPG,而典型的视频文件格式包括 AVI(*.avi)、MP4(*.mp4)、QuickTime(*.mov) 和 Windows Media Video(*.wmv)。
同时介绍了 FPS 的概念以及如何在程序中计算它。此外,展示了如何获取 cv2.VideoCapture 对象的所有属性,以及如何使用它们加载视频并反向播放。

系列链接

OpenCV-Python实战(1)——OpenCV简介与图像处理基础
OpenCV-Python实战(3)——OpenCV中绘制图形与文本
OpenCV-Python实战(4)——OpenCV常见图像处理技术
OpenCV-Python实战(5)——OpenCV图像运算
OpenCV-Python实战(6)——OpenCV中的色彩空间和色彩映射
OpenCV-Python实战(7)——直方图详解
OpenCV-Python实战(8)——直方图均衡化
OpenCV-Python实战(9)——OpenCV用于图像分割的阈值技术
OpenCV-Python实战(10)——OpenCV轮廓检测
OpenCV-Python实战(11)——OpenCV轮廓检测相关应用
OpenCV-Python实战(12)——一文详解AR增强现实
OpenCV-Python实战(13)——OpenCV与机器学习的碰撞
OpenCV-Python实战(14)——人脸检测详解
OpenCV-Python实战(15)——面部特征点检测详解
OpenCV-Python实战(16)——人脸追踪详解
OpenCV-Python实战(17)——人脸识别详解
OpenCV-Python实战(18)——深度学习简介与入门示例
OpenCV-Python实战(19)——OpenCV与深度学习的碰撞
OpenCV-Python实战(20)——OpenCV计算机视觉项目在Web端的部署
OpenCV-Python实战(21)——OpenCV人脸检测项目在Web端的部署
OpenCV-Python实战(22)——使用Keras和Flask在Web端部署图像识别应用
OpenCV-Python实战(23)——将OpenCV计算机视觉项目部署到云端


http://chatgpt.dhexx.cn/article/ibwZqqwN.shtml

相关文章

Python实战:批量修改文本文件

Python实战:批量修改文本文件 sub方法、listdir方法、with open as 函数的实战用法 一、需求: 目前我们有一个文件夹,里面有爬虫抓取的txt文档1000篇,但是由于抓取格式问题,每篇文章之后都有几行相同的乱码现在我们…

Python实战,爬取金融期货数据

大家好,我是毕加锁。 今天给大家带来的是 Python实战,爬取金融期货数据 文末送书! 文末送书! 文末送书! 任务简介 首先,客户原需求是获取https://hq.smm.cn/copper网站上的价格数据(注:获取的是…

20个Python实战项目(附源码),拿走就用。

Python是目前最好的编程语言之一。 由于其可读性和对初学者的友好性,已被广泛使用。 那么要想学会并掌握Python,可以实战的练习项目是必不可少的。 接下来,我将给大家介绍20个非常实用的Python项目,帮助大家更好的学习Python。 大家也可根据项目的需求,自己构建解决方法…

这4个Python实战项目,让你瞬间读懂Python!

前言 Python 是一种极具可读性和通用性的编程语言。Python 这个名字的灵感来自于英国喜剧团体 Monty Python,它的开发团队有一个重要的基础目标,就是使语言使用起来很有趣。Python 易于设置,并且是用相对直接的风格来编写,对错误…

验证email的Python实战代码

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

python实战—考勤报表数据分析处理

标题python实战—考勤报表数据分析处理 需求: 在部分考勤报表导出来的数据中,会出现多次打卡的记录,即excel同一单元格中会有多个时间记录,而Excel本身无法只能进行2个数据分列。 -存在员工忘记打卡,漏打卡、迟到早退…

python实战-读取xlsx表格批量替换文件名

文章目录 一、前言二、解决思路三、具体代码实现四、总结 一、前言 ​  一位在校当老师的同学遇到了一个需求,学生1寸照片是以学生姓名命名,现在需要重命名1寸照片,重命名为exel里对应的学生姓名的身份证号码,我心想这个需求很…

百看不如一练, 247 个 Python 实战案例!

众所周知,我们在学习Pyhont过程中,大都看书枯燥、看视频进度慢,网上查找的学习案例又比较凌乱不成体系。。。 百看不如一练,今天为大家搜集了一份Python从入门到进阶的实战案例合集,共计247个案例,185页内容…

整理了200多个Python实战案例,都有完整且详细的教程

不管是学习什么语言,最终目的都是做项目。搜遍全网,整理了200多个Python实战的小项目,都有完整的代码,以及代码中用到的数据源等等。可以直接拿来用,也可以用于学习练手寻找思路。 告别枯燥,60秒学会⼀个⼩…

精选32个最新Python实战项目(附源码),拿走就用

Python是目前最好的编程语言之一。由于其可读性和对初学者的友好性,已被广泛使用。那么要想学会并掌握Python,可以实战的练习项目是必不可少的。接下来,我将给大家介绍20个非常实用的Python项目,帮助大家更好的学习Python。大家也…

Appium + python 实战

文章目录 Appium介绍Appium 原理Appium使用Appium Python实战 Appium介绍 是一个移动端的自动化测试框架,是跨平台的,支持ios和Android平台上的移动原生应用、混合以及web移动应用,可以针对不同的平台使用一套API来编写测试脚本&#xff0c…

30个有趣的Python实战项目(附源码)

大家好,今天给大家重磅推荐我的好朋友J哥的公众号——「菜J学Python」,J哥经常在公众号分享有趣的Python实战项目,而且基本都附代码和数据。废话不多说,大家先点击以下卡片关注一波: 点击关注菜J学Python J哥是985金融…

35个Python实战项目,完整源代码!

收集整理最新36个python实战项目源代码,系统实用,不是普通的小脚本! 多看多练是提升代码能力的最佳途径,一起操练起来! 视频转字符动画 12306 B站弹幕 B站滑块验证码破解 GUI签名 python爬取并简单分析51job py…

全网首发!精选32个最新Python实战项目(附源码),拿走就用!

Python是目前最好的编程语言之一。由于其可读性和对初学者的友好性,已被广泛使用。那么要想学会并掌握Python,可以实战的练习项目是必不可少的。接下来,我将给大家介绍32个非常实用的Python项目,帮助大家更好的学习Python。大家也…

整理了60个 Python 实战例子,拿来即用!

人生苦短,我用 Python! 大家好,最近有一些朋友问我有没有一些 Python 实战小案例。今天我整理排版了一遍,给大家分享一下。喜欢记得点赞、收藏、关注。 整理了60个Python小例子,拿来即用! 整理了60个 Py…

OpenCV-Python实战(1)——OpenCV简介与图像处理基础

OpenCV-Python实战(1)——OpenCV简介与图像处理基础 OpenCV介绍Python安装OpenCVOpenCV主要模块OpenCV应用场景 OpenCV图像处理基础图像基础图像处理中的主要问题图像处理流程 像素、颜色、通道、图像和颜色空间图像描述图像文件类型 OpenCV中的坐标系Op…

精选了20个Python实战项目(附源码),拿走就用!零基础练手不二项目!

Python是目前最好的编程语言之一。由于其可读性和对初学者的友好性,已被广泛使用。 那么要想学会并掌握Python,可以实战的练习项目是必不可少的。 接下来,我将给大家介绍20个非常实用的Python项目,帮助大家更好的学习Python。 …

精选了20个Python实战项目(附源码),拿走就用!

点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 昔闻洞庭水,今上岳阳楼。 大家好,我是小F。 Python是目前最好的编程语言之一。由于其可读性和对初学者的友好性,已被…

100个精选Python实战项目案例,送给缺乏练手经验的你

随着 Python 语言的流行,越来越多的人加入到了 Python 的大家庭中。为什么这么多人学 Python ?我要喊出那句话了:“人生苦短,我用 Python!”,正是因为语法简单、容易学习,所以 Python 深受大家喜…

python:实战篇

python 实战 python 实战篇 1、python解压1. python解压zip、7z2. python 解压rar1)windows:2)linux: 2、python执行Linux系统命令的3种方法3、python代码打包成exe安装包安装打包加密【附】 4、windows下:py文件引用其他py文件5、…