Python-OpenCV中VideoCapture类和VideoWriter类的使用

海信鸥
2023-12-01

Python-OpenCV中VideoCapture类

Python-OpenCV中的VideoCapture类的官方文档:
https://docs.opencv.org/4.0.0/d8/dfe/classcv_1_1VideoCapture.html

VideoCapture()是用于从视频文件、图片序列、摄像头捕获视频的类;

#!/usr/bin/env python
'''
VideoCapture()的使用
'''
import cv2
import argparse
import os
import pdb
# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-v", “–videoPath”, default="./video_1.mp4", help=“path to input video”)
ap.add_argument("-o", “–outputPath”, default=“grabImages”, help=“path to output frames”)

args = vars(ap.parse_args())
# 初始化,并读取第一帧
# rval表示是否成功获取帧
# frame是捕获到的图像
vc = cv2.VideoCapture(args[“videoPath”])
rval, frame = vc.read()

# 获取视频fps
fps = vc.get(cv2.CAP_PROP_FPS)
# 获取视频总帧数
frame_all = vc.get(cv2.CAP_PROP_FRAME_COUNT)
print("[INFO] 视频FPS: {}".format(fps))
print("[INFO] 视频总帧数: {}".format(frame_all))
print("[INFO] 视频时长: {}s".format(frame_all/fps))

outputPath = os.path.sep.join([args[“outputPath”]])
if os.path.exists(outputPath) is False:
print("[INFO] 创建文件夹,用于保存提取的帧")
os.mkdir(outputPath)

# 每隔100帧保存一张图片
frame_interval = 100
# 统计当前帧
frame_count = 1
# 保存图片个数
count = 0

while rval:
    rval, frame = vc.read()
    if frame_count % frame_interval == 0:
        filename = os.path.sep.join([outputPath, “test_{}.jpg”.format(count)])
        cv2.imwrite(filename, frame)
        count += 1
        print(“保存图片:{}”.format(filename))
    frame_count += 1
    c = cv2.waitKey(1)
	if c == 27:
		break

# 关闭视频文件
vc.release()
print("[INFO] 总共保存:{}张图片".format(count))
cv2.destroyAllWindows()
  1. cap= cv2.VideoCapture(args[“videoPath”])
    cap = cv2.VideoCapture(0)
    VideoCapture()中参数是0,表示打开笔记本的内置摄像头。
    cap = cv2.VideoCapture("…/test.avi")
    VideoCapture("…/test.avi"),表示参数是视频文件路径则打开视频。

  2. ret,frame = cap.read()
    cap.read()按帧读取视频,ret,frame是cap.read()方法的两个返回值。
    ret是布尔值,如果读取帧正确,则返回True,如果文件读取到结尾,则返回False。frame就是每一帧的图像,是个三维矩阵。

  3. c=cv2.waitKey(1)
    c得到的是键盘输入的ASCII码,esc键对应的ASCII码是27,即按esc键时if条件句成立
    waitKey()方法本身表示等待键盘输入,
    参数是1,表示延时1ms切换到下一帧图像,对于视频而言;
    参数为0,如cv2.waitKey(0)只显示当前帧图像,相当于视频暂停,;
    参数过大如cv2.waitKey(1000),会因为延时过久而感觉到卡顿。

  4. 调用release()释放摄像头

  5. 调用destroyAllWindows()关闭所有图像窗口

Python-OpenCV中VideoWriter类

官网资料:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html?highlight=videowriter

OpenCV 底层是用 FFMEPG 进行多媒体开发的,所以 OpenCV 它的长项不在于此,它只是提供了这种能力而已,如果要针对多媒体文件做复杂的处理,推荐的还是 FFMEPG 专业库。

OpenCV 用来创建视频文件的类是 VideoWriter。

视频类相关的基础知识

  1. 文件后缀名
    我们一般都知道视频文件是 .mp4、.3gp、.rmvb 等等格式的,后缀名是为了告诉用户或者操作系统,它的内容是什么格式的,方便用专业的工具或者软件操作它们。

  2. 文件格式
    我们可以将一个视频文件看做一个容器,这个容器里面有视频画面数据、音频数据、字幕数据等等。
    不同的文件格式如 mp4、avi、mkv 等等,它们存放打包数据的方式不一样,文件内部文件编码方式也可能不一样。

  3. 编码格式
    视频容器中,一般有视频和音频数据,它们采取的编码方式不一样。
    视频常见的编码方式通常有: x264、h264、mpeg-4
    音频常见的编码方式通常有: mp3、AAC、flac
    编码的目的主要是为了高效存储和传输,如果你不采用编码压缩的话,那么视频可以看做是一系列的图片序列,体积会非常大。

  4. 编码器和解码器
    把视频或者音频按照编码格式,编码成特定文件格式需要编码器的参与,不然每次开发重新写代码代价很高。
    把特定文件格式解码成特定的编码格式数据,这个过程称为解码,需要解码器的存在。
    解码器和编码器都有开源的或者收费的工具库,极大方便了开发者。

  5. FPS 帧率
    frame per second,每秒钟有多少帧图像。
    fps 越高,细节越好,体验也越好,但是文件容量也越高。

OpenCV 的 VideoWriter 类

VideoWriter(filename, fourcc, fps, frameSize[, isColor])
filename:要保存的文件的路径
fourcc:指定编码器
fps:要保存的视频的帧率
frameSize:要保存的文件的画面尺寸
isColor:指示是黑白画面还是彩色的画面

fourcc 本身是一个 32 位的无符号数值,用 4 个字母表示采用的编码器。 常用的有 “DIVX"、”MJPG"、“XVID”、“X264"。fourcc可用的列表

代码示例

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()

这段代码的目的就是获取摄像头的视频流,然后保存到本地,帧率是 20fps,尺寸是640*480.

如果需要读取视频文件,那么就将 VideoCapture 指定文件路径。

如果将图片序列合成为视频文件,原理也一样,一张一张读取,然后写到 VideoWriter 当中去。

 类似资料: