抖音时光倒流原理
抖音的时光倒流原理,应该来说最好理解,也就是将视频倒放。如果你是掌握PR或者AE的用户,那么视频倒放肯定手到擒来。但是,今天我们要做的是使用OpenCV程序实现视频的倒放效果(当然PR与AE底层实现的效果就是这段代码原理)。
下面,我们来一步步掌握视频的整体倒放,以及部分倒放的操作代码。
实现视频整体倒放
先要了解时光倒流的具体实现,我们不妨先实现一个简单的整体倒放。对于整体倒放来说,相对比部分倒放简单,只需要读取视频,然后把每一帧保存,然后倒着遍历写入视频文件保存即可。
具体代码如下所示:
#视频整体倒放
def video_Inverted(videoFileName,outputFileName):
cap = cv2.VideoCapture(videoFileName)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
videoWriter = cv2.VideoWriter(outputFileName+".avi", fourcc, fps, (width, height))
frame_list = []
while (cap.isOpened()):
ret, frame = cap.read()
if ret:
frame_list.append(frame)
c = cv2.waitKey(1)
if c == 27:
break
else:
break
for frame in frame_list[::-1]:
videoWriter.write(frame)
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
video_Inverted("45.mp4","output")
运行之后,我们的视频就会倒放,效果如下:
实现视频部分倒放
视频的部分倒放在抖音以及影视作品中也非常的常见,比如影视中惯用的回忆,然后加快进度等都有倒放的影子。那么如何实现视频的中间部分倒放呢?
答案很简单,我们分为如下2个步骤:
- 首先设置需要倒放视频的帧数起点与终点
- 然后设置三个列表,一个保存不需要倒放的倒放前的帧数图像,一个保存倒放的帧数图像,一个保存不需要倒放的倒放后那段帧数图像。
- 最后,拼接倒放前的图像,倒放的图像,倒放后的图像。这样就完成了视频里面部分视频的倒放。
下面,我们将上面的步骤转换为代码,具体如下:
# 视频的部分倒放
def video_part_Inverted(videoFileName, outputFileName):
cap = cv2.VideoCapture(videoFileName)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
videoWriter = cv2.VideoWriter(outputFileName + ".avi", fourcc, fps, (width, height))
frame_list_start = [] # 倒放前图像列表
frame_list_end = [] # 倒放后图像列表
inverted_list = [] # 需要倒放的图像列表
fps_start = 66# 倒放起始帧
fps_end = 150# 倒放结束帧
i = 0
while (cap.isOpened()):
ret, frame = cap.read()
if ret:
if i >= fps_start and i <= fps_end:
inverted_list.append(frame)
elif i < fps_start:
frame_list_start.append(frame)
elif i > fps_end:
frame_list_end.append(frame)
i += 1
c = cv2.waitKey(1)
if c == 27:
break
else:
break
for frame in frame_list_start:
videoWriter.write(frame)
for frame in inverted_list[::-1]:
videoWriter.write(frame)
for frame in frame_list_end:
videoWriter.write(frame)
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
video_part_Inverted("45.mp4", "output1")
原理已经讲清楚了,相信这段代码很好理解,这里就不在赘述,也不放运行后的图像。感兴趣的读者,可以自己找一段视频测试。