python 读取 10 bit YUV 文件

        最近博主在做HDR2SDR 的项目,在用python做demo的过程中遇到一个问题,输入是HDR的视频(H.265, YUV420P10LE, BT2020, 25fps的MKV文件),由于MKV文件是10bit的,博主直接使用 cv2.VideoCapture() 函数,得到的frame数据只有8bit, 在网上找了好久,都不知道如何使用cv2.VeideoCapture()函数读10bit 的数据,只好使用最笨的办法,此博文用以记录,如果有相同需求的朋友看到这篇文章也可有个借鉴,如果有知道如何直接读取10bit MKV文件的朋友,也麻烦留言告诉一下博主,博主感激不尽。

        MKV是一种视频格式,包含许多封装信息,python要读取YUV420P10LE 格式,那么首先要将MKV文件解码出YUV文件,此处博主使用ffmpeg解码,且只选取其中10s的所有帧。语法如下:

ffmpeg -i inputfile.MKV -ss 00:00:00 -t 10 -s 3840x2160 -pix_fmt yuv420p10le outfile.yuv

        解码得到YUV文件后,可以使用ffplay 播放一下视频:

ffplay -video_size 3840x2160 -pixel_format yuv420p10le -i outfile.yuv

       解码得到单帧YUV语法如下:

ffmpeg -i input.MKV -ss 00:00:00 -f segment -segment_time 0.04 -frames 1 -s 3840x2160 -pix_fmt yuv420p10le %3d.yuv 

         此处博主有个疑惑,用ffplay播放的视频和直接打开MKV播放的视频并不一致,亮度和颜色明显被抑制,博主猜测可能原因是MKV直接使用播放器播放的视频是BT2020 10 bit的,但是ffplay 在播放时,只能播放8bit的视频(内部做了10-8处理),未做验证。

        得到YUV10bit数据,排列方式是按照 YYY...YYY   UUU...UUU   VVV...VVV排放,且每个分量占2个byte. 因此python 代码如下:

input_filename = "outfile.yuv"
pic_width = 3840
pic_height = 2160
frame_number = 250
frame_size = 24883200

fp = open(input_filename , 'rb')
ps = fp.tell()
for i in range(frame_num):
    Yt = np.zeros(shape=(pic_height , pic_width ), dtype=np.uint16, order='C')
    Ut = np.zeros(shape=(pic_height , pic_width ), dtype=np.uint16, order='C')
    Vt = np.zeros(shape=(pic_height , pic_width ), dtype=np.uint16, order='C')
    for m in range(pic_height):
        for n in range(pic_widht):
            Yt[m,n] = ord(fp.read(1))+(ord(fp.read(1))<<8)
    for m in range(0, pic_height, 2):
        for n in range(0, pic_widht-1, 2):
            Ut[m,n] = ord(fp.read(1))+(ord(fp.read(1))<<8)
            Ut[m+1, n] = Ut[m, n+1] = Ut[m+1, n+1] = Ut[m, n]
    for m in range(0, pic_height-1, 2):
       for n in range(0, pic_widht-1, 2):
            Vt[m//2, n//2] = ord(fp.read(1)) + (ord(fp.read(1)) << 8)
            Vt[m + 1, n] = Vt[m, n + 1] = Vt[m + 1, n + 1] = Vt[m, n]
 

        注意,此处我是因为要将YUV再转成RGB格式后再进行处理,因此我在读UV数据时,将图像变成了YUV444模式, 如果仅仅只需要YUV420模式,请自行修改代码。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值