当前位置: 首页 > news >正文

YUV转RGBA的操作

NV12格式

YYYYYYYY

YYYYYYYY

YYYYYYYY

YYYYYYYY

UVUVUVUV

UVUVUVUV

两个平面,UV交错

基本方案

int clamp(int value, int min, int max) {
    if (value < min) {
        return min;
    } else if (value > max) {
        return max;
    } else {
        return value;
    }
}

void NV12_T_RGBA(unsigned char* YUV, unsigned char* rgba, unsigned int width, unsigned int height)
{
    int frameSize = width * height;

    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {
            // Y值
            int Y = YUV[j * width + i];
            // UV值, UV 交错排列,只占总高度的一半
            int U = YUV[frameSize + (j / 2) * width + (i & ~1)];
            int V = YUV[frameSize + (j / 2) * width + (i & ~1) + 1];

            // 转换
            int R = clamp((int)(Y + 1.13983 * (V - 128)), 0, 255);
            int G = clamp((int)(Y - 0.39465 * (U - 128) - 0.5806 * (V - 128)), 0, 255);
            int B = clamp((int)(Y + 2.03211 * (U - 128)), 0, 255);

            // 存储RGBA数据,将Alpha通道设置为0
            rgba[(j * width + i) * 4] = R;
            rgba[(j * width + i) * 4 + 1] = G;
            rgba[(j * width + i) * 4 + 2] = B;
            rgba[(j * width + i) * 4 + 3] = 0;
        }
    }
}

在NV12格式的YUV数据中,UV分量是按照2x2的子采样存储的,这意味着每个UV值对应原始图像中2x2区块的四个像素。这种存储方式导致UV数据的横向分辨率只有Y数据的一半。为了从YUV数据中正确地提取UV分量,我们需要确保我们访问的UV索引对应于其在Y数据中的位置。

这里使用的表达式 i & ~1 用于确定当前像素对应的UV组件的水平位置。下面是这个操作的详细解释:

位运算详解
i:表示当前像素的横坐标。
~1:这是一个位运算符。1 在二进制中表示为 00000001,取反后变为 11111110。
i & ~1:这个运算实际上是将 i 的最低位(二进制的最右边位)清零,从而使得得到的结果总是偶数。这个偶数指向当前2x2块中第一个像素(即左上角)的位置。
例子说明
假设我们有一个宽度为8的图像,对应的行中像素横坐标 i 从0到7。我们使用 i & ~1 来查看结果:

当 i = 0(二进制 000)时,i & ~1 的结果是 0(二进制 000)。
当 i = 1(二进制 001)时,i & ~1 的结果是 0(二进制 000)。
当 i = 2(二进制 010)时,i & ~1 的结果是 2(二进制 010)。
当 i = 3(二进制 011)时,i & ~1 的结果是 2(二进制 010)。
当 i = 4(二进制 100)时,i & ~1 的结果是 4(二进制 100)。
当 i = 5(二进制 101)时,i & ~1 的结果是 4(二进制 100)。
当 i = 6(二进制 110)时,i & ~1 的结果是 6(二进制 110)。
当 i = 7(二进制 111)时,i & ~1 的结果是 6(二进制 110)。
如你看到,对于每两个相邻的 i 值(0和1, 2和3, 4和5, 6和7),i & ~1 都返回相同的偶数值。这样确保了,不管处理的是2x2块中的哪一个像素,我们总是从对应的UV坐标(同一个UV值)提取色差分量,保持了UV分量正确的对应和采样逻辑

不同的转换公式

参考:YUV与RGB转换公式(BT601、BT709、BT2020)_bt601和bt709-CSDN博客

http://www.dtcms.com/a/111977.html

相关文章:

  • 图解AUTOSAR_SWS_LINTransceiverDriver
  • 【嵌入式学习5】PyQt5模块介绍、创建第一个窗口
  • Linux安装启动ssh服务器以及ssh的配置
  • Leetcode 15 -- 双指针
  • Mysql 中的 MyISAM 引擎
  • 第十五届蓝桥杯单片机省赛程序设计试题
  • CSS 3D变换,transform:translateZ()
  • 从小米汽车事故反思 LabVIEW 开发
  • 专业的情商测评工具:EQ-i在线测评系统
  • Fastjson 处理 JSON 生成与解析指南
  • 31--当认证协议开始“选秀“:RADIUS、LDAP、AD与本地认证的C位之争
  • react redux的学习,多个reducer
  • drawio导出流程图为白色背景png图片
  • 对OSPF协议的LSA分析
  • Linux系统进程
  • AI 浪潮下企业身份管理:特点凸显,安全挑战升级
  • CMake学习-- install 指令详细说明
  • 11.多线程-信号量-线程池
  • AWS 云运维管理指南
  • ekf-imu --- 四元数乘法符号 ⊗ 的含义
  • SQLite 触发器
  • 深入解析CPU主要参数:选购与性能评估指南
  • ngx_alloc
  • 【2022】【论文笔记】基于相变材料的光学激活的、用于THz光束操作的编码超表面——
  • leetcode-代码随想录-哈希表-有效的字母异位词
  • 2007-2019年各省地方财政交通运输支出数据
  • 动物多导生理信号采集分析系统技术简析
  • 分治算法的使用条件
  • 页面简单传参
  • 【Linux】条件变量封装类及环形队列的实现