scikit-video 是一个python视频处理库,使用它可以方便地对视频进行处理。
读写视频
skvideo.io 是使用FFmpeg/LibAV作为后端的视频读写模块。利用可用的后端,它会用合适的探测工具 (ffprobe, avprobe, or even mediainfo)来解析视频的元数据。
1. 读视频
使用skvideo.io.vread来将任意视频数据作为一个单独的ndarry加载入内存。注意,这个函数假定你有足够大的内存,所有尽量使用小的视频。
import skvideo.io
import skvideo.datasets
videodata = skvideo.io.vread(skvideo.datasets.bigbuckbunny())
print(videodata.shape)
使用skvideo.io.vreader可以逐帧加载任意视频。这个函数可以用来加载大文件,而且它通常比把视频加载为一个单独的ndarry要快,但是它需要在加载时处理每一帧。
import skvideo.io
import skvideo.datasets
videogen = skvideo.io.vreader(skvideo.datasets.bigbuckbunny())
for frame in videogen:
print(frame.shape)
有时特定的用例需要微调(fine tuning)FFmpeg的读入参数。你可以使用skvideo.io.FFmpegReader
import skvideo.io
import skvideo.datasets
# here you can set keys and values for parameters in ffmpeg
inputparameters = {}
outputparameters = {}
reader = skvideo.io.FFmpegReader(skvideo.datasets.bigbuckbunny(),
inputdict=inputparameters,
outputdict=outputparameters)
# iterate through the frames
accumulation = 0
for frame in reader.nextFrame():
# do something with the ndarray frame
accumulation += np.sum(frame)
例如, FFmpegReader默认返回的是RGB类型,但是有时你想使用其他颜色空间,你可以在outputparameters中设置合适的 key/values值。因为FFmpeg输出被导入stdin,你可以在这使用所有的FFmpeg 指令。inputparameters对那些没有头信息的原始视频信号很有用。
2. 写视频
将一个ndarry写为视频文件可以使用skvideo.io.write
import skvideo.io
import numpy as np
outputdata = np.random.random(size=(5, 480, 680, 3)) * 255
outputdata = outputdata.astype(np.uint8)
skvideo.io.vwrite("outputvideo.mp4", outputdata)
通常写入视频需要微调 FFmpeg的写入参数以选择编码器、帧率、位率等。你可以使用skvideo.io.FFmpegWriter实现这些。
import skvideo.io
import numpy as np
outputdata = np.random.random(size=(5, 480, 680, 3)) * 255
outputdata = outputdata.astype(np.uint8)
writer = skvideo.io.FFmpegWriter("outputvideo.mp4")
for i in xrange(5):
writer.writeFrame(outputdata[i, :, :, :])
writer.close()
视频元信息
使用skvideo.io.ffprobe读取视频元信息。
import skvideo.io
import skvideo.datasets
import json
metadata = skvideo.io.ffprobe(skvideo.datasets.bigbuckbunny())
print(metadata.keys())
print(json.dumps(metadata["video"], indent=4))
运动
import skvideo.io
import skvideo.motion
import skvideo.datasets
videodata = skvideo.io.vread(skvideo.datasets.bigbuckbunny(),num_frames=5)
motion = skvideo.motion.blockMotion(videodata)
print(videodata.shape)
print(motion.shape)
# compensate the video
compensate = skvideo.motion.blockComp(videodata, motion)
# write
skvideo.io.vwrite("compensate.mp4", compensate)
测量
import skvideo.io
import skvideo.motion
import skvideo.datasets
import skvideo.measure
# compute vectors from bigbuckbunny
videodata = skvideo.io.vread(skvideo.datasets.bigbuckbunny(),num_frames=5,as_grey=True)
# videodata = skvideo.io.vread(skvideo.datasets.bigbuckbunny())
# skvideo.io.vwrite("origin.mp4", videodata)
motion = skvideo.motion.blockMotion(videodata)
print(videodata.shape)
print(motion.shape)
# compensate the video
compensate = skvideo.motion.blockComp(videodata, motion)
# write
skvideo.io.vwrite("compensate.mp4", compensate)
print(skvideo.measure.ssim(videodata,compensate))
print(skvideo.measure.psnr(videodata,compensate))
print(skvideo.measure.mse(videodata,compensate))
读写图片
import skvideo.io
# a frame from the bigbuckbunny sequence
vid = skvideo.io.vread('/home/shuai/python_test/output.png')
T, M, N, C = vid.shape
print("Number of frames: %d" % (T,))
print("Number of rows: %d" % (M,))
print("Number of cols: %d" % (N,))
print("Number of channels: %d" % (C,))
# upsacle by a factor of 2
vid = skvideo.io.vread('/home/shuai/python_test/output.png',
outputdict={
"-sws_flags":"bilinear",
"-s":"2560x1440"
})
T, M, N, C = vid.shape
print("Number of frames: %d" % (T,))
print("Number of rows: %d" % (M,))
print("Number of cols: %d" % (N,))
print("Number of channels: %d" % (C,))
skvideo.io.vwrite("outputplus.png", vid)