OpenCV 之视频文件的处理


  计算机视觉项目的常见处理流程是加载图像,然后进行某种处理,最后输出处理后的图像,结果可以保存到磁盘或者进行展示。因此,下文以将图像转换为灰度图像为例,对图像或视频的加载、处理和保存三个步骤进行介绍。

1. 图像数据处理

import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--in_image', default='girl.jpg', help='Input image')
parser.add_argument('--out_image', default='girl_gray.jpg', help='Output image')
args = parser.parse_args([])  # Pycharm
# args = parser.parse_args([])  # Jupyter Notebook

img = cv2.imread(args.in_image)  # 读取
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 处理:转为灰度图
cv2.imshow('gril gray', img_gray)  # 显示
cv2.imwrite(args.out_image, img_gray)  # 写入
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结束后,可在工作目录中看到保存的灰度图像girl_gray.jpg

2. 视频数据处理

  在 OpenCV 中,使用cv2.VideoCapture()捕获不同来源的视频,如图像序列、视频文件和相机。

2.1 调用摄像头

"""
功能:保存关键帧
当按下键盘上的 c 键时,将当前帧保存到磁盘(同时保存 BGR 和灰度帧)
"""

import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--index_camera', default=int(0), help="index of the camera")
args = parser.parse_args([])

capture = cv2.VideoCapture(args.index_camera)
# capture = cv2.VideoCapture(0)

if capture.isOpened() is False:
    print("Error opening the camera")
    
# 注释 1    
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("FRAME_WIDTH: '{}'".format(frame_width))  # FRAME_WIDTH: '640.0'
print("FRAME_HEIGHT : '{}'".format(frame_height))  # FRAME_HEIGHT : '480.0'
print("FPS : '{}'".format(fps))  # FPS : '30.0'
   
frame_index = 0
while capture.isOpened():
    ret, frame = capture.read()  # 注释 2
    if ret is True:
        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 注释 3
        cv2.imshow('Grayscale input camera', gray_frame)
        if cv2.waitKey(20) & 0xFF == ord('c'):  # 注释 4
            frame_name = "camera_frame_{}.png".format(frame_index)
            gray_frame_name = "grayscale_camera_frame_{}.png".format(frame_index)
            cv2.imwrite(frame_name, frame)
            cv2.imwrite(gray_frame_name, gray_frame)
            frame_index += 1
        if cv2.waitKey(20) & 0xFF == ord('q'):
            break
    else:
        break

capture.release()  # 注释 6
cv2.destroyAllWindows()

注释:

  1. 访问capture对象的某些属性,例如帧宽度、帧高度和每秒帧数;
  2. capture.read()方法:从相机逐帧捕获画面,该方法从相机返回帧和一个布尔值(指示是否已从capture对象正确读取帧);
  3. 将图像转为灰度图;
  4. 实现按下c键保存功能:
    (1)cv2.waitKey()0xFF的按位与 (&) 运算用于仅获取cv2.waitKey()的最后 8 位;
    (2)ord('c')返回 q 字符对应的 8 位 ASCII 值;
  5. 实现按下q键退出程序的功能;
  6. 释放所有内容;

2.2 读取视频文件

  cv2.VideoCapture也可用以读取视频文件,只需提供视频文件的路径。

import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--video_path", default='qiaqia.mp4', 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'):
            break
    else:
        break
capture.release()
cv2.destroyAllWindows()

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

2.3 保存视频文件

  本节主要介绍如何使用cv2.VideoWriter保存视频文件。

2.3.1 计算 FPS

import cv2
import time

capture = 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'):
            break
        processing_end = time.time()
        processing_time_frame = processing_end - processing_start
        print("FPS: {}".format(1.0 / processing_time_frame))  # 注释 1
    else:
        break

capture.release()
cv2.destroyAllWindows()

注释 :

  1. (1)processing_time_frame是处理一帧图像所耗时间;(2)最终计算所得 FPS 会比实际值小,因为包含了cv2.waitKey(20)的时间。

2.3.2 写入视频文件

  视频编码是一种用于压缩和解压缩数字视频的程序。压缩视频格式通常遵循视频压缩规范或视频编码格式的标准规范。OpenCV 提供了 FOURCC 用于指定视频编解码器。应该注意的是:支持的编解码器是平台相关的,如果想使用特定的编解码器,则应该在系统上安装该编解码器。典型的编解码器包括 DIVX、XVID、X264 和 MJPG。视频文件格式是一种用于存储数字视频数据的文件格式,典型的视频文件格式包括*.avi*.mp4*.mov*.wmv。在使用时,应考虑视频文件格式和 FOURCC 之间需要进行正确的组合。 在 OpenCV 中创建视频文件时,必须考虑这些因素:

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

import cv2
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--output_video_path", default='./my_video.mp4', help="write video path")
args = parser.parse_args([])

capture = cv2.VideoCapture(0)

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

fourcc = cv2.VideoWriter_fourcc(*'XVID')

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

while capture.isOpened():
    ret, frame = capture.read()
    if ret:
        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        gray_frame = cv2.flip(gray_frame, 1)  # 水平翻转
        out_gray.write(gray_frame)  

        cv2.imshow('gray', gray_frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

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

3. 实例

  加载视频文件并反向输出(首先显示视频的最后一帧,依此类推)。

import cv2
import argparse

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 & 0xFF
        print("int_value: '{}'".format(int_value))
        fourcc_decode += chr(int_value)
    return fourcc_decode
    
parser = argparse.ArgumentParser()
parser.add_argument("--video_path", default='qiaqia.mp4', help="video file path")
parser.add_argument("--output_video_path", default='', help="video write path")
args = parser.parse_args([])

capture = cv2.VideoCapture(args.video_path)

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)

out = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), True)

if capture.isOpened() is False:
    print("Error opening video stream or file")
frame_index = capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1

while 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
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break
    else:
        break

capture.release()
out.release()
cv2.destroyAllWindows()

【转载自】 OpenCV-Python实战(2)——图像与视频文件的处理

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值