YUYV码流中提取单帧并转为RGB图片

OpenGL 渲染 YUYV(YUV422) OpenGL渲染YUYV(YUV422) 阅读详情

YUV和RGB都是一种颜色空间编码,要在这两种颜色空间之间进行转换,当然得知道它们的内存布局情况。下面先简单说下这两种颜色空间的编码情况。


RGB颜色空间应该是我们比较熟悉的了,分别是Red,Green,Blue三基色,每个分量占用一个字节,取值为0-255,三个0为黑,三个255为白,每三个字节为一个像素,当然在我们很多时候的处理中,可能会加入alpha通道,表示透明度,组合起来就是rgba四个通道。


YUV有两大类,平面格式和打包格式,具体这两种格式有什么区别呢,只有知道了具体的存储格式,我们才能对各个像素进行处理。平面格式就是把YUV的三个分量Y,U,V分开存放,例如放在三个数组中;而打包格式是把YUV的三个分量都放在一起,如按照一定的编码顺序存放在一个数组中。就这里我们说的YUYV格式来说,它就是一种打包格式,在内存布局中的具体方式是这样,YUYV YUYV……,每个分量占用一个字节,每两个字节也就是16位为一个像素,每两个像素一组就是一个巨像素,我们看到每两个像素也就是一个巨像素中有两个Y分量一个UV分量,这是因为YUYV是以4:2:2的格式打包的。其他yuv格式如下,注意:YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。关于yuv的详细介绍请看这里。


MEDIASUBTYPE_YUY2  YUY2格式,以4:2:2方式打包 
MEDIASUBTYPE_YUYV  YUYV格式(实际格式与YUY2相同) 
MEDIASUBTYPE_YVYU  YVYU格式,以4:2:2方式打包 
MEDIASUBTYPE_UYVY  UYVY格式,以4:2:2方式打包 
MEDIASUBTYPE_AYUV 带Alpha通道的4:4:4  YUV格式 
MEDIASUBTYPE_Y41P  Y41P格式,以4:1:1方式打包 
MEDIASUBTYPE_Y411  Y411格式(实际格式与Y41P相同)
MEDIASUBTYPE_Y211  Y211格式 
MEDIASUBTYPE_IF09 IF09格式 
MEDIASUBTYPE_IYUV IYUV格式 
MEDIASUBTYPE_YV12 YV12格式
MEDIASUBTYPE_YVU9 YVU9格式

上述的这些格式的处理方式都和YUYV的处理方式类似,只是它们的打包格式不同,从而YUV分量在内存中的具体编码方式也就不同,如果在看YUV的详细介绍时对所列举的各个采集方式不是很明白,可以自己动手试着画些草图或者是YUV的布局方式来帮助自己理解。它们不同的采集方式将会对应不同的处理方式,下面主要是对YUYV格式为例来做介绍:


我们先设想一张图片,它具有长和高两个变量,首先明确一点,在我们对图片进行处理转换时,这两个变量width和height是不会变得,也就是说一张RGB图像和一张YUV图像它们的长和高都是一样的,这一点对我们后续的处理很重要。同时它的长和高都是以像素点为基本单位,所以总的像素就是这张图的面积width*height,既然width和height都不变,那么一张图片的总像素点肯定就不会变了,所以图片的一行所占用的内存就为: width*(一个像素点占用的字节数), 对这些有个明确的概念后,我们处理起来就容易多了。一张RGB24图像不考虑alpha通道,那么它一个像素占用三个字节,考虑alpha通道RGB32,那么一个像素就占用四个字节。


对于YUV格式的图像来说,降低的只是它的色度采样率,也就是它的UV分量,而亮度分量Y是没有降低的,这里就不再做具体的说明。例如,4:4:4的采样方式是一个Y分量对应一个U和一个V分量,并没有降低;4:2:2是两个Y共用一个UV分量;4:2:0是四个Y共用一个UV分量。所以它的像素点数仍然没有变得。如,YUYV格式16位一个像素,一张图片占用的总内存为: width*height*2,其他格式内存占用情况可以看这里。


下面对YUYV码流进行提取单帧处理,现在我们应该很清楚的知道了,YUYV格式单帧图片所占用的内存应该就为width*height*2,yuv格式和rgb之间的转换都是有相应的公式的,网上一找很多的讲解,这里也不再介绍了。


下面是yuyv转rgb24的函数:

int convert_yuv_to_rgb_pixel(int y, int u, int v)
{
 unsigned int pixel32 = 0;
 unsigned char *pixel = (unsigned char *)&pixel32;
 int r, g, b;
 r = y + (1.370705 * (v-128));
 g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));
 b = y + (1.732446 * (u-128));
 if(r > 255) r = 255;
 if(g > 255) g = 255;
 if(b > 255) b = 255;
 if(r < 0) r = 0;
 if(g < 0) g = 0;
 if(b < 0) b = 0;
 pixel[0] = r * 220 / 256;
 pixel[1] = g * 220 / 256;
 pixel[2] = b * 220 / 256;
 return pixel32;
}

int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
{
 unsigned int in, out = 0;
 unsigned int pixel_16;
 unsigned char pixel_24[3];
 unsigned int pixel32;
 int y0, u, y1, v;
 for(in = 0; in < width * height * 2; in += 4) {
  pixel_16 =
   yuv[in + 3] << 24 |
   yuv[in + 2] << 16 |
   yuv[in + 1] <<  8 |
   yuv[in + 0];
  y0 = (pixel_16 & 0x000000ff);
  u  = (pixel_16 & 0x0000ff00) >>  8;
  y1 = (pixel_16 & 0x00ff0000) >> 16;
  v  = (pixel_16 & 0xff000000) >> 24;
  pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
  pixel_24[0] = (pixel32 & 0x000000ff);
  pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
  pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
  rgb[out++] = pixel_24[0];
  rgb[out++] = pixel_24[1];
  rgb[out++] = pixel_24[2];
  pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
  pixel_24[0] = (pixel32 & 0x000000ff);
  pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
  pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
  rgb[out++] = pixel_24[0];
  rgb[out++] = pixel_24[1];
  rgb[out++] = pixel_24[2];
 }
 return 0;
}

下面是测试代码:

    //因为只是简单的测试用,所以代码写的有点随意
    QFile file("G:/Documents/QtProject/yuyvSplit/flower_yuyv422_352X288.yuv");
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open file failed.";
        return;
    }

    int width = 352;
    int height = 288;
    int frames  = 250;  //yuyv码流总的帧数
    int singleCounts = width * height * 2;
    int yuyvCounts = singleCounts * 250;
	int yuyvPitch = width * 2;    //yuyv 缓存一行的大小

    int rgb24Size = width * height * 3;
	int rgb32Size = width * height * 4;
	int rgb32Pitch = width * 4;   //rgb32 缓存一行的大小
    int rgb24Pitch = width * 3;

    qDebug() << "yuyvCounts: " << yuyvCounts << "\nfileSize: " << file.size();

    for(int i = 0; i < 1; ++i )
    {
        char *singleFrame = new char[singleCounts]();
        int ret = file.read(singleFrame, singleCounts);
        qDebug() << "read return size: " << ret << " signleCounts: " << singleCounts;
        char *rgb24 = new char[rgb24Size]();
        convert_yuv_to_rgb_buffer((unsigned char*)singleFrame, (unsigned char*)rgb24, width, height);

        //不用QT的话,这里可以直接把图片rgb24buffer写入文件image.bmp中,
        //注意保存格式,bmp是位图,而类似jpg,png之类的是经压缩过的。
        QImage *img = new QImage((unsigned char*)rgb24, width, height, rgb24Pitch, QImage::Format_RGB888);

        //这里把图像呈现出来观察
        ui->image->setPixmap(QPixmap::fromImage(*img));

		delete[] singleFrame;
		delete[] rgb32;
    }

    file.close();

YUV码流文件可以用 这个工具打开,可以直接从中看到yuv码流的帧数,用到的YUYV文件见 这里,感谢提供者!


YUV图像格式转换: YUYV 转 NV12 (YUV420SP) 首先确认YUYV与NV12 的采样格式, YUYV 属于YUV4:2:2采样, 而NV12属于YUV4:2:0采样。 采样方式如下图所示: 可以很明显地看出YUV422采样中两个像素点共用一对U和V的分量, 而YUV420采样中四个像素点共用一对U和V 的分量。有了这个概念,接下来的理解将十分轻松。 两者在存储方式上的表现如下图所示: ... 阅读详情

相关推荐

YUV格式详解

1、什么是YUV? YUV是指亮度参量和色度参量分开表示的像素格式,其中“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。 与我们熟知的RGB类似,YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信...

iva_brother的博客 2万+

谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV

1) YUV 4:4:4 YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。 下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 (2) Y

cuiy0001的专栏 2万+

Linux V4L2 摄像头采集 + YUYV 转 RGB 显示

本文详细介绍了 Linux 下通过 V4L2 框架实现摄像头数据采集的完整流程,包括设备打开、格式设置、内存映射、采集帧数据,以及如何将 YUYV 图像格式转换为 ARGB 并实时显示在 LCD 屏幕上。

weixin_56167571的博客 2240

YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB

YUYV、YVYU、UYVY、VYUY格式,它们都是YUV422的打包格式——即在内存中,Y、U、V都是挨着排序的。它们的名称就表示了Y、U、V的顺序。像YUYV,就是Y、U、Y、V、Y、U、Y、V。在做转换时,就显得很容易、简单了。 因为极其相近,故在将这几种格式全部封闭到一个函数里做。代码如下: void yuv422packed_to_rgb24(YUV_TYPE type, unsigned char* yuv422p, unsigned char* rgb, int width, int heig

此心安处是吾乡的博客 6262

白炽灯寿命工程解析:从钨丝蒸发到电压控制的可靠性设计

白炽灯作为一种经典的电光源,其工作原理基于电流通过钨丝产生热辐射发光。在高温下,钨丝会持续蒸发导致灯丝逐渐变细、电阻增大,这是影响其寿命的核心物理机制。从工程角度看,白炽灯的可靠性设计涉及材料科学、热力学和电路设计的交叉,技术价值在于通过理解其失效原理,可以在成本与性能间取得最佳平衡。在实际应用中,电压波动、开关浪涌电流和机械振动是主要寿命杀手,尤其在工业控制、仪器仪表和特定照明场景中,合理的设计能大幅提升系统稳定性。本文深入探讨了钨蒸发、热应力等关键因素,并结合浪涌抑制和降压设计等实战技巧,为工程师提供了

weixin_28684655的博客 569

SAM2与Docker的完美组合:5分钟搞定Linux环境下的图像分割部署

本文详细介绍了如何在Linux环境下通过Docker快速部署SAM2图像分割模型,解决安装过程中的常见问题。文章提供了从镜像选择、CUDA版本匹配到容器构建的全流程指南,特别针对GPU加速环境下的'cudnn_frontend: No execution plans support the graph'等报错提供了实用解决方案,帮助开发者在5分钟内完成高效部署。

fern8的博客 933

Clawra:OpenClaw生态中摄像头能力的环境契约与可靠性保障

在AI Agent系统中,硬件感知能力(如摄像头调用)并非简单的API调用,而是涉及设备驱动、权限管理、内存调度与模型适配的多层环境约束。Clawra作为OpenClaw官方Skill,将‘摄像头可用性’从人工排查经验固化为可执行、可验证的自动化契约,通过启动自检握手、深度健康探针和能力协商机制,解决Linux/Windows/ARM64等异构环境下常见的permission denied、device not found、stream timeout等典型故障。其技术价值在于弥合Agent框架与物理世界之

458

YF-S401水流量传感器在STM32上的精准计量实现

本文详细介绍了YF-S401水流量传感器与STM32微控制器的集成应用,实现精准水流计量。通过外部中断和外部时钟两种脉冲计数方案,结合硬件配置、软件滤波和校准技巧,确保高精度流量测量。适用于智能家居和工业自动化中的水控系统,提升系统稳定性和测量准确性。

rainy的博客 896

图像格式(YUYV)

1.参考链接 https://blog.youkuaiyun.com/sz76211822/article/details/91361086

lkjxcj3096的博客 2105

飞控芯片的隐形战场:传感器冗余与实时OS的可靠性革命

本文深入探讨飞控芯片在工业级无人机中的可靠性设计,聚焦传感器冗余架构与实时操作系统(RTOS)的容错机制。通过多IMU备份、自适应加权融合算法及NuttX、ChibiOS等RTOS的故障隔离技术,确保系统在极端环境下毫秒级自愈。文章还涵盖开源生态如PX4的跨平台移植及RISC-V架构的应用,为高可靠性飞控系统提供关键技术参考。

z5a6b的博客 877

LaMAR数据集下载和使用流程

LaMAR数据集

qq_51745206的博客 971

YUV4:2:2和YUV4:2:0 区别

1) YUV 4:4:4 YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。 下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 (2) YUV 4

龙图腾的博客 6519

基于Python的高考志愿辅助填报系统

在实际应用中,系统需要处理更复杂的数据,包括更多的高校和专业信息、更详细的录取规则、以及用户的历史选择等。系统需要提供用户友好的界面,让考生输入自己的信息和偏好,然后通过后端的模型计算出推荐的志愿列表。此外,系统还应该提供一些个性化的服务,如根据考生的输入动态调整推荐策略、保存用户的填报历史和偏好等。特征可能包括考生的分数、所在省份、文理科类别、专业偏好、高校的地理位置、排名、专业的就业前景等。3. **推荐逻辑**:根据用户的分数和专业偏好,结合历史录取数据,使用简单的算法来推荐可能录取的高校和专业。

coder_wwwdy的博客 1976

常用图像像素格式 NV12、NV2、I420、YV12、YUYV

文章目录 常用图像像素格式 RGB 和 YUVRGB 格式YUV 格式YUV采样YUV存储格式常见的像素格式YUV422:YUYV、YVYU、UYVY、VYUYYUV420:I420、YV12、NV12,、NV21 常用图像像素格式 RGB 和 YUV 近期由于项目需要,开始接触图像像素格式,因此在这里做一个小结。 像素格式描述了像素数据存储所用的格式,定义了像素在内存中的编码方式。RGB 和 YUV 为两种经常使用的像素格式。 RGB 格式 一般较为熟悉,RGB图像...

yaningli的博客 3043

把 SAP GUI 做成可维护的应用:Module Pool 基础与 Table Control 深入实战

SAP Module Pool 与 Table Control 开发要点 摘要:Module Pool 作为 SAP GUI 交互的核心技术,由程序、屏幕(Dynpro)和流逻辑(Flow Logic)组成,通过 PBO/PAI 事件驱动数据流。Table Control 是其中处理多行数据的核心控件,其开发关键在于: 正确理解 PBO/PAI 数据流机制 掌握 CXTAB_CONTROL 结构的关键属性(LINES、TOP_LINE 等) 合理设置列控制属性(CXTAB_COLUMN) 采用 LOOP W

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 241

从零到一使用PXE实现系统的无人值守自动化安装的保姆级教程

本文是《从零到一使用PXE实现系统的无人值守自动化安装的保姆级教程》亲自实操可用,本文从PXE是什么?有啥用?及其亲自实践出通过以国产银河麒麟系统为例从零到一的搭建出PXE服务器端(适用于其他系统),且测试了该搭建的PXE服务端自动化无人值守安装系统的保姆级实操教程。适用于大批量设备系统安装部署场景。

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 580

YUYV格式到RGB格式的转换

为什么YUYV格式要转到RGB格式,视频的显示调用的多数API都是基于RGB格式,所以需要进行格式的转换。 YUYV格式如下: Y0U0Y1V0 Y2U1Y3V1.......... 说明:一个Y代表一个像素,而一个Y和UV组合起来构成一个像素,所以第0个像素Y0和第一个像素Y1都是共用第0个像素的U0和V0。而每个分量Y,U,V都是占用一个字节的存储空间。所以Y0U0Y1V0相当于两个像素,占...

weixin_34129696的博客 1398

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解

YUV是指亮度参量和色度参量分开表示的像素格式,而这样分开的好处就是不但可以避免相互干扰,还可以降低色度的采样率而不会对图像质量影响太大。YUV是一个比较笼统地说法,针对它的具体排列方式,可以分为很多种具体的格式。转载一篇对yuv格式解释的比较清楚地文章,也可以直接参考微软的那篇文章。对于YUV格式,比较原始的讲解是MPEG-2 VIDEO部分的解释,当然后来微软有一个比较经典的解释,中文的大多是...

jerry3564的博客 7036

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

yuyv v4l2的数据转换成RGB

【代码】yuyv v4l2的数据转换成RGB。

tengfeidx的博客 436

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

yuv 图像处理是不是只处理灰度_YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)

YUV格式有两大类:planar和packed。对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。对于packed的YUV格式,每个像素点的Y,U,V是连续交*存储的。YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩...

weixin_39640265的博客 858

yuyv(yuv422)转换为yuv420p

我的摄像头采集到的数据是yuyv格式(属于yuv422),而X264在进行编码的时候需要 标准的YUV(4:2:0)。所以有一个yuv422toyuv420的转换。在网上找了半天找到的方法拿过来转换了查看都很花。于是自己看了一下yuv 格式的解释,准备写一个转换代码。以下许多解释都是按我的理解: 一、yuv yuv格式通常有两大类:打包(packed)和平面(planar)格式。前者在码流里是y...

weixin_37897683的博客 4037

FFMPEG 编码YUYV 数据

看了雷神的博客《最简单的基于FFMPEG的视频编码器(YUV编码为H.264)》,它介绍的是使用FFMPEG将YUV420 数据编码成H.264数据。在它的博客中,没有介绍到YUYV数据格式的编码,但是我们在实际应用中,有时候摄像头只能输出YUYV数据格式,这样他的工程就不能使用了。经过一通折腾,终于在他的基础上实现了使用FFMPEG将YUYV编码成H264数据。 因为YUYV数据是.........

Biao 5496

YUVToRGB(CUDA Conversion)库的学习

YUVToRGB(CUDA Conversion)库的学习

周同学的博客 3785

【基础知识】YU12、YV12、NV12、NV21、YUY2、UYVY、YUYV、YVYU、AYUV、I420、IYUV、NV16

类别格式NV12, NV21NV16AYUVI420/YU12/NV12/NV21 是最常用的四种 YUV 4:2:0 格式,掌握它们足以应对 90% 的视频/图像处理场景。如需某格式的C++/Python 解析代码内存布局图或FFmpeg 转换命令,欢迎继续提问!

lijian2017的博客 1212

MIPG和YUYV格式区别与特点

MJPG:YUYV:

weixin_67505885的博客 2055
上一篇: 字符编码及宽字符类型(wchar_t)的跨平台处理
下一篇: 通过Python爬虫爬取知乎某个问题下的图片
Willib
博客等级 码龄14年 83粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值