YUV 8bit转10bit

文章介绍了如何使用ffmpeg和Python进行YUV8位到10位的转换,特别是从P010le格式转换为8位的NV12和YUV420p格式。提供了两个Python脚本,一个用于将P010le转为NV12,另一个将P010le转为YUV420p8bit。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在有些场景中,我们经常会使用到YUV 8 bit转10bit的场景。
比如YUV420p 8bit 转 P010,P010le,YUV420p10le。

首先说ffmpeg 8 bit 转 10bit.
对于ffmpeg的P010le 和P010be 分别代表小端和大端,那么它转化的时候非常简单,就是8 bit再增加 8bit,后面的8bit全为0.
比如:
在这里插入图片描述

这是最简单的一种办法,所以如果你有一个转换后的10bitYUV,那么只要简单的去掉这个全为0的byte就可以了。
补充说明:
P010le和P010be 排列方式和NV12一样,是YYYY… UVUVUVUVUVU…
下面是一个简单python代码,将10bit P010le转换为8bit nv12:

import cv2 as cv
import numpy as np
import os

W = 1920
H = 1080

num=5
Y_planar = W*H*2
UV_planar = W*H

# p010 2 nv12
root = os.path.split(os.path.realpath(__file__))[0]
name = root + "\\dev-0-session-0-test10-p010.yuv"
fp = open(name, "rb")
fp2 = open(name+"-out.yuv","wb+")



for i in range(num):
    Y = fp.read(Y_planar)
    U = fp.read(UV_planar)

    Y = [int(x) for x in Y]
    U = [int(x) for x in U]

    YY = np.zeros(shape=(W*H), dtype='uint8', order='C')
    UV = np.zeros(shape=(int((W*H)/2)), dtype='uint8', order='C')

    for i in range(int(W*H-2)):
        YY[i]=Y[2*i + 1]
	# 单纯的把0x00抛弃掉
    for i in range(int((W*H-4)/4)):
        UV[2*i+0] = U[4*i+1]
        UV[2*i+1] = U[4*i+3]
    
    fp2.write(bytes(YY))
    fp2.write(bytes(UV))


fp.close()
fp2.close()

除了这种简单的增加一个字节的方式外,其实还有另外一种方式:
在这里插入图片描述

ffmpeg中的yuv420p10le就是这种方式。
燧远的y10,P010le就是这种方式。
下面一个脚本,可以将P010le的转为YUV420 8bit

import cv2 as cv
import numpy as np
import os

W = 1920
H = 1080

num=5
Y_planar = W*H*2
UV_planar = W*H

# p010 2 nv12
root = os.path.split(os.path.realpath(__file__))[0]
name = root + "\\dev-0-session-0-test10-p010le.yuv"
fp = open(name, "rb")
fp2 = open(name+"-out-yuv420p8bit.yuv","wb+")

y1 = np.zeros(shape=(H, W), dtype=np.uint8, order='C')
u1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')
v1 = np.zeros(shape=(int(H/2), int(W/2)), dtype=np.uint8, order='C')

for i in range(num):
        for m in range(H):
            for n in range(W):
                msb = (ord(fp.read(1))>>2) 
                lsb = (ord(fp.read(1))<<6)
                y1[m,n] = msb | lsb
                
        for m in range(int(H/2)):
            for n in range(int(W/2)):
                msb = (ord(fp.read(1))>>2) 
                lsb = (ord(fp.read(1))<<6)
                u1[m,n] = msb | lsb

                msb = (ord(fp.read(1))>>2) 
                lsb = (ord(fp.read(1))<<6)
                v1[m,n] = msb | lsb

        fp2.write(bytes(y1))
        fp2.write(bytes(u1))
        fp2.write(bytes(v1))
        


fp.close()
fp2.close()



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值