YUV420->RGB888格式转换的CPP实现

article/2025/9/29 7:21:20

git地址:

GitHub - Evayangelion/EYUVConverter: A YUV converter implemented by cpp

上一次学习了YUV各种采样和存储方式的区别(YUV知识存档)

接下来一起学习一下RGB格式的知识和YUV到RGB的转换方式

RGB色彩模式的分类

RGB的分类相较YUV来说就比较简单和直观,总体来说遵循“怎么取样就怎么存储的”分类方式

按照每个像素信息占据的空间分类,RGB格式可以分成以下几种:

RGB16:每个像素占据的空间是16bit

        RGB16分类下还有两种细分类别:

             RGB565:R\G\B分量分别占用5bit、6bit、5bit

R

R

R

R

R

G

G

G

G

G

G

B

B

B

B

B

                可以用这几个掩码来分离RGB三个分量:

                R = RGB & 0xF800

                

                G = RGB & 0x07E0

                

                B = RGB & 0x001F

                

              RGB555:R\G\B分量分别占用5bit、5bit、5bit,留下最高位不用

R

R

R

R

R

G

G

G

G

G

B

B

B

B

B

                可以用这几个掩码来分离RGB三个分量:

                R = RGB & 0x7C00

                

                G = RGB & 0x03E0

        ​​​​​​​        

                B = RGB & 0x001F

        ​​​​​​​        

RGB24:每个像素占据的空间是24bit,其中R\G\B分量分别占用8bit、8bit、8bit

B

B

B

B

B

B

B

B

G

G

G

G

G

G

G

G

R

R

R

R

R

R

R

R

                可以用这几个掩码来分离RGB三个分量:

                R = RGB & 0x7C00

        ​​​​​​​        

                G = RGB & 0x03E0

        ​​​​​​​        

                B = RGB & 0x001F

        ​​​​​​​        

RGB32:每个像素占据的空间是32bit,其中R\G\B分量分别占用8bit、8bit、8bit,多出的8bit用来存alpha分量,也就是透明分量

B

B

B

B

B

B

B

B

G

G

G

G

G

G

G

G

R

R

R

R

R

R

R

R

A

A

A

A

A

A

A

A

                可以用这几个掩码来分离RGB三个分量:

                R = RGBA & 0x0000FF00

        ​​​​​​​        

                G = RGBA & 0x00FF0000

        ​​​​​​​        

                B = RGBA & 0xFF000000

        ​​​​​​​        

                A = RGBA & 0x000000FF

        ​​​​​​​        

YUV420RGB格式的转换

简单说完了RGB的储存原理和分类方式,接下来需要知道RGB和YUV各个分量的转化办法,这里直接给出转换公式:

        R = Y + 1.402 * (V -128);

        G = Y - 0.34414 * (U - 128) - 0.71414 * (V - 128);

        B = Y + 1.772 * (U - 128);

由于YUV三个分量是有复数值的,而RGB分量的值都在0-255中间,所以需要将YUV分量进行量化

有上面的知识,加上之前对YUV的了解,下来就可以尝试将一张YUV420的图片转换成RGB888

void YUV420toRGB(unsigned char *yuv420, unsigned char*rgb ,int width, int height) {int Ylen = width * height;unsigned char *p_Y420 = yuv420;unsigned char *p_U420 = p_Y420 + Ylen;unsigned char *p_V420 = p_U420 + Ylen / 4;int rgbIndex = 0;int R,G,B,Y,U,V;for(int y = 0; y < height; y++) {for(int x = 0; x < width; x++){Y = *(p_Y420 + y * width + x);U = *(p_U420 + (y / 2) * (width / 2) + x / 2);V = *(p_V420 + (y / 2) * (width / 2) + x / 2);/* * 在网络上搜索出的UV分量取值大多是 (y * width / 4) + x / 2这样* 我认为写成(y / 2) * (width / 2) + x / 2可以帮助理解* 原因如下:* 1.因为是YUV420的采样方式,每2×2个y分量公用一个u/v分量*   也就是对于偶数i,共用一个ui/vi的y分量有:*   yi    yi+1*   yi+w  yi+w+1*   所以在y和x方向分别需要/2* 2.width/2的原因是uv分量的行宽是y分量的一半*   y分量进入下一行需要+width个y分量*   那么uv分量进入下一行则需要+width/2个uv分量*/R = Y + 1.402 * (V -128);G = Y - 0.34414 * (U - 128) - 0.71414 * (V - 128);B = Y + 1.772 * (U - 128);R = R < 255 ? R : 255;G = G < 255 ? G : 255;B = B < 255 ? B : 255;R = R < 0 ? 0 : R;G = G < 0 ? 0 : G;B = B < 0 ? 0 : B;*(rgb + rgbIndex++) = R;*(rgb + rgbIndex++) = G;*(rgb + rgbIndex++) = B;}}
}

参考:

《图像处理》Part1 YUV4:2:2toYUV4:2:0、YUV420toYUV422、YUV422toRGB24、YUV420toRGB24算法_梁Rio的博客-CSDN博客

图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别_handy周的博客-CSDN博客_rgb565


http://chatgpt.dhexx.cn/article/XdNrGnAR.shtml

相关文章

YUV444,YUV420P,YUV420SP,YUV422P,YUV422SP,NV12,NV21,NV16,NV61等格式区分与存储简介

一、基础知识&#xff1a; 概述 YUV是顏色編碼方式&#xff0c;常用於視頻及圖像處理中。 其中的YUV是三個分量。“Y”表示明亮度&#xff08;Luminance或Luma&#xff09;&#xff0c;也就是灰度值。“U”和“V” 表示的是彩色信息&#xff0c;分別爲色度和濃度&#xff08;C…

OpenGL渲染YUV420P

一 、YUV420P数据格式二 、GLFW渲染YUV420P2.1 定义顶点数据2.2 创建YUV三张纹理2.3上行YUV420数据2.4 渲染纹理2.5 着色器 三、代码地址以及存在的问题四 、解决存在的问题 一 、YUV420P数据格式 图片来源于谷歌 结合上图可以看出YUV420P的特点如下&#xff1a; ①无论在横向还…

详解 YUV 格式(I420/YUV420/NV12/NV12/YUV422)

转载自&#xff1a;划水型派大星 YUV &#xff08;YCbCr&#xff09;是一种像素格式&#xff0c;常见于视频编码与静态图像。与 RGB 格式&#xff08;红-绿-蓝&#xff09;相反&#xff0c;YUV 分别由一个称为 Y&#xff08;相当于灰度&#xff09;的“亮度”分量&#xff08;…

ffmpeg学习笔记(2)-YUV420算法原理

ffmpeg学习笔记(2)——YUV420算法原理 一、YUV像素格式 YUV的组成格式如下图所示 Y:明亮度&#xff0c;即灰度值 U、V&#xff1a;颜色 YUV格式将亮度信息和色彩信息分离&#xff0c;没有色彩信息依然能够显示图像&#xff08;没有色彩信息&#xff09;&#xff0c;很好的解…

音视频编解码: YUV存储格式中的YUV420P,YUV420SP,NV12, NV21理解(转)

概述 之前介绍了YUV码流的采样格式&#xff0c;下面分析下YUV码流的存储格式&#xff0c;YUV码流的存储格式与采样格式息息相关。总的来讲&#xff0c;YUV存储格式主要分为两种&#xff1a; planar 平面格式 指先连续存储所有像素点的 Y 分量&#xff0c;然后存储 U 分量&…

图像编码YUV420格式

目录 一、YUV简介 二、RGB 到 YUV 的转换 三、YUV采样 YUV 4:4:4 YUV 4:2:2 YUV 4:2:0 四、YUV 存储格式 基于 YUV 4:2:2 采样的格式 YUYV 格式 UYVY 格式 YUV 422P 格式 基于 YUV 4:2:0 采样的格式 YU12 和 YV12 格式 NV12 和 NV21 格式 一、YUV简介 YUV&#x…

YUV420数据格式详解

YUV简介 YUV格式有两大类&#xff1a;planar和packed。 对于planar的YUV格式&#xff0c;先连续存储所有像素点的Y&#xff0c;紧接着存储所有像素点的U&#xff0c;随后是所有像素点的V。 对于packed的YUV格式&#xff0c;每个像素点的Y,U,V是连续交叉存储的。 YUV分为三个分…

python 生产者消费者模式

生产者消费者模式概述 在并发编程中使用生产者和消费者模式能够解决大不多的并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 为什么使用生产者消费者模式 在线程世界里&#xff0c;生产者就是生产数据的线程&#xff0c;消费者就是…

生产者-消费者模式

概述 生产者-消费者模式在系统交互方面,有几个特点: 1、系统解耦 2、解决并发问题 3、不需要关心对方系统何时处理数据,处理结果如何 下面用几个简单例子逐步说明。 简单例子 假设有两个系统,A系统和B系统,B系统需要依赖A系统产生的数据,也就是说,A系统产生数据后,必须把数…

生产者消费者模式及简单的运用场景

先考虑一个问题&#xff1a;服务端接受多个客户端提交的视频文件进行转码的操作&#xff0c;应该怎么设计&#xff1f; 由于转码比较花费时间&#xff0c;所以我们排除同步的想法。而转码需要用到的外部软件&#xff08;exe文件&#xff09;&#xff0c;不能同时被多个线程用到…

Java多线程系列—生产者消费者模式的多种实现(04)

生产者消费者模式 我们先来看看什么是生产者消费者模式,生产者消费者模式是程序设计中非常常见的一种设计模式,被广泛运用在解耦、消息队列等场景。 在现实世界中,我们把生产商品的一方称为生产者,把消费商品的一方称为消费者,有时生产者的生产速度特别快,但消费者的消…

生产者消费者模式的Java实现

一.概述 1. 什么是“生产者消费者模式”&#xff1f; 生产线程负责生产&#xff0c;消费线程负责消费 生产线程和消费线程要达到均衡。 生产满了就不能继续生产了&#xff0c;必须让消费线程进行消费 消费完了就不能再消费了&#xff0c;必须让生产线程进行生产 这是一种特殊的…

实现生产者消费者模式的三种方式

什么是生产者消费者模式 简单来说&#xff0c;生产者消费者模式就是缓冲区。 那么这么做有两个好处&#xff0c;一个是解耦&#xff0c;第二个是平衡生产能力和消费能力的差&#xff0c;因为生产者和消费者的速度是不一样的&#xff0c;有了这个缓冲区就可以平衡这样一个落差&…

生产者消费者模式最佳实践

测试环境&#xff1a;ubuntu18.04opencv4.2Qt 一个生产者-消费者模式下的视频处理框架。基础结构&#xff1a;视频读取类线程不断读取视频帧&#xff0c;处理类线程对图像进行处理&#xff0c;之后通过信号与槽机制在主线程中显示。特点&#xff1a;视频读取、处理为独立线程&a…

生产者、消费者模式

架构设计&#xff1a;生产者/消费者模式[0]&#xff1a;概述 今天打算来介绍一下“生产者&#xff0f;消费者模式”&#xff0c;这玩意儿在很多开发领域都能派上用场。由于该模式很重要&#xff0c;打算分几个帖子来介绍。今天这个帖子先来扫盲一 把。如果你对这个模式已经比较…

生产者和消费者模式详解

★简介 生产者消费者模式并不是GOF提出的23种设计模式之一&#xff0c;23种设计模式都是建立在面向对象的基础之上的&#xff0c;但其实面向过程的编程中也有很多高效的编程模式&#xff0c;生产者消费者模式便是其中之一&#xff0c;它是我们编程过程中最常用的一种设计模式。…

生产者消费者模式+代码实现

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 为什么要使用生产者和消费者模式 在线程世界里&#xff0c;生产者就是生产数据的线程&#xff0c;消费者就是消费数据的线程。在…

生产者消费者模式详解(转载)

★简介 在实际的软件开发过程中&#xff0c;经常会碰到如下场景&#xff1a;某个模块负责产生数据&#xff0c;这些数据由另一个模块来负责处理&#xff08;此处的模块是广义的&#xff0c;可以是类、函数、线程、进程等&#xff09;。产生数据的模块&#xff0c;就形象地称为生…

多线程之生产者消费者模式

文章目录 基本组成阻塞队列有界队列与无界队列ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue 流量控制与信号量(Semaphore)双缓冲与Exchanger 基本组成 生产者&#xff1a;生产者的任务是生产产品&#xff0c;产品可以是数据&#xff0c;也可以是任务。(将产品存入传…

java 生产者消费者模式

java的生产者消费者模式&#xff0c;有三个部分组成&#xff0c;一个是生产者&#xff0c;一个是消费者&#xff0c;一个是缓存。 这么做有什么好处呢&#xff1f; 1.解耦(去依赖)&#xff0c;如果是消费者直接调用生产者&#xff0c;那如果生产者的代码变动了&#xff0c;消费…