C/C++ 图像二进制存储与读取
本系列文章由 @yhl_leo 出品,转载请注明出处。
文章链接: http://blog.csdn.net/yhl_leo/article/details/50782792
在深度学习时,制作样本数据集时,需要产生和读取一些二进制图像的数据集,如MNIST,CIFAR-10等都提供了适合C语言的二进制版本。
以CIFAR-10的数据集为例,官网上有两段关键的介绍:
二进制版本数据集格式为(图像大小为32x32):
<1 x label><3072 x pixel>
...
<1 x label><3072 x pixel>
In other words, the first byte is the label of the first image, which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image. The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue. The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image.
由此,绘制一个简图:
根据图像大小32x32 = 1024,不难知道,每个颜色值存储为1 byte,因此,对于单个图像的二进制存储与读取(先不管RGB颜色存储顺序),找了一张32x32的彩色lena图像,如下实现:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
void main()
{
FILE *fpw = fopen( "E:\\patch.bin", "wb" );
if ( fpw == NULL )
{
cout << "Open error!" << endl;
fclose(fpw);
return;
}
Mat image = imread("E:\\lena32.jpg");
if ( !image.data || image.channels() != 3 )
{
cout << "Image read failed or image channels isn't equal to 3."
<< endl;
return;
}
// write image to binary format file
int labelw = 1;
int rows = image.rows;
int cols = image.cols;
fwrite( &labelw, sizeof(char), 1, fpw );
char* dp = (char*)image.data;
for ( int i=0; i<rows*cols; i++ )
{
fwrite( &dp[i*3], sizeof(char), 1, fpw );
fwrite( &dp[i*3+1], sizeof(char), 1, fpw );
fwrite( &dp[i*3+2], sizeof(char), 1, fpw );
}
fclose(fpw);
// read image from binary format file
FILE *fpr = fopen( "E:\\patch.bin", "rb" );
if ( fpr == NULL )
{
cout << "Open error!" << endl;
fclose(fpr);
return;
}
int labelr(0);
fread( &labelr, sizeof(char), 1, fpr );
cout << "label: " << labelr << endl;
Mat image2( rows, cols, CV_8UC3, Scalar::all(0) );
char* pData = (char*)image2.data;
for ( int i=0; i<rows*cols; i++ )
{
fread( &pData[i*3], sizeof(char), 1, fpr );
fread( &pData[i*3+1], sizeof(char), 1, fpr );
fread( &pData[i*3+2], sizeof(char), 1, fpr );
}
fclose(fpr);
imshow("1", image2);
waitKey(0);
}
运行结果如下:
再看图片属性:
与官网上的大小3073一致,那么这么存取应该没问题。
严格按照官网的RGB通道分别存储,略作修改就可以实现:
/* for ( int i=0; i<rows*cols; i++ )
{
fwrite(&dp[i*3], sizeof(char), 1, fpw);
fwrite(&dp[i*3+1], sizeof(char), 1, fpw);
fwrite(&dp[i*3+2], sizeof(char), 1, fpw);
}
*/
for ( int i=0; i<rows*cols; i++ )
fwrite(&dp[i*3+2], sizeof(char), 1, fpw); // R
for ( int i=0; i<rows*cols; i++ )
fwrite(&dp[i*3+1], sizeof(char), 1, fpw); // G
for ( int i=0; i<rows*cols; i++ )
fwrite(&dp[i*3], sizeof(char), 1, fpw); // B
存储和读取多张图片方法类似,这里就不做介绍。
本文已同步于GitHub:yhlleo/image2binarytest
C/C++ 图像二进制存储与读取的更多相关文章
- SQLite数据库如何存储和读取二进制数据
SQLite数据库如何存储和读取二进制数据 1. 存储二进制数据 SQLite提供的绑定二进制参数接口函数为: int sqlite3_bind_blob(sqlite3_stmt*, int, co ...
- .NET中二进制图片的存储与读取
判断HttpContext是否为空: string configPath = "img/defaultPhoto.png"; if (HttpContext.Current != ...
- .Net下二进制形式的文件存储与读取
.Net下图片的常见存储与读取凡是有以下几种:存储图片:以二进制的形式存储图片时,要把数据库中的字段设置为Image数据类型(SQL Server),存储的数据是Byte[].1.参数是图片路径:返回 ...
- [TFRecord格式数据]利用TFRecords存储与读取带标签的图片
利用TFRecords存储与读取带标签的图片 原创文章,转载请注明出处~ 觉得有用的话,欢迎一起讨论相互学习~Follow Me TFRecords其实是一种二进制文件,虽然它不如其他格式好理解,但是 ...
- 在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。
在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除. 作者:邵盛松 2009-09-05 前言 1关于的BLOB(Binary)数据的存储和读取功能主要参考了MSDN上的一篇& ...
- MFC用串行化实现文档存储和读取功能
在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...
- Python3基础 pickle.dump和load 对一个对象进行序列化存储及读取
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- numpy中文件的存储和读取-嵩天老师笔记
numpy中csv文件的存储和读取 CSV文件:(Comma‐Separated Value, 逗号分隔值) 一维和二维数组 存储 np.savetxt(frame,array,fmt='%.18e' ...
- Numpy用于数组数据的存储和读取
Python的Numpy模块可用于存储和读取数据: 1.将一个数组存储为二进制文件 Numpy.save:将一个数组以.npy的格式保存为二进制文件 调用格式:numpy.save(file, arr ...
随机推荐
- rac环境改动spfile后遭遇ora-29250小例
原创作品.出自 "深蓝的blog" 博客.转载时请务必注明出处,否则有权追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/ar ...
- 使用美橙主机建站(jsp+mysql+tomcat建站)
1.注冊美橙互联账号:http://www.cndns.com/ 2.选择橙云主机: 3.选择你须要的主机类型. 3.能够随时与客服进行沟通.购买完毕后登陆 管理中心 4.点击左边 主机类管理--&g ...
- vim插件系列
http://foocoder.com/blog/mei-ri-vimcha-jian-ping-hua-gun-dong-accelerated-smooth-scroll-dot-vim.html ...
- Intellij IDEA社区版打包Maven项目成war包,并部署到tomcat上
转自:https://blog.csdn.net/yums467/article/details/51660683 需求分析 我们利用 Intellij idea社区版IDE开发了一个maven的sp ...
- 使用python进行re拆分网页内容
这里简短的总结一下而不是完全的罗列python的re模块,python的re具有强大的功能,如下是一个从我们学校抓取数据然后拆分的程序,代码如下: import httplib import urll ...
- 8、List接口的特点及其相关功能
/* * Collection * |--List * 元素有序(指的是存储顺序和取出顺序是否一致),可重复. * |--Set * 元素无序,唯一. */ /* * List的特有功能: * A:添 ...
- java中字符串比较==和equals
1 总体来说java中字符串的比较是==比较引用,equals 比较值的做法.(equals 对于其他引用类型比较的是地址,这是因为object的equals方法比较的是引用),但是不同的声明方法字符 ...
- HBase编程 API入门系列之delete(管理端而言)(9)
大家,若是看过我前期的这篇博客的话,则 HBase编程 API入门之delete(客户端而言) 就知道,在这篇博文里,我是在客户端里删除HBase表的. 这里,我带领大家,学习更高级的,因为,在开发中 ...
- Super超级ERP系统---(6)采购管理--入库上架
采购商品入库完成后,下一步就是上架操作.所谓上架就是把入库放到移动托盘的商品转移到固定货架上,货架上有货位号,可以把商品放到指定的货位上.主要分两步操作,上架操作主要是移动PDA上完成的 1.扫描移 ...
- Docker installs
docker要求系统内核必须在3.10以上uname -r 命令查看你当前的内核版本 1.更新yum源并删除旧版docker yum remove docker docker-common docke ...