本系列文章由 @yhl_leo 出品,转载请注明出处。

文章链接: http://blog.csdn.net/yhl_leo/article/details/50782792


在深度学习时,制作样本数据集时,需要产生和读取一些二进制图像的数据集,如MNISTCIFAR-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++ 图像二进制存储与读取的更多相关文章

  1. SQLite数据库如何存储和读取二进制数据

    SQLite数据库如何存储和读取二进制数据 1. 存储二进制数据 SQLite提供的绑定二进制参数接口函数为: int sqlite3_bind_blob(sqlite3_stmt*, int, co ...

  2. .NET中二进制图片的存储与读取

    判断HttpContext是否为空: string configPath = "img/defaultPhoto.png"; if (HttpContext.Current != ...

  3. .Net下二进制形式的文件存储与读取

    .Net下图片的常见存储与读取凡是有以下几种:存储图片:以二进制的形式存储图片时,要把数据库中的字段设置为Image数据类型(SQL Server),存储的数据是Byte[].1.参数是图片路径:返回 ...

  4. [TFRecord格式数据]利用TFRecords存储与读取带标签的图片

    利用TFRecords存储与读取带标签的图片 原创文章,转载请注明出处~ 觉得有用的话,欢迎一起讨论相互学习~Follow Me TFRecords其实是一种二进制文件,虽然它不如其他格式好理解,但是 ...

  5. 在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。

    在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除. 作者:邵盛松 2009-09-05 前言 1关于的BLOB(Binary)数据的存储和读取功能主要参考了MSDN上的一篇& ...

  6. MFC用串行化实现文档存储和读取功能

    在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...

  7. Python3基础 pickle.dump和load 对一个对象进行序列化存储及读取

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. numpy中文件的存储和读取-嵩天老师笔记

    numpy中csv文件的存储和读取 CSV文件:(Comma‐Separated Value, 逗号分隔值) 一维和二维数组 存储 np.savetxt(frame,array,fmt='%.18e' ...

  9. Numpy用于数组数据的存储和读取

    Python的Numpy模块可用于存储和读取数据: 1.将一个数组存储为二进制文件 Numpy.save:将一个数组以.npy的格式保存为二进制文件 调用格式:numpy.save(file, arr ...

随机推荐

  1. 读取url中某个值

    url="http://test.plus.1course.cn/Task/Display?id=25942" print(url) result=url.split('/')[- ...

  2. Kafka集群部署及測试

    题记 眼下我们对大数据进行研究方向以Spark为主,当中Spark Streaming是能够接收动态数据流并进行处理.那么Spark Streaming支持多源的数据发送端,比如TCP.ZeroMQ. ...

  3. POJ3190 Stall Reservations 贪心

    这是个典型的线程服务区间模型.一些程序要在一段时间区间上使用一段线程运行,问至少要使用多少线程来为这些程序服务? 把所有程序以左端点为第一关键字,右端点为第二关键字从小到大排序.从左向右扫描.处理当前 ...

  4. modelstate.isvalid false

    http://stackoverflow.com/questions/1791570/modelstate-isvalid-false-why 第一个 About "can it be th ...

  5. 中文分词--最大正向与逆向匹配算法python实现

    最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描).例如:词典中 ...

  6. 2014.9.20Hashtable概述

    hashtable叫哈希表,用于表示键值的集合,这些键值对根据键的哈希代码进行组织,其每个元素都存储于DictionaryEntry对象中的键值对.键不能为空引用. count:获取包含在hashta ...

  7. hihoCoder-1828 2018亚洲区预选赛北京赛站网络赛 A.Saving Tang Monk II BFS

    题面 题意:N*M的网格图里,有起点S,终点T,然后有'.'表示一般房间,'#'表示毒气房间,进入毒气房间要消耗一个氧气瓶,而且要多停留一分钟,'B'表示放氧气瓶的房间,每次进入可以获得一个氧气瓶,最 ...

  8. 批量插入 SqlBulkCopy的测试

    关于SqlBulkCopy的测试 最近要做.net关于sql大量插入,找到了sqlbulkcopy(自己google下,应该很多说明了)这个好东西,于是测试下性能,用了三个方法对比: 1)直接用ado ...

  9. 从Android源码分析View绘制

    在开发过程中,我们常常会来自定义View.它是用户交互组件的基本组成部分,负责展示图像和处理事件,通常被当做自定义组件的基类继承.那么今天就通过源码来仔细分析一下View是如何被创建以及在绘制过程中发 ...

  10. showdialog

    在C#中窗口的显示有两种方式:模态显示(showdialog)和非模态显示(show). 区别: 模态与非模态窗体的主要区别是窗体显示的时候是否可以操作其他窗体.模态窗体不允许操作其他窗体,非模态窗体 ...