一、本期目标
大家好,这是我们自学 Python OpenCV 的第二天!
今天我们来学习 OpenCV 的视频处理!
阅读本期文章,你将学会:
- 读取视频文件;
- 显示视频;
- 保存视频文件;
- 从摄像头获取并显示视频。
你将学习这些函数:
- cv2.VideoCapture()
- cv2.VideoWrite()
二、用摄像头捕获视频
生活中,我们时长需要获取摄像头画面。OpenCV 为这种应用提供了一个简单的接口。
为了获取视频,你应该创建一个 VideoCapture
对象。
它的参数可以是设备的索引号,或者是一个视频文件。
设备索引号就是在指定要使用的摄像头,一般的笔记本电脑都有内置摄像头,所以参数就是 0。你可以通过设置成 1 或者其他的来选择别的摄像头。
之后,你就可以一帧一帧的捕获视频了。
但是最后,别忘了停止捕获视频。
import cv2
capture = cv2.VideoCapture(0)
while True:
# 逐帧捕获
ret, frame = capture.read()
# 黑白
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 显示结果
cv2.imshow('frame', gray)
# 如果按下q退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 结束捕获并关闭窗口
capture.release()
cv2.destroyAllWindows()
capture.read()
返回一个布尔值(True / False)。如果帧读取的是正确的,那么返回值就是 True。所以最后你可以通过查看它的返回值来判断视频文件是否达到了结尾。
有时候 capture 不会成功初始化摄像头设备,这种情况下,执行上面的代码就会报错。你可以使用 captrue.isOpened()
来检查摄像头设备是否初始化成功。如果返回值是 True,那么就成功了,否则你需要使用函数 capture.open()
来初始化。
你还可以使用函数 capture.get(propId)
来获得视频的一些参数信息。这里 propId
可以是 0 ~ 18 之间的任意整数,每一个数代表视频的一个属性:
整数 | OpenCV | 代表属性 |
---|---|---|
0 | CAP_PROP_POS_MSEC | 视频当前播放位置,毫秒单位 |
1 | CAP_PROP_POS_FRAMES | 基于以0开始的被捕获或解码的帧索引 |
2 | CAP_PROP_POS_AVI_RATIO | 视频文件的相对位置(当前播放位置):0=电影开始,1=电影结尾 |
3 | CAP_PROP_FRAME_WIDTH | 视频流的帧宽度 |
4 | CAP_PROP_FRAME_HEIGHT | 视频流的帧高度 |
5 | CAP_PROP_FPS | 帧速率 |
6 | CAP_PROP_FOURCC | 编解码,字符代码 |
7 | CAP_PROP_FRAME_COUNT | 视频文件的帧数 |
8 | CAP_PROP_FORMAT | 返回对象的格式 |
9 | CAP_PROP_MODE | 返回后端特定值,即当前捕获模式 |
10 | CAP_PROP_CONTRAST | 图像的亮度(适用于相机) |
11 | CAP_PROP_CONTRAST | 图像的对比度(适用于相机) |
12 | CAP_PROP_SATURATION | 图像的饱和度(适用于相机) |
13 | CAP_PROP_HUE | 色调图像(仅适用于相机) |
14 | CAP_PROP_GAIN | 图像增益(仅适用于相机),白平衡 |
15 | CAP_PROP_EXPOSURE | 曝光(仅适用于相机) |
16 | CAP_PROP_CONVERT_RGB | 是否将图像转换为RGB布尔标志 |
17 | CAP_PROP_WHITE_BALANCE_BLUE_U | 暂时不支持 |
18 | CAP_PROP_RECTIFICATION | 立体摄像机的矫正标注,只有DC1394 v.2x后端支持 |
注:
本表转自 CSDN 博主『Qredsun』的原创文章《OpenCV get(propId) 常用的值》。
原文链接:https://blog.csdn.net/qq_17328759/article/details/125379584
英文好的同志可以看这张图:
视频属性的其中的一些值可以使用 capture.set(propId,value)
来修改,value 就是你想要设置成的新值。
例如,我可以使用 captrue.get(3)
和 captrue.get(4)
来查看每一帧的宽和高。默认情况下得到的值是 640X480。但是我可以使用 ret=capture.set(3,320)
和 ret=capture.set(4,240)
来把宽和高改成 320X240。
注意:
当你的程序报错时,你首先应该检查的是你的摄像头是否能够在其他程序中正常工作(比如 linux 下的 Cheese)。
三、从文件中播放视频
与从摄像头中捕获一样,你只需要把设备索引号改成视频文件的名字。
在播放每一帧时,使用 cv2.waiKey()
设置适当的持续时间。如果设置的太低视频就会播放的非常快,如果设置的太高就会播放的很慢(你可以使用这种方法控制视频的播放速度)。通常情况下 25 毫秒就可以了。
import cv2
cap = cv2.VideoCapture('video.mp4') # 导入视频
while True:
ret, frame = cap.read()
if not ret: # 读取失败或播放结束时退出
print("退出播放。")
break
else:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', gray)
if cv2.waitKey(25) & 0xFF == ord('Q'): # 播放中途按下“q”终端播放
print("退出视频播放。")
break
cap.release()
cv2.destroyAllWindows()
注意:
你应该确保你已经装了合适版本的 ffmpeg 或者 gstreamer。如果你装错了那就比较头疼了。
四、保存视频
在我们捕获视频,并对每一帧都进行加工之后,我们会想要保存这个视频。对于图片来时很简单只需要使用 cv2.imwrite()
。但对于视频来说就要多做点工作。
这次我们要创建一个 VideoWriter
的对象。
我们应该确定一个输出文件的名字。接下来指定 FourCC 编码(下面会介绍)。播放频率和帧的大小也都需要确定。最后一个是 isColor
标签。如果是 True,每一帧就是彩色图,否则就是灰度图。
FourCC 就是一个 4 字节码,用来确定视频的编码格式。可用的编码列表可以从 fourcc.org 查到。这是平台依赖的。
- In Fedora: DIVX, XVID, MJPG, X264, WMV1, WMV2. (XVID is
more preferable. MJPG results in high size video. X264 gives
very small size video) - In Windows: DIVX (More to be tested and added)
- In OSX : (I don’t have access to OSX. Can some one fill this?)
FourCC 码以下面的格式传给程序,以 MJPG 为例:
cv2.VideoWriter_fourcc(*"MJPG")
下面的代码是从摄像头中捕获视频,沿水平方向旋转每一帧并保存它。
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter('video.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
ret, frame = cap.read()
if ret == True:
frame = cv2.flip(frame, 0)
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
本期文章到此结束,欢迎大家点赞、收藏哦~