【数字图像处理】YUV420转RGB并BMP存储<纯C++实现>

2023-05-16


  
  
1、读取akiyo_qcif.yuv YUV420文件,按帧读取,转RGB,并存储到BMP文件。
2、暂时实现读取一帧并存储一张BMP图片。 若要读取YUV序列,写成循环方式即可。
3、生成的BMP文件还有一点小问题:图像的倒立的,而且红色偏多。
YUV是qcif分辨率。
估计是YUV到RGB的计算公式有点问题。解决中。。。。
图像倒立问题已经解决。
红色不知道是不是公式变换和RGB数值区间限制的时候产生的。估计和UV的差值方式也有关系。
红色的问题已经解决,采用的变换公式不正确。 但是还是有一些横纹,不知道是怎么回事。
 
     
     
头文件 Ex1 . h
typedef unsigned char BYTE ;
typedef unsigned short WORD ;
typedef unsigned int DWORD ;
typedef long LONG ;
//位图文件头定义;
//其中不包含文件类型信息(由于结构体的内存结构决定,
//要是加了的话将不能正确读取文件信息)
typedef struct tagBITMAPFILEHEADER {
// WORD bfType;//文件类型,必须是0x424D,即字符“BM”
DWORD bfSize ; //文件大小
WORD bfReserved1 ; //保留字
WORD bfReserved2 ; //保留字
DWORD bfOffBits ; //从文件头到实际位图数据的偏移字节数
} BITMAPFILEHEADER ;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize ; //信息头大小
LONG biWidth ; //图像宽度
LONG biHeight ; //图像高度
WORD biPlanes ; //位平面数,必须为1
WORD biBitCount ; //每像素位数
DWORD biCompression ; //压缩类型
DWORD biSizeImage ; //压缩图像大小字节数
LONG biXPelsPerMeter ; //水平分辨率
LONG biYPelsPerMeter ; //垂直分辨率
DWORD biClrUsed ; //位图实际用到的色彩数
DWORD biClrImportant ; //本位图中重要的色彩数
} BITMAPINFOHEADER ; //位图信息头定义
typedef struct tagRGBQUAD {
BYTE rgbBlue ; //该颜色的蓝色分量
BYTE rgbGreen ; //该颜色的绿色分量
BYTE rgbRed ; //该颜色的红色分量
BYTE rgbReserved ; //保留值
} RGBQUAD ; //调色板定义
//像素信息
typedef struct tagIMAGEDATA
{
BYTE blue ; ///8位灰度图用其中1个
BYTE green ;
BYTE red ;
} IMAGEDATA ;
源文件 Ex1 . cpp
#include "stdafx.h"
#include "Ex1.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#define qcif
#ifdef qcif
#define Y_WIDTH 176
#define Y_HEIGHT 144
#define U_WIDTH 88
#define U_HEIGHT 72
#define V_WIDTH 88
#define V_HEIGHT 72
#endif
//变量定义
BITMAPFILEHEADER strHead ; //位图文件头
BITMAPINFOHEADER strInfo ; //位图信息头
unsigned char Y_space [ Y_WIDTH * Y_HEIGHT ];
unsigned char U_space [ U_WIDTH * U_HEIGHT ];
unsigned char V_space [ V_WIDTH * V_HEIGHT ];
unsigned char R_space [ Y_WIDTH * Y_HEIGHT ];
unsigned char G_space [ Y_WIDTH * Y_HEIGHT ];
unsigned char B_space [ Y_WIDTH * Y_HEIGHT ];
void ReadImage ( unsigned char * pImage , char * cFileName , int nWidth , int nHeight , long offset ); 读取YUV文件
int main ( int argc , char * argv [])
{
long origin = 0 + Y_WIDTH * Y_HEIGHT + U_WIDTH * U_HEIGHT + V_WIDTH * V_HEIGHT ; ///YUV文件起始位置
int i , j , u_j , v_j ;
int width , height ;
width = Y_WIDTH ;
height = Y_HEIGHT ;
FILE * fpw ;
WORD bfType_w = 0x4d42 ;
IMAGEDATA * imagedata = NULL ; //动态分配存储BMP图片的像素信息的二维数组
imagedata = ( IMAGEDATA * ) malloc ( width * height * sizeof ( IMAGEDATA )); //按IMAGEDATA结构体大小,分配存储BMP图片的存储空间
//初始化原始图片的像素数组
for ( i = 0 ; i < height ; ++ i )
{
for ( int j = 0 ; j < width ; ++ j )
{
( * ( imagedata + i * width + j )). blue = 0 ;
( * ( imagedata + i * width + j )). green = 0 ;
( * ( imagedata + i * width + j )). red = 0 ;
}
}
// origin=0;///读第一帧
// for(i=0,origin=0;i<148;i++,origin+=(Y_WIDTH*Y_HEIGHT+U_WIDTH*U_HEIGHT+V_WIDTH*V_HEIGHT))
// {///读取第一帧图像
ReadImage ( Y_space , "akiyo_qcif.yuv" , Y_WIDTH , Y_HEIGHT , origin ); //carphone001.yuv
ReadImage ( V_space , "akiyo_qcif.yuv" , V_WIDTH , V_HEIGHT , Y_WIDTH * Y_HEIGHT ); ///读取方法涉及YUV的存储顺序。 存储顺序是所有Y,随后是所有V,最后是所有U。
ReadImage ( U_space , "akiyo_qcif.yuv" , U_WIDTH , U_HEIGHT , Y_WIDTH * Y_HEIGHT + V_WIDTH * V_HEIGHT );
// }
///YUV转成RGB 176*144 88*72 width * height
u_j = 0 ; v_j = 0 ;
int y , cb , cr ; //y u v
int r , g , b ;
for ( i = 0 ; i < Y_HEIGHT ; i ++ )
{
for ( j = 0 ; j < Y_WIDTH ; j ++ )
{
u_j = j / 2 ; ///取倍数
v_j = j / 2 ; ///取倍数,U和V的宽度是Y的一半。
/对应4:2:0 YUV 采样方式 参考文章:http://blog.csdn.net/shallon_luo/article/details/5544796
y = Y_space [ j + i * Y_WIDTH ];
cb = U_space [ u_j + i * U_WIDTH ];
cr = V_space [ v_j + i * V_WIDTH ];
/* R = Y + 1.14V,G = Y - 0.39U - 0.58V,B = Y + 2.03U YUV对应YCbCr
r = y + 1.14*cr;
g = y - 0.39*cb - 0.58*cr;
b = y + 2.03*cb; */
/* YCbCr与RGB的关系 */
r = 1.164 * ( y - 16 ) + 1.596 * ( cr - 128 );
g = 1.164 * ( y - 16 ) - 0.813 * ( cr - 128 ) - 0.392 * ( cb - 128 );
b = 1.164 * ( y - 16 ) + 2.017 * ( cb - 128 );
/* r=1.0*y+1.402*(cr-128) ;
g=1.0*y-0.34413*(cb-128)-0.71414*(cr-128);
b=1.0*y+1.772*(cb-128);*/
r = r > 255 ? 255 : r ;
g = g > 255 ? 255 : g ;
b = b > 255 ? 255 : b ;
r = r < 0 ? 0 : r ;
g = g < 0 ? 0 : g ;
b = b < 0 ? 0 : b ;
B_space [ j + i * Y_WIDTH ] = b ;
G_space [ j + i * Y_WIDTH ] = g ;
R_space [ j + i * Y_WIDTH ] = r ;
}
}
for ( i = 0 ; i < Y_HEIGHT ; ++ i )
{
for ( int j = 0 ; j < Y_WIDTH ; ++ j )
{
( * ( imagedata + i * Y_WIDTH + j )). blue = B_space [ j + i * Y_WIDTH ];
( * ( imagedata + i * Y_WIDTH + j )). green = G_space [ j + i * Y_WIDTH ];
( * ( imagedata + i * Y_WIDTH + j )). red = R_space [ j + i * Y_WIDTH ];
}
}
///保存BMP图像
if (( fpw = fopen ( "result033.bmp" , "wb" )) == NULL )
{
cout << "create the bmp file error!" << endl ;
return NULL ;
}
fwrite ( & bfType_w , 1 , sizeof ( WORD ), fpw );
strHead . bfSize = Y_WIDTH * Y_HEIGHT * 3 + 54 ; //位图文件大小,说明文件的大小,用字节为单位
strHead . bfReserved1 = 0 ;
strHead . bfReserved2 = 0 ;
strHead . bfOffBits = 54 ; //从文件头到实际位图数据的偏移字节数14+40,无调色板。
fwrite ( & strHead , 1 , sizeof ( tagBITMAPFILEHEADER ), fpw );
strInfo . biWidth = Y_WIDTH ; //指定图象的宽度,单位是象素。
strInfo . biHeight = Y_HEIGHT ; //指定图象的高度,单位是象素。
strInfo . biBitCount = 24 ; 指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)(
strInfo . biClrImportant = 0 ; ///指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。
strInfo . biClrUsed = 0 ; ///指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。
strInfo . biCompression = 0 ; //指定位图是否压缩。
strInfo . biPlanes = 1 ; ///平面数,必须是1
strInfo . biSize = 40 ; ///指定这个结构的长度,必须是40。
strInfo . biSizeImage = 3 * width * height ; //指定实际的位图数据占用的字节数,似乎填什么都可以。
fwrite ( & strInfo , 1 , sizeof ( tagBITMAPINFOHEADER ), fpw );
//保存像素数据
for ( i = Y_HEIGHT ; i > 0 ; -- i ) ///从上往下写。图像上下翻转
{
for ( int j = 0 ; j < Y_WIDTH ; ++ j )
//for(int j = Y_WIDTH;j > 0;--j)///从右往左写 图像左右对调
{
fwrite ( & (( * ( imagedata + i * Y_WIDTH + j )). blue ), 1 , sizeof ( BYTE ), fpw );
fwrite ( & (( * ( imagedata + i * Y_WIDTH + j )). green ), 1 , sizeof ( BYTE ), fpw );
fwrite ( & (( * ( imagedata + i * Y_WIDTH + j )). red ), 1 , sizeof ( BYTE ), fpw );
}
}
fclose ( fpw );
//释放内存
delete [] imagedata ;
return 0 ;
}
void ReadImage ( unsigned char * pImage , char * cFileName , int nWidth , int nHeight , long offset )
{
int j , i ;
unsigned char * pWork ;
FILE * fp = 0 ;
if ( fp = fopen ( cFileName , "rb" ) ) //打开一幅图像
{
fseek ( fp , offset , SEEK_SET ); //文件定位
pWork = pImage ; //指针指向
for ( j = 0 ; j < nHeight ; j ++ , pWork += nWidth )
for ( i = 0 ; i < nWidth ; i ++ )
fread ( pWork + i , 1 , 1 , fp ); //顺序读取,每次读一个字节存入pwork[]中
fclose ( fp );
}
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数字图像处理】YUV420转RGB并BMP存储<纯C++实现> 的相关文章

  • Silverlight 4 BitmapImage - bmp 文件支持

    MSDN 提到了对 PNG 和 JPG 的支持 但许多人正在尝试 setSource file bmp 并抱怨 灾难性失败 有人可以澄清一下 是否支持 bmp 吗 如果没有 在 silverlight 中显示 bmp 的最佳方式是什么 Si
  • 阿尔法 + RGB -> ARGB?

    在as3中 是否有实用程序或函数可以将RGB颜色 例如0xFF0000 和alpha值 例如0 5 转换为A 32位ARGB值 从 ARGB 到 RGB alpha 一些解释 位图数据可以在其构造函数中采用 ARGB 值 但在精灵中填充形状
  • 将 Arduino RGB LED 从一种颜色渐变为另一种颜色?

    目前 我已成功让 LED 灯循环显示我选择的八种颜色 一切都工作正常 除了我想要一种更自然的感觉 并且想要从一种颜色褪色 过渡到下一种颜色 而不是让它们互相替换 到目前为止 这是我的代码 int redPin 11 int greenPin
  • 如何将图像转换为灰度?

    我想通过代码 android 做与上图完全相同的事情 但我对执行此操作的算法感到困惑 我所知道的是 对于每个像素 将 RGB 转换为 HSL 将 HSL 转换回 RGB 谁能帮我解释一下第 2 步要做什么 非常感谢 ps 我可以通过 Col
  • 如何使用 Python 更快地处理图像?

    我试图编写一个脚本来检测屏幕上的 RGB 值 然后单击 x y 值 我知道如何执行单击 但我需要比下面的代码当前处理图像的速度快得多 这可以用Python实现吗 到目前为止 我一次读取一行 当 x 1920 时 我进入第二行 但完成一行大约
  • PHP 生成 RGB

    我面临着这种情况 我有一个来自数据库的 ID 因此它可以是 1 100 1000 并且我需要生成随机颜色 但是相同的 ID 应该会产生相同的颜色 关于如何实现这一目标有什么建议吗 Thanks 使用加密哈希并剪切不需要的字节 functio
  • 从信号图像(RGB)中去除背景“噪音”

    I have some signal images 正如您所看到的 其中一些包含颜色信号 一些只是灰色 黑色信号 我的任务是提取白色背景的纯信号仅有的 这意味着我需要删除图像中除信号之外的所有内容 我检查了虚线 点线 实线 顶部和底部 具有
  • Python Pygame 无法正确显示图像

    我是 Python 新手 我开始学习 Eric Matthes 的 Python 速成课程 我在 Pygame 章节的开头 遵循代码 但我加载的图像总是看起来损坏 我不知道为什么 代码来自书本 第一个文件 import pygame cla
  • Javax ImageIO IIOException 显然没有原因

    大家好 我有一个 Java 问题 对于我的高级研究课程 我已经基本完成 但我只需要分析我生成的图像中的一些数据 我不想将其标记为家庭作业 因为它不是任何必需作业的一部分 这是我自己想出的来收集结果的东西 我编写了一个程序来逐像素比较两个图像
  • 将真彩色 RGB 图像转换为索引颜色

    我想使用索引调色板将 24 位 RGB 图像 每个通道 8 位 转换为 8 位 我最初的想法是创建一个数组并简单地计算每种颜色在图像中出现的次数 但我认为如果有大面积的颜色略有变化而占用了所有调色板空间 那将是浪费较小但可能更重要的颜色组
  • 计算一系列值的 RGB 值以创建热图

    我正在尝试用 python 创建热图 为此 我必须为可能值范围内的每个值分配一个 RGB 值 我想将颜色从蓝色 最小值 更改为绿色到红色 最大值 下面的图片示例解释了我对颜色组合的看法 我们的范围是从 1 纯蓝色 到 3 纯红色 2 介于两
  • java中RGB转灰度、bmp图像

    我的老师给我们布置了一个任务 要制作一个采用 640x480 bmp 彩色图像的课程 将其转换为灰度图像 我找到了一些有想法的资源 所以我做到了 但是有一个问题 因为它似乎使它不会给我错误 但输出没有出现 我认为这是我的代码 我的代码是 i
  • 使用鼠标光标捕获屏幕截图

    我使用以下代码在 Windows 上获取屏幕截图 hdcMem CreateCompatibleDC hdc int cx GetDeviceCaps hdc HORZRES int cy GetDeviceCaps hdc VERTRES
  • 如何设置 BufferedImage 中的 RGB 像素以显示 16 位深度的 PNG?

    我正在尝试读取并显示 PNG 文件 我处理 8 位深度的图像没有问题 我按如下方式进行 BufferedImage result new BufferedImage width height BufferedImage TYPE INT R
  • 将 RGB 数组转换为 Mat (OpenCv)

    我一直在尝试转换数组 R G B 在带有 opencv 的 Mat 对象中 但是返回的数据是错误的 有人知道为什么吗 double data 12 0 0 255 0 0 255 0 0 255 0 0 255 Mat src Mat 2
  • YUV420 到 RGB 转换

    我使用以下公式将 RGB 矩阵转换为 YUV 矩阵 Y 0 257 R 0 504 G 0 098 B 16 Cr V 0 439 R 0 368 G 0 071 B 128 Cb U 0 148 R 0 291 G 0 439 B 128
  • 如何在C中将RGB转换为HSL?

    如何在 C C 中将 RGB 转换为 HSL Note This is a short self answer I posted it here so people can find it quickly with a search 翻译代
  • 位图文件头大小

    我是 bmp 文件编程的新手 我检查了这个网站以了解 bmp 标头 http www daubnet com en file format bmp http www daubnet com en file format bmp bmp 文件
  • 使用 ZPL 打印 BMP

    如何使用 ZPL II 打印位图 BMP 图像 我使用 DY 将 BMP 下载到打印机 DYR PRINT B B
  • Alpha 混合红色、蓝色和绿色图像以生成着色为任何 RGB 值的图像?

    基本上 我有一个上下文 我无法以编程方式对图像进行着色 尽管我可以更改它的 alpha 值 通过一些实验 我发现我可以使用特定的 alpha 值对图像的红色 蓝色和绿色版本进行分层 以产生各种颜色 但是我想知道是否可以通过这种方法实现真正

随机推荐

  • CSP考试复习:第一单元 C++语言基础 1.1 程序结构

    第一单元 C 43 43 语言基础 1 1 程序结构 1 程序框架 注释 xff1a 注释有两种 xff0c 一种是 xff0c 另一种是 必须单独放置一行 xff0c 或代码所在行 的后面 xff1b 而 成对存在 xff0c 可以插入到
  • Intel Realsense T265开箱测试

    前言 xff1a 最近因为要做VIO xff0c 在实验室蹭到一个Realsense T265来用 xff0c 仅此记录下简单测试过程 xff08 官方文档写非常清楚 xff0c 建议详细阅读 xff0c 链接 xff1a https gi
  • posix thread介绍

    xfeff xfeff posix thread是 操作系统级 xff08 OS level xff09 的API规范 xff0c 主要用来定义线程及线程间同步的相关操作 xff0c 采用C语言定义 posix规范主要在unix like类
  • PX4飞控之自主起飞Takeoff控制逻辑

    本文主要以PX4飞控1 5 5版本为例 xff0c 介绍Navigator中自主起飞 xff08 Takeoff xff09 算法控制逻辑 注 xff1a mission任务中的自主起飞与此模块不同 Takeoff与导航中的其他模块类似 x
  • PX4飞控之导航及任务架构

    本文重点介绍PX4飞控的Navigator和mission控制框架和逻辑 Navigator导航部分是无人机自主飞行控制的核心所在 xff0c 其中包括自主起飞 自主降落 自主返航 自主任务以及GPS失效保护等各个部分 搞懂这个部分有助于理
  • PX4飞控之位置控制(1)整体架构

    位置控制是无人机飞控的核心算法之一 xff0c 一方面根据commander中的flag标志位和Navigator中提供的航点信息进行控制 xff08 自主模式下 xff09 xff0c 另一方面得到期望姿态角 xff08 setpoint
  • spring整合ehcache找不到org.springframework.cache.ehcache.EhCacheCacheManager的解决方案

    一般org springframework cache ehcache EhCacheCacheManager和org springframework cache ehcache EhCacheManagerFactoryBean会同时找不
  • CC3200之GPIO引脚分析

    预备知识 xff1a xff08 1 xff09 volatile关键字 xff1a volatile定义的变量一般为无需开发者自己赋值 xff0c 会自动改变的变量 在普通的程序中 xff0c 编译器都具有优化功能 xff0c 为了避免浪
  • OpenStack 之 OVS介绍

    一 概述 Open vSwitch的官方定义 xff1a Open vSwitch是一个具有工业级质量的多层虚拟交换机 通过可编程扩展 xff0c 可以实现大规模网络的自动化 xff08 配置 管理 维护 xff09 它支持现有标准管理接口
  • OVN是OVS 5倍的性能--性能测试报告

    我们已经对OVN做了许多次的性能测试 xff0c 但是缺少一个OVN和 xff08 ML2 43 OVS xff09 的性能对比测试 我和许多人一起对比了这2种后端 本文是第一部分 xff1a 控制平面的性能对比 后面会另外发文公布数据平面
  • OpenStack 中的5种分配IPv6地址的方式

    在OpenStack Pike版本中创建IPv6子网时 xff0c 有五种设置地址方式供选择 上图中这五种方式显示不全 xff0c 现将其全部展示 No options specified xff08 Default xff09 xff0c
  • STM32 | TCP通信实例分析

    1024G 嵌入式资源大放送 xff01 包括但不限于C C 43 43 单片机 Linux等 关注微信公众号 嵌入式大杂烩 xff0c 回复1024 xff0c 即可免费获取 xff01 前言 关于socket的笔记 xff0c 之前已经
  • RT-Thread和Freertos的区别?

    关注 嵌入式大杂烩 xff0c 选择 星标公众号 一起进步 xff01 Freertos是一个国外推出的一个迷你的实时操作系统内核 xff0c 开源 xff0c 功能包括 xff1a 任务管理 时间管理 信号量 消息队列 内存管理 记录功能
  • C语言 | 函数指针作为函数的参数

    1024G 嵌入式资源大放送 xff01 包括但不限于C C 43 43 单片机 Linux等 关注微信公众号 嵌入式大杂烩 xff0c 回复1024 xff0c 即可免费获取 xff01 函数指针有两种常用的用法 xff0c 一种是作为结
  • 解析I2C通信协议

    一 I2C的概念 1 I2C总线是PHLIPS公司推出的一种串行总线 xff0c I2C总线只有两根双向信号线 其中一根是数据线SDA xff0c 另一根是时钟线SCL 2 每个接到I2C总线上的器件都有唯一的地址 发送数据到总线上的称为发
  • uCOS-II任务间通信之信号量 [转载]

    uCOS II任务间通信之信号量 信号量是什么 xff1f 信号量有什么用 xff1f 信号量是可以用来表示一个或多个事件的发生 xff0c 还可以用来对共享资源的访问 uCOS II提供了5个对信号量进行操作的函数 如下所示 xff1a
  • 关于STM32串口3的使用,接收并解析一帧数据

    关于STM32串口3的使用 xff0c 接收并解析一帧数据 当stm32的串口1被使用时 xff0c 我们可以使用其他串口来使用 步骤 xff1a 串口3定义 初始化 xff1b 串口3中断服务函数 接收的一帧数据并判断是否正确 xff1b
  • Windows Docker Desktop 无法启动报错 Docker Desktop is shutting down 的可能解决办法

    之前有一次 docker 启动到一半的时候电脑蓝屏了 xff0c 电脑重启之后 docker 就无法启动了 xff0c 一直报错 Docker Desktop is shutting down 网上查了一下 xff0c 发现一个可能的解决办
  • ESP8266的开发环境搭建、解决编译[Makefile:xxx: .subdirs] Error 2错误问题

    ESP8266的开发环境搭建 解决编译错误问题 ESP8266的开发环境搭建链接如下 ESP8266的开发环境搭建 在最后工程加载完毕后右击该工程 xff0c 在弹出的列表中选择 Build Project 编译工程 xff0c 如果在Co
  • 【数字图像处理】YUV420转RGB并BMP存储<纯C++实现>

    1 读取akiyo qcif yuv YUV420文件 xff0c 按帧读取 xff0c 转RGB xff0c 并存储到BMP文件 2 暂时实现读取一帧并存储一张BMP图片 若要读取YUV序列 xff0c 写成循环方式即可 3 生成的BMP