Python + 读取 / 写入视频

读取并播放视频

这篇教学会介绍OpenCV 里的VideoCapture() 方法,透过这个方法,读取电脑中的视频,或开启电脑的摄影镜头读取视频画面。

因为程式中的OpenCV 会需要使用镜头或GPU,所以请使用本机环境( 参考:使用Python 虚拟环境) 或使用Anaconda Jupyter 进行实作( 参考:使用Anaconda ) ,并安装OpenCV 函式库( 参考:OpenCV函式库)。

VideoCapture() 开启视频

使用VideoCapture() 方法时,如果参数指定「视频路径」,可以开启电脑中的视频,如果参数指定「0、1、2...」数字,则会开启电脑的摄影镜头读取影像画面,数字代表镜头的编号,通常都从0 开始,如果有外接镜头可能会是1、2 之类的编号。

cap = cv2.VideoCapture(0)         # 读取摄影镜头
cap = cv2.VideoCapture('视频路径') # 读取电脑中的视频

如果有遇到错误讯息( 特别是Windows ),可以尝试加入第二个cv2.CAP_DSHOW 参数( 表示DirectShow,也就是目前系统)。

cv2.CAP_DSHOW 是DirectShow,内容是一个「数值」,使用后等同输入700,第二个参数详细可以参考:Flags for video I/O

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

使用VideoCapture() 之后,通常会再透过cap.isOpened() 来判断视频是否正常开启,如果正常开启会回传True,否则是False,下方的程式码执行后,会读取电脑摄影镜头,如果没有读取到镜头资讯,就会印出Cannot open camera 的文字。

import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()

顺利开起视频后,就能使用cap.read() 的方法,读取视频的每一帧( 例如60fps 表示一秒钟有六十帧),读取后会回传两个值,第一个值ret 为True 或False,表示顺利读取或读取错误,第二个值表示读取到视频某一帧的画面,如果读取成功,就能透过imshow() 的方法,将该帧的画面显示出来,下方的程式码除了显示图片,更搭配waitKey(1) 方法,就能不断更新显示的图片,看起来就像播放视频一般。

使用waitKey(1) 表示每一毫秒更新一次画面,参数数值设定越大,图片更新时间就会越长,视频看起来就会出现延迟的状况,参考:waitKey() 等待多久关闭

import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    ret, frame = cap.read()             # 读取视频的每一帧
    if not ret:
        print("Cannot receive frame")   # 如果读取错误,印出讯息
        break
    cv2.imshow('oxxostudio', frame)     # 如果读取成功,显示该帧的画面
    if cv2.waitKey(1) == ord('q'):      # 每一毫秒更新一次,直到按下 q 结束
        break
cap.release()                           # 所有作业都完成后,释放资源
cv2.destroyAllWindows()                 # 结束所有视窗

搭配cvtColor() 改变视频色彩

cvtColor() 方法可以改变图片的色彩,如果将视频每一帧的图片套用cvtColor(),最后就会呈现的改变颜色的视频,下面的程式码执行后,就会读取电脑摄影机,并将彩色视频转换成黑白色彩的视频。

import cv2
cap = cv2.VideoCapture(0)
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)  # 转换成灰阶
    # gray = cv2.cvtColor(frame, 6)  # 也可以用数字对照 6 表示转换成灰阶
    cv2.imshow('oxxostudio', gray)
    if cv2.waitKey(1) == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

读取串流图片MJPEG ( Motion JPEG ) 使用cap.read() 不仅能读取电脑摄影机画面,也可以读取MJPEG ( Motion JPEG ) 的图片串流格式,Motion JPEG ( Motion Joint Photographic Experts Group、M-JPEG ) 是一种影像压缩格式,每一个视讯框图像分别使用JPEG 编码,常用在网路摄影机、物联网摄影机之类的装置。 下方的范例读取交通部的「CCTV 开放资料集」所提供的「国道监视器影像」,读取后就能开启OpenCV 视窗并即时监看特定影像。

import cv2
cap = cv2.VideoCapture('https://cctvn.freeway.gov.tw/abs2mjpg/bmjpg?camera=15771')

if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    ret, frame = cap.read()             # 读取视频的每一帧
    if not ret:
        print("Cannot receive frame")   # 如果读取错误,印出讯息
        # 出现错误就再读取一次,避免程式到此处就停止
        cap = cv2.VideoCapture('https://cctvn.freeway.gov.tw/abs2mjpg/bmjpg?camera=15771')
        continue
    cv2.imshow('oxxostudio', frame)     # 如果读取成功,显示该帧的画面
    if cv2.waitKey(1) == ord('q'):      # 每一毫秒更新一次,直到按下 q 结束
        break
cap.release()                           # 所有作业都完成后,释放资源
cv2.destroyAllWindows()                 # 结束所有视窗

写入并储存视频

这篇教学会介绍OpenCV 里的VideoWriter() 方法,透过这个方法,可以将读取到的视频( 电脑中的视频或摄影镜头拍摄的视频),进行转档或转换色彩,储存成新的视频档。

因为程式中的OpenCV 会需要使用镜头或GPU,所以请使用本机环境( 参考:使用Python 虚拟环境) 或使用Anaconda Jupyter 进行实作( 参考:使用Anaconda ) ,并安装OpenCV 函式库( 参考:OpenCV函式库)。

使用VideoWriter() 储存视频

使用VideoWriter() 方法,可以建立一个空的「视频档」,将撷取到的影像图片组成新的串流格式,写入空的视频档案里,完成后就会储存成新为新的视频。

  • 使用cv2.VideoCapture() 读取电脑摄影机镜头影像。
  • 读取影像后使用cap.get() 方法取得视频长宽尺寸。
  • 使用cv2.VideoWriter_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(),最后就会呈现的改变颜色的视频,下面的程式码执行后,就会读取电脑摄影机,并将彩色视频转换成黑白色彩的影片,最后储存为黑白的视频。

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() 方法取得视频属性,下方列出该方法可取得的属性,以及对应的数字编号:

数字属性说明
0CAP_PROP_POS_MSEC视频目前播放的毫秒数。
1CAP_PROP_POS_FRAMES从0 开始的被截取或解码的帧的索引值。
2CAP_PROP_POS_AVI_RATIO视频播放的相对位置,0 表示开始,1 表示结束。
3CAP_PROP_FRAME_WIDTH视频宽度。
4CAP_PROP_FRAME_HEIGHT视频高度。
5CAP_PROP_FPS视频帧率fps。
6CAP_PROP_FOURCC编解码的的四个字元。
7CAP_PROP_FRAME_COUNT视频总共有几帧。
8CAP_PROP_FORMAT视频格式。
9CAP_PROP_MODE 模式目前的截取模式。
10CAP_PROP_BRIGHTNESS 亮度摄影机亮度。
11CAP_PROP_CONTRAST摄影机对比度。
12CAP_PROP_SATURATION摄影机饱和度。
十三CV.CAP_PROP_HUE摄影机HUE 色调数值。
14CAP_PROP_GAIN摄影机图像增益数值。
15CAP_PROP_EXPOSURE摄影机曝光度。
16CAP_PROP_CONVERT_RGB 复制代码视频是否有转换为RGB。

Python 中,可以使用 `multiprocessing` 模块来实现多进程读写文件。 以下是一个示例代码,其中有两个进程,一个进程用于写入数据到文件中,另一个进程用于读取文件中的数据: ```python import multiprocessing # 写入数据到文件的进程 def write_data(filename, data_queue): with open(filename, "w") as f: while True: data = data_queue.get() if data == "STOP": break f.write(data + "\n") # 读取数据从文件的进程 def read_data(filename, data_queue): with open(filename, "r") as f: for line in f: data_queue.put(line.strip()) if __name__ == "__main__": # 创建一个进程共享队列 data_queue = multiprocessing.Queue() # 创建写入文件的进程 write_process = multiprocessing.Process(target=write_data, args=("data.txt", data_queue)) # 创建读取文件的进程 read_process = multiprocessing.Process(target=read_data, args=("data.txt", data_queue)) # 启动进程 write_process.start() read_process.start() # 等待写入进程完成 write_process.join() # 停止读取进程 data_queue.put("STOP") ``` 在这个例子中,我们创建了一个共享队列 `data_queue`,写入进程将数据写入这个队列,读取进程从这个队列中读取数据。 需要注意的是,在写入进程中,我们需要将数据写入文件中并且添加一个换行符,而在读取进程中,我们需要使用 `strip()` 方法来去掉读取的每一行数据的换行符。此外,在写入进程完成后,我们向队列中添加一个 `STOP` 标记来停止读取进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值