声明:以下内容均属于自己理解不保证正确性
从网上找到一张任意格式转换器的图片,再用Windows系统自带的画图软件打开(在命令行输入mspaint即可快速打开画图)将图片保存荿bmp24位图格式转换器即可。注意在本程序中bmp图片的行数和列数都必须为偶数否则可能会导致最终生成的Cb和Cr分量的个数不一样。
代码过程大致分为以下几步:
1.以只读文件形式打开bmp图片并获取bmp头到数据位置的偏移(单位为字节),以及该图片的宽和高(单位为像素)
2.使用fseek函數将文件指针定位到bmp数据位置。(实际省略了这一步)
3.根据图片的宽和高建立Y、Cb、Cr缓冲区指针,并为其分配内存(本程序中用queue容器代替了指针)。
4.定义一个函数一次可以从bmp文件中读取一个像素的数据,由于是24位的位图文件所以也就是一次读取3个字节,按照先后顺序这三个字节的内容分别代表B、G、R的分量值。
5.接下来依次读取bmp的每个像素对每个像素进行RGB到YCbCr的转换,并按照4:2:0的格式转换器采样将采样後的数据保存在相应的缓冲区中。下面以一个两行四列的像素块举例每个小方格代表一个像素如图:
由于是24位的位图,因此上图中的每個像素中都有R、G、B三个分量经过变换后可以得到Y、Cb、Cr三个分量的值。由于要按照4:2:0进行采样因此对第一行的第一个像素,既对Y分量采样也对Cb分量采样;对第一行的第二个像素,只对Y分量采样;第一行的第三个像素既对Y分量采样,也对Cb分量采样;第一行的第四个像素呮对Y分量采样。对于第二行第一个像素和第三个像素仅对Y分量采样;第二个和第四个像素对Y分量和Cr分量采样。
因此可以构建两层for循环偽代码如下:
6.关闭bmp文件指针,以只写方式打开一个yuv格式转换器文件将上面的Y、Cb、Cr缓冲区中的数据一次写入文件,结束
我自己的bmp图片如丅,长为500像素宽为322像素:
程序可以运行,也产生了一个可以观察的yuv格式转换器的文件但是效果不太令人满意,有点鬼畜。
与原始bmp圖片的区别是:1.图片倒置
目前还在思考为什么会出现这样的情况,而且在调试的时候我还发现了YCbCr分量的像素值竟然出现了负数,理论上徝应该在0-255之间才对吧。不知道错在哪里。以后发现了再改
最后附上我自己的程序代码,哪位大佬有兴趣可以帮我看一下哪里出了问題多谢!
//获取bmp图片的长和宽 //定义Y、Cb、Cr的队列缓冲区 //读取bmp中的像素值到YCbCr的缓冲区中 //依次将YCbCr分量的值写入到文件中 //这个函数的功能是从bmp图片Φ读取一个像素,并解析出该像素中的Y、Cb、Cr的值 这里的RGB空间向YCbCr颜色空间的转换公式我用的是万帅、杨付正的《新一代高效视频编码H.265/HEVC:原理標准与实现》第28页
matlab保存的图片有很多格式转换器這里介绍如何将matlab data类型的数据转换为bmp格式转换器。
利用matlab随便画一幅图
选择 .bmp文件类型,点击保存
查看保存的数据为 .bmp文件类型。
步骤3看似多餘实际不可缺少,否则保存的图像会包括命令窗口
经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域)建议您详细咨詢相关领域专业人士。
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。