一、图像处理工作流
通常,我们需要将图像的输入和输出地址作为输入,然后读取、处理和写入图像。首先,需要将图像作为输入,必需的参数是Input_path_image和Output_image_path,即要加载的图像的路径和图像输出的路径。然后通过cv2.imread()和cv2.imwrite()函数读取和写入图像。
import argparse
import cv2
# 创建一个ArgumentParser对象,用于解析命令行参数
parser = argparse.ArgumentParser()
# 指定一个参数 Path_image
parser.add_argument("-Input_image_path", help="Path of input image")
parser.add_argument("-Output_image_path", help="Path of output image")
# 解析命令行参数,并将解析结果存储在args变量中
args = parser.parse_args()
# 读取输入图片
input_image = cv2.imread(args.Input_image_path)
cv2.imshow("Input image", input_image)
cv2.waitKey(0)
# 处理输入图片
gray_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY) # 色彩转换函数
cv2.imshow("Output image", gray_image)
cv2.waitKey(0)
# 打印输出图片
cv2.imwrite(args.Output_image_path, gray_image)
二、处理相机画面
2.1 读取相机画面
首先,我们先创建一个cv2.VideoCapture()对象。参数是视频文件路径,如果参数为0,则表示打开内置摄像头;如果参数为1,则表示打开外接摄像头。
videocapture = cv2.VideoCapture(0)
然后,我们可以通过read()函数来按帧读取视频。其中,success和frame是两个返回值。其中success是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False;frame就是每一帧的图像,是个三维矩阵。
success, frame = videocapture.read()
然后,我们可以对读取到的每一帧的图像进行处理,例如显示当前画面、获取灰度图等。另外,可以通过检测按键输入的方式来退出显示。
import cv2
# 使用自带摄像头
Video_Capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 检测摄像头是否成功打开
if Video_Capture.isOpened() is False:
print("Error to open the camera")
Video_Capture.open(0) # 无法打开摄像头时使用
while Video_Capture.isOpened():
# 逐帧获取图像
success, frame = Video_Capture.read()
if success is True:
cv2.imshow("Camera_0", frame)
# 将相机里获取的图像转为灰度图像
Camera_0_Gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("Camera_0_Gray", Camera_0_Gray)
# 按q退出 ord('q')的作用是提取q的ASCII码
if cv2.waitKey(100) & 0xFF == ord('q'):
break
Video_Capture.release()
cv2.destroyAllWindows()
2.2 读取画面属性
如果我们需要访问Video_Capture对象的某些属性,例如帧宽度、帧高度和每秒帧数(FPS),如果调用不受支持的属性,则返回0。
import cv2
# 使用自带摄像头
Video_Capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 获取Video_Capture的属性
frame_width = Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = Video_Capture.get(cv2.CAP_PROP_FPS)
另外,如果我们需要保存某一帧的画面,我们也可以通过检测按键输入的方式来保存。
# 按s保存当前帧 ord('s')的作用是提取q的ASCII码
if cv2.waitKey(100) & 0xFF == ord("s"):
time_stamp = int(time.time())
cv2.imwrite("save_image_{}.png".format(time_stamp), frame)
完整代码:
import cv2
import time
# 使用自带摄像头
Video_Capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 获取Video_Capture的属性
frame_width = Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = Video_Capture.get(cv2.CAP_PROP_FPS)
print("frame_width:{}".format(frame_width))
print("frame_height:{}".format(frame_height))
print("fps:{}".format(fps))
# 检测摄像头是否成功打开
if Video_Capture.isOpened() is False:
print("Error to open the camera")
Video_Capture.open(0) # 无法打开摄像头时使用
while Video_Capture.isOpened():
# 逐帧获取图像
success, frame = Video_Capture.read()
if success is True:
cv2.imshow("Camera_0", frame)
# 将相机里获取的图像转为灰度图像
Camera_0_Gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("Camera_0_Gray", Camera_0_Gray)
# 按s保存当前帧 ord('s')的作用是提取q的ASCII码
if cv2.waitKey(100) & 0xFF == ord("s"):
time_stamp = int(time.time())
cv2.imwrite("save_image_{}.png".format(time_stamp), frame)
# 按q退出 ord('q')的作用是提取q的ASCII码
if cv2.waitKey(100) & 0xFF == ord('q'):
break
Video_Capture.release()
cv2.destroyAllWindows()
三、 处理视频文件
3.1读取视频文件
cv2.VideoCapture()对象也可以用于读取视频文件,要读取视频文件,应在创建 cv2.VideoCapture() 对象时提供视频文件的路径。
import cv2
# 解析视频地址
Video_Capture = cv2.VideoCapture("luoshengmen.mp4")
if Video_Capture.isOpened() is False:
print("Error to open the video")
while Video_Capture.isOpened():
# 逐帧读取视频画面
success, frame = Video_Capture.read()
if success is True:
cv2.imshow("luoshengmen", frame)
if cv2.waitKey(100) & 0xFF == ord("q"):
break
Video_Capture.release()
cv2.destroyAllWindows()
3.2 保存视频文件
VideoWriter(filename, fourcc, fps, framesize, iscolor)
filename:保存文件的路径
fourcc:指定编码器
fps:保存的视频的帧率
framesize:保存的视频的画面尺寸
iscolor:指示是黑白画面还是彩色画面
import cv2
Video_Capture = cv2.VideoCapture(0)
frame_width = Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = Video_Capture.get(cv2.CAP_PROP_FPS)
# 视频编码器
fourcc = cv2.VideoWriter_fourcc(*"XVID") # avi格式
# fourcc = cv2.VideoWriter_fourcc(*"mp4v") # MP4格式
# 创建VideoWriter对象,用于将帧写入到输出视频文件中
output_video = cv2.VideoWriter("output_video.avi", fourcc, int(fps), (int(frame_width), int(frame_height)), True)
while Video_Capture.isOpened():
success, frame = Video_Capture.read()
if success:
# 保存一帧
output_video.write(frame)
cv2.imshow("output_video", frame)
if cv2.waitKey(20) & 0xFF == ord("q"):
break
3.3 读取视频属性
以下方式(get函数)可以获取主要的视频属性。
print("视频当前帧:{}".format(Video_Capture.get(cv2.CAP_PROP_POS_FRAMES)))
print("视频当前帧时间戳:{}".format(Video_Capture.get(cv2.CAP_PROP_POS_MSEC)))
print("FPS:{}".format(Video_Capture.get(cv2.CAP_PROP_FPS)))
print("视频帧宽度:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)))
print("视频帧高度:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print("视频帧总数:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_COUNT)))
可以通过设定视频属性(set函数),来实现一些功能,例如视频倒放。
import cv2
# 解析视频地址
Video_Capture = cv2.VideoCapture("luoshengmen.mp4")
# 获取视频总帧数
frame_index = Video_Capture.get(cv2.CAP_PROP_FRAME_COUNT)-1
if Video_Capture.isOpened() is False:
print("Error to open the video")
while Video_Capture.isOpened() and frame_index >= 0:
# 设定视频当前帧数为frame_index
Video_Capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
# print("视频当前帧:{}".format(Video_Capture.get(cv2.CAP_PROP_POS_FRAMES)))
# print("视频当前帧时间戳:{}".format(Video_Capture.get(cv2.CAP_PROP_POS_MSEC)))
# print("FPS:{}".format(Video_Capture.get(cv2.CAP_PROP_FPS)))
# print("视频帧宽度:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)))
# print("视频帧高度:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# print("视频帧总数:{}".format(Video_Capture.get(cv2.CAP_PROP_FRAME_COUNT)))
success, frame = Video_Capture.read()
if success:
cv2.imshow("video", frame)
if cv2.waitKey(20) & 0xFF == ord("q"):
break
frame_index -= 1
Video_Capture.release()
cv2.destroyAllWindows()
3.4 保存倒放视频
综合上述内容,可以实现倒放视频并将视频内容保存。
import cv2
def decode_fourcc(fourcc):
fourcc_int = int(fourcc)
fourcc_decode = ""
for i in range(4):
int_value = fourcc_int >> 8 * i & 0xFF
fourcc_decode += chr(int_value)
return fourcc_decode
# 创建一个视频捕获对象, 用于从指定的视频文件中读取视频帧。
Video_Capture = cv2.VideoCapture("罗生门.mp4")
# 获取视频总帧数
frame_index = Video_Capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1
# 获取视频的基本属性
frame_width = Video_Capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = Video_Capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = Video_Capture.get(cv2.CAP_PROP_FPS)
# 获取并解码fourcc
fourcc = cv2.VideoWriter_fourcc(*decode_fourcc(Video_Capture.get(cv2.CAP_PROP_FOURCC)))
output_video = cv2.VideoWriter("罗生门_倒放.mp4", fourcc, int(fps), (int(frame_width), int(frame_height)), True)
if Video_Capture.isOpened() is False:
print("Error opening the video")
while Video_Capture.isOpened() and frame_index >= 0:
# 视频从最后一帧开始放
Video_Capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
success, frame = Video_Capture.read()
if success:
cv2.imshow("罗生门倒放", frame)
output_video.write(frame)
if cv2.waitKey(20) & 0xFF == ord("q"):
break
# 往前一帧
frame_index -= 1
Video_Capture.release()
output_video.release()
cv2.destroyAllWindows()