From c0bba8b2a71ebd43511645c00f7b545e120047ab Mon Sep 17 00:00:00 2001 From: "lxbpxylps@126.com" Date: Mon, 16 Aug 2021 20:25:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: DX3906G <3190104610@zju.edu.cn> --- VideoGen.py | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 VideoGen.py diff --git a/VideoGen.py b/VideoGen.py new file mode 100644 index 0000000..afcd7bd --- /dev/null +++ b/VideoGen.py @@ -0,0 +1,90 @@ +import cv2 +import numpy as np +import struct +import sys +import os +import argparse + + +def BGR888_2_RGB565(img): + '''BGR888 转化为 RGB565 + + Arguments: + - img -- 待转化的 numpy 数组 + ''' + + img_B = img[:, :, 0] + img_G = img[:, :, 1] + img_R = img[:, :, 2] + img_RGB565 = ((img_B & 0xF8) >> 3) | ( + (img_G & 0xFC) << 3) | ((img_R & 0xF8) << 8) + return img_RGB565.flatten() + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser( + description='生成供 STM32-Player (https://github.com/StopPointTeam/STM32-Player) 播放的视频') + parser.add_argument('-i', '-input', help='输入视频路径') + arg = vars(parser.parse_args()) + + if os.path.exists(arg['i']) == False: + print('输入视频路径不存在,请检查路径!') + sys.exit(1) + + cap = cv2.VideoCapture(arg['i']) + if cap.isOpened() == False: + print('打开输入视频失败!') + sys.exit(1) + + fps = cap.get(cv2.CAP_PROP_FPS) + frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT) + frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) + frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) + + print('输入视频分辨率:', frame_width, '*', frame_height) + print('输入视频 FPS:', fps) + print('输入视频总帧数:', round(frame_count)) + print('输入视频时长:', round(frame_count / fps, 2), 's') + + if fps > 30: + frame_interval = int(fps / (fps - 30)) + fps = 30 + print('输入视频 FPS 超过 30,将自动转换为 30') + else: + frame_interval = 0 + + frame_seq = 0 # 输入视频帧序号 + new_seq = 0 # 输出视频帧序号 + + # 保存到二进制文件中 + filename = os.path.basename(arg['i']) + '.32v' + file = open(filename, 'wb') + file.seek(153600, os.SEEK_SET) + + while True: + ret, img = cap.read() # 捕获一帧 + if ret == True: + frame_seq += 1 + if (frame_interval == 0 or frame_seq % frame_interval != 0): + new_seq += 1 + + # 变换尺寸,并转化为 uint16 类型 numpy 数组 + img_resized = np.array(cv2.resize( + img, (320, 240))).astype('uint16') + + img_RGB565 = BGR888_2_RGB565(img_resized) # 颜色空间转换 + + fmt = '>' + len(img_RGB565) * 'H' # 格式化字符串,大端模式 + data = struct.pack(fmt, *img_RGB565) # 列表转换为二进制字节流 + + file.write(data) + print('正在处理:第', frame_seq, '/', round(frame_count), '帧,进度:', + round(frame_seq / frame_count * 100, 2), '%') + + else: + # 写入视频信息头 + file.seek(0, os.SEEK_SET) + file.write(struct.pack('