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万+

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

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

458

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

此心安处是吾乡的博客 6259

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

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

weixin_56167571的博客 2239

VS2017配置PCL1.9.1 for win10(超详细)

准备工作 VS2017 自行下载 PCL1.9.1 点击链接跳转Github下载,根据自己的环境选择 win64或win32,作者下载的是:PCL-1.9.1-AllInOne-msvc2017-win64.exepcl-1.9.1-pdb-msvc2017-win64.zip 安装PCL 双击点开PCL-1.9.1-AllInOne-msvc2017-win64.exe,选择Add PCL to the system PATH for all users, 更改安装路径,E:\Progra

malapoa的博客 1144

图像格式(YUYV)

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

lkjxcj3096的博客 2105

STGCN+YOLOV8行为分类

使用关节点追踪网络获取关节点数据,以yolo-v8网络为例,获取2D关节点数据。此次实验采用KTH动作识别数据集,包含人步行、慢跑、跑步、拳击、挥手和拍手等动作。

SDADASDAF的博客 3890

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

金融科技数据源

数字金融开放研究平台

平平淡淡,戒急用忍,一生学闭嘴。 1756

QT播放器插件内嵌浏览器配合流媒体实现国标摄像头网页端播放

基本原理在浏览器⽹页中的指定播放窗口的位置和⼤⼩,实现⼀个内嵌到⽹页中显⽰的播放窗⼝,前端还必须可对这个内嵌播放窗⼝进⾏控制,⽽且播放窗⼝必须跟随浏览器窗⼝的移动和缩放、⽹页滚动、标签页切换、关闭等操作进⾏⾃动联动。播放器可以通过QT实现。这个播放窗⼝同时提供Web Socket的服务端和JSON打包命令的解析执⾏模块,前端就可以通过Web Socket连接后发送JSON打包的控制命令实现控制播放窗⼝。

cameravision的博客 562

常用图像像素格式 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

docker 安装oracle

本文介绍了使用Docker部署Oracle数据库的实践指南。主要内容包括:常用Oracle镜像的阿里云和华为云拉取地址,11g/12c/19c等不同版本的启动命令示例,以及连接数据库的基本信息。实战部分详细演示了Oracle 11g的安装过程,包括镜像拉取、容器启动、密码修改和数据库连接步骤,并通过Sql Developer和命令行两种方式创建用户。最后提到数据持久化的重要性,建议将数据库文件挂载到宿主机目录以防止容器删除导致数据丢失。文章提供了完整的操作命令和截图说明,适合需要快速部署Oracle测试环境

weixin_39766667的博客 372

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

原子力显微镜AFM图像处理软件Gwyddion使用教程(图文)

Gwyddion使用教程Gwyddion简介Gwyddion user guide下载地址本次教程用的AFM扫描图像下载地址AFM/STM校准样品Gwyddion使用step1step2step3step4step5step6step7step8你没见过的CD磁道到底长啥样一张图总结 Gwyddion简介        &nbs...

王纯配的博客 5万+

【NLP】第十章:位置编码Positional Encoding

前面讲RNN时一般都会有一个ht的输出,这个输出就是样本与样本之间的信息,而且RNN是时序循环的,所以RNN本身的结构,在物理上,就自带词的前后顺序信息的。比如词never,不管never本身的词向量是什么,只要你在序列中排第一个位置,你的位置向量就是[0,1,01],你排第三个位置,你的位置向量就是[0.9,-0,4,0.2,1.0]。也所以,你可以理解为:embedding后的词嵌入,PE按照每个样本在sequence中的位置,把embedding后的词嵌入给扭转后,才送入attention的。

因为热爱所以坚持 1917

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

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

jerry3564的博客 7035

YOLOv11 改进 - 下采样 | 轻量化突破:ADown 下采样让 YOLOv11 参量减、精度升

本文介绍了一种轻量级的特征下采样模块 ADown,它结合平均池化与最大池化策略,实现更有效的信息保留与压缩。在传统卷积网络中,特征下采样常造成信息损失,而 ADown 通过双通道并行结构优化了下采样效果,提升了模型的表达能力。在 YOLOv11 中引入 ADown 替换原有的下采样模块后,网络在保持高效性的同时,显著提升了目标检测的精度与稳定性。文章详细介绍了 ADown 的核心代码实现、模块注册流程以及 YOLOv11-ADown 模型的配置和训练方法,为轻量化目标检测模型的优化提供了实用参考。

魔改工程师的博客 1479

yuyv v4l2的数据转换成RGB

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

tengfeidx的博客 436

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

yuyv(yuv422)转换为yuv420p

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

weixin_37897683的博客 4037

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

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的博客 857

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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的博客 1211

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、付费专栏及课程。

余额充值