图像处理基础 | 格式转换.nv12转高质量.jpg灰度图 python
图像格式转换
.nv12 是一种常见的 YUV 4:2:0 图像格式,主要用于视频编码、图像处理和硬件加速的视频解码等应用中。它是 YUV 格式中的一种色度子采样(Chroma Subsampling)格式,通常用于高效的图像和视频数据存储和传输。
在 .nv12 格式中,图像数据被分为两部分:
Y(亮度成分):表示图像的明暗信息。
UV(色度成分):表示图像的色彩信息。
NV12 格式详细结构
1. Y 平面(亮度成分)
Y 平面包含图像的亮度信息,对于每个像素有一个对应的 Y 值。
在 YUV 4:2:0 格式中,Y 分量的分辨率与原始图像相同,即每个像素都有一个亮度值。
2. UV 平面(色度成分)
UV 平面由 U 和 V 分量组成,其中 U 表示蓝色差值,V 表示红色差值。
色度子采样:在 YUV 4:2:0 中,色度分量 U 和 V 的分辨率是亮度分量 Y 的一半(水平和垂直方向各采样一半),因此 UV 平面的尺寸比 Y 平面小一半。
在 .nv12 格式中,U 和 V 分量是交错存储的,即 U 和 V 分量依次排列。例如,UV 平面存储的第一个字节是 U 分量,第二个字节是 V 分量,接着是下一个 U 和 V 分量,以此类推。
3. 存储顺序
.nv12 格式的存储顺序是将 Y 分量(亮度信息)存储在前面,紧接着存储 交错的 UV 分量(色度信息)。
这意味着,数据的布局是:首先是所有的 Y 数据,然后是交错存储的 U 和 V 数据。
假设图像的宽度为 W,高度为 H:
Y 分量:存储的字节数是 W * H,每个像素一个字节。
UV 分量:存储的字节数是 (W // 2) * (H // 2) * 2,每两个像素共享一个 U 和一个 V 分量,因此每个像素占用一个字节,U 和 V 分量交错存储
def nv21_to_gray_jpg(nv21_data, width, height, output_path):
data = np.frombuffer(nv21_data, dtype=np.uint8)
data = np.append(data, values=0)#图片完整时,可以不补充0
img = data.reshape((height + height // 2, width))
yuv_img = np.zeros((height + height // 2, width), dtype=np.uint8)
yuv_img[...] = img
bgr_img = cv2.cvtColor(yuv_img, cv2.COLOR_YUV2BGR_NV12)
gray_image = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
quality = [int(cv2.IMWRITE_JPEG_QUALITY), 100]
cv2.imwrite(output_path, gray_image,quality)
if __name__ == '__main__':
# 假设图像宽度和高度
width = 640
height = 480
output_path = 'output_gray_image.jpg'
# 读取 .rgb 文件
with open('4.nv12', 'rb') as f:
nv21_data = f.read()
nv21_to_gray_jpg(nv21_data,width,height,output_path)