写入并储存影片
这篇教学会介绍 OpenCV 里的 VideoWriter() 方法,透过这个方法,可以将读取到的影片 ( 电脑中的影片或摄影镜头拍摄的影片 ),进行转档或转换色彩,储存成新的影片档。
因为程序中的 OpenCV 会需要使用镜头或 GPU,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda ) ,并安装 OpenCV 函数库 ( 参考:OpenCV 函数库 )。
使用 VideoWriter() 储存影片
使用 VideoWriter() 方法,可以建立一个空的“影片档”,将截取到的图像图片组成新的串流格式,写入空的影片文件里,完成后就会储存成新为新的影片,范例延伸“读取并播放影片”的程序码,进行下列的修改:
- 使用 cv2.VideoCapture() 读取电脑摄影机镜头图像。
- 读取图像后使用 cap.get() 方法取得影片长宽尺寸 ( 参考:get 方法可取得的影片属性 )。
- 使用 cv2.VideoWriter_fourcc() 方法设定储存的影片格式 ( 参考:FOURCC )。
- 使用 cv2.VideoWriter() 产生空的影片文件 ( 设定格式、帧率 fps、长宽 )。
- 在 while 循环里使用 out.write() 方法,将取得的图片写入每一帧。
- 结束后使用 out.release() 释放资源。
import cv2
cap = cv2.VideoCapture(0) # 讀取電腦攝影機鏡頭影像。
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # 取得影像寬度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 取得影像高度
fourcc = cv2.VideoWriter_fourcc(*'MJPG') # 設定影片的格式為 MJPG
out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (width, height)) # 產生空的影片
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
out.write(frame) # 將取得的每一幀圖像寫入空的影片
cv2.imshow('oxxostudio', frame)
if cv2.waitKey(1) == ord('q'):
break # 按下 q 鍵停止
cap.release()
out.release() # 釋放資源
cv2.destroyAllWindows()
解决无法储存影片的问题
实作过程中,可能会遇到“无法储存影片”的状况,通常的解决方法有下面三种:
- 修改 fourcc 的影片格式,如果是 mov 或 mp4 的影片档,使用“*'mp4v'”、“*'MJPG'”或“'M','J','P','G'”( 星号改半形 )。
- 将输入影片的长宽和输入的长宽度调整为“相同的长宽”。
- 修改影片的档名,加上 01、02、03...等数字。
搭配 cvtColor() 储存为黑白的影片
使用 cvtColor() 方法可以改变图片的色彩,如果将影片每一帧的图片套用 cvtColor(),最后就会呈现的改变颜色的影片,下面的程序码执行后,就会读取电脑摄影机,并将彩色影片转换成黑白色彩的影片,最后储存为黑白的影片。
色彩模式参考:cvtColor() 颜色转换名称与数字对照
import cv2
cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.mov', fourcc, 20.0, (width, height))
# 如果轉換成黑白影片後如果無法開啟,請加上 isColor=False 參數設定
# out = cv2.VideoWriter('output.mov', fourcc, 20.0, (width, height), isColor=False)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 轉換成灰階
out.write(gray)
cv2.imshow('oxxostudio', gray)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
get 方法可取得的影片属性
上述的范例程序码中,使用了 cap.get() 方法取得影片属性,下方列出该方法可取得的属性,以及对应的数字编号:
| 数字 | 属性 | 说明 |
|---|---|---|
| 0 | cv.CAP_PROP_POS_MSEC | 影片目前播放的毫秒数。 |
| 1 | cv.CAP_PROP_POS_FRAMES | 从 0 开始的被截取或解码的帧的索引值。 |
| 2 | cv.CAP_PROP_POS_AVI_RATIO | 影片播放的相对位置,0 表示开始,1 表示结束。 |
| 3 | cv.CAP_PROP_FRAME_WIDTH | 影片宽度。 |
| 4 | cv.CAP_PROP_FRAME_HEIGHT | 影片高度。 |
| 5 | cv.CAP_PROP_FPS | 影片帧率 fps。 |
| 6 | cv.CAP_PROP_FOURCC | 编解码的的四个字元。 |
| 7 | cv.CAP_PROP_FRAME_COUNT | 影片总共有几帧。 |
| 8 | cv.CAP_PROP_FORMAT | 影片格式。 |
| 9 | cv.CAP_PROP_MODE | 目前的截取模式。 |
| 10 | cv.CAP_PROP_BRIGHTNESS | 摄影机亮度。 |
| 11 | cv.CAP_PROP_CONTRAST | 摄影机对比度。 |
| 12 | cv.CAP_PROP_SATURATION | 摄影机饱和度。 |
| 13 | cv.CAP_PROP_HUE | 摄影机 HUE 色调数值。 |
| 14 | cv.CAP_PROP_GAIN | 摄影机图像增益数值。 |
| 15 | cv.CAP_PROP_EXPOSURE | 摄影机曝光度。 |
| 16 | cv.CAP_PROP_CONVERT_RGB | 影片是否有转换为 RGB。 |
参考数据
- OpenCV:Getting Started with Videos
微信扫码关注
抖音扫码关注