【nv12 格式转换】不同图像数据格式之间转换代码实操

news/2024/12/5 6:38:27/

文章目录

  • 1 问题先行
  • 2 nv12介绍
    • 2.1 YUV格式
    • 2.2 NV12排布
  • 3 不同数据格式之间转换实操
  • 4 参考链接

1 问题先行

  1. nv12是什么格式?和常见的rgb/bgr有什么关系吗?他们之间能互相转换吗?
  2. 如何读取一张图片,然后把图片转换成nv12格式?有代码嘛?
  3. 部署时,为何要用nv12数据格式作为输入?rgb不行吗?

2 nv12介绍

2.1 YUV格式

YUV格式主要用于优化彩色视频信号的传输。
YUV分为三个分量:Y表示明亮度,也就是灰度值;U和V表示色度,用于描述影像色彩及饱和度,指定像素的颜色。

2.2 NV12排布

NV12图像格式属于YUV颜色空间中的YUV420SP格式,每四个Y分量共用一组U分量和V分量,Y连续排序,U与V交叉排序。

排列方式如下:
在这里插入图片描述

3 不同数据格式之间转换实操

读取一张图片,从bgr转成nv12,再从nv12转成yuv44,具体内容看看代码和输出即可。

import cv2 
import numpy as np 
from PIL import Image # -------------------------------------------------------#
# 注意: image.shape = (h, w, c)
# nv12数据与YUV_I420的uv分量排列方式不同,具体可参考本文第2章节描述
# -------------------------------------------------------#
def bgr2nv12(image): image = image.astype(np.uint8) height, width = image.shape[0], image.shape[1] yuv420p = cv2.cvtColor(image, cv2.COLOR_BGR2YUV_I420).reshape((height * width * 3 // 2, )) y = yuv420p[:height * width] uv_planar = yuv420p[height * width:].reshape((2, height * width // 4)) uv_packed = uv_planar.transpose((1, 0)).reshape((height * width // 2, )) nv12 = np.zeros_like(yuv420p) nv12[:height * width] = y nv12[height * width:] = uv_packed return nv12# nv12转yuv444
def nv12Toyuv444(nv12, target_size):height = target_size[0] width = target_size[1] nv12_data = nv12.flatten() yuv444 = np.empty([height, width, 3], dtype=np.uint8) yuv444[:, :, 0] = nv12_data[:width * height].reshape(height, width) u = nv12_data[width * height::2].reshape(height // 2, width // 2) yuv444[:, :, 1] = Image.fromarray(u).resize((width, height),resample=0) v = nv12_data[width * height + 1::2].reshape(height // 2, width // 2) yuv444[:, :, 2] = Image.fromarray(v).resize((width, height),resample=0) return yuv444if __name__=='__main__': img = cv2.imread("./zebra_cls.jpg")     # bgr  hwcprint("cv2读图shape:", img.shape)# 直接resize,其它缩放图片方式个性化使用 img = cv2.resize(img,(672,672))         # bgr  hwcprint("resize后的图片shape:", img.shape)# 将bgr的数据格式转换成nv12的数据格式# 注意上方转换函数写的时候,输入img需要是(h, w, c)的layout排布nv12 = bgr2nv12(img)# 677376=672x672x3/2,这儿为什么除以2,参考本文第1章理解理解~print("nv12的shape:", nv12.shape)# 将nv12的数据保存下来供给模型,作为真实输入nv12.tofile("nv12_input_data.bin")# nv12转yuv444img = nv12Toyuv444(nv12, (672,672))print("yuv444的shape:", img.shape)# 变换数据排布layoutimg = img.transpose(2,0,1) print("yuv444 transpose之后的shape:", img.shape)# 增加一个N维度img = img[np.newaxis,:,:,:] print("增加一个N维度的shape:",img.shape)

输出

cv2读图shape: (376, 376, 3)
resize后的图片shape: (672, 672, 3)
nv12的shape: (677376,)# 677376=672x672x3/2,为什么除以2,参考本文第2章理解理解~
yuv444的shape: (672, 672, 3)
yuv444 transpose之后的shape: (3, 672, 672)
增加一个N维度的shape: (1, 3, 672, 672)

:部分代码有参考地平线OE包中的内容。

之所以用nv12作为部署时的数据输入,是因为其数据量是rgb/bgr等格式的一半,减少模型load输入数据的时间。

4 参考链接

1. https://developer.horizon.ai/forumDetail/118364000835765839

http://www.ppmy.cn/news/20972.html

相关文章

【C++】IO流

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉C语言的输…

【Linux】gdb调试器

【Linux】gdb调试器 文章目录【Linux】gdb调试器1、调试器的意义2、gdb调试器介绍2.1 gdb的作用2.2 gdb的配置3、gdb调试器的使用3.1 常用调试命令3.2 调试前准备3.3 指令演示3.3.1 断点3.3.2 逐过程、逐语句3.3.3 查询变量3.3.4 跳转3.3.5 结束函数、跳出执行3.3.4 跳转3.3.5 …

leetcode 1626. Best Team With No Conflicts(最佳无冲突团队)

scores数组中是每个队员的得分,ages数组中为对应队员的年龄, 现在要从这个队里挑选出一些队员,使总得分最高, 挑选时年龄大的要比年龄小的score更高(严格大于),才不会产生冲突。 返回最高的得分…

python小游戏——怀念经典坦克大战代码

♥️作者:小刘在这里 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的,绽放,愿所有的美好&#…

Python流程控制语句之跳转语句

上一篇:Python流程控制语句之循环语句 文章目录前言一、break 语句二、continue 语句三、pass 空语句总结前言 上一篇博客我们讲解了Python中的循环语句,知道循环条件一直满足时,代码将会一直执行下去,就像一辆迷路的车&#xff…

【flyway入门及使用】解决生产环境sql更新遗漏

flyway入门及使用 一、简单介绍 flyway开源的数据库版本管理工具 二、为什么要使用flyway 1.自己写的sql没有在全部环境执行 2.别人写的sql没有在全部环境执行 3.有人修改了已经执行过的SQL,期望再次执行 4.需要新增环境做数据迁移 三、flyway是如何工作 1…

国内在线图表工具,你能说出几个?

之前写过很多篇在线图表、数据分析处理类工具的内容,但都是针对单个问题写的,没有将其整合起来,今天就借着这个问题,做个国内在线图表工具的合集。 一共5大类,每一类各介绍一个代表性工具,全文较长&#x…

can‘t be used as a mixin because it extends a class other than ‘Object‘.

程序员如果敲一会就停半天,抱着一杯茶,表情拧巴,那才是在编程 Flutter 项目开发指导 从基础入门到精通使用目录 前言 - 基础关键字 class:声明一个类,提供具体的成员变量和方法实现。abstract class:声明一…