文章目录
- 1. 图像数据处理
- 2. 视频数据处理
- 2.1 调用摄像头
- 2.2 读取视频文件
- 2.3 保存视频文件
- 2.3.1 计算 FPS
- 2.3.2 写入视频文件
- 3. 实例
计算机视觉项目的常见处理流程是加载图像,然后进行某种处理,最后输出处理后的图像,结果可以保存到磁盘或者进行展示。因此,下文以将图像转换为灰度图像为例,对图像或视频的加载、处理和保存三个步骤进行介绍。
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()
注释:
- 访问
capture
对象的某些属性,例如帧宽度、帧高度和每秒帧数;capture.read()
方法:从相机逐帧捕获画面,该方法从相机返回帧和一个布尔值(指示是否已从capture
对象正确读取帧);- 将图像转为灰度图;
- 实现按下
c
键保存功能:
(1)cv2.waitKey()
与0xFF
的按位与 (&) 运算用于仅获取cv2.waitKey()
的最后 8 位;
(2)ord('c')
返回 q 字符对应的 8 位 ASCII 值;- 实现按下
q
键退出程序的功能;- 释放所有内容;
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)
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()