ubuntu下使用C++生成cifar10二进制格式的数据
来源:互联网 发布:苏州php培训 编辑:程序博客网 时间:2024/06/04 19:07
作者:石炜贤&曾翔钰
注:本篇博客代码需要使用opencv,如果还没配置,可以参照这篇博客:
http://blog.csdn.net/code_better/article/details/53287587
学习了tensorflow后我们知道,tensorflow中训练卷积神经网络用的数据是cifar-10的bin版本的。可是我们手上有的只是一堆图片,那我们如何才能将其转化为这种格式的数据呢?
在cifar-10数据官网中查看数据格式后我们知道,其图片大小为32*32,每一个训练样本的大小是3073个字节,其中,第一个字节为label,label的值为0-9。其后的每1024个字节分别为R,G,B三个通道的值。且存储顺序为行主顺序,故3072中的前32个字节为R通道的第一行像素的值。还有一个batches.meta.txt文件,里面存储这label(0-9,充当真正标签的索引)对应的值。
如下图:
好了,进入主题吧~
主要流程:
①得到图片文件名列表,构建标签(label),这二者均是vector对象;
②使用opencv得到图片每个像素的三个通道的值,同时将标签和像素值写入文件。
简单吧,来看看代码。
主体代码:
#include "BinaryDataset.h"using namespace cv;void BinaDataset::images2BinaryFile( std::string filefolder, std::vector<std::string> &img_list, std::vector<int> &img_labels, std::string filename) { const int size_list = img_list.size(); FILE *fp = fopen(filename.c_str(), "wb"); if (fp == NULL) { std::cout << "Open error!" << std::endl; fclose(fp); return; } for (int idx = 0; idx < size_list; ++idx) { std::string currentPath = filefolder; currentPath += img_list[idx]; mat2Binary(currentPath, img_labels[idx], fp);#if 1 std::cout << "image " << idx + 1 << " saved." << std::endl;#endif } fclose(fp);}void BinaDataset::mat2Binary( std::string &image_file, int label, FILE *&fp) { cv::Mat image = cv::imread(image_file, IMREAD_UNCHANGED); if (!image.data) { std::cout << "Image " << getFileName(image_file) << " load failed!" << std::endl; } else { if (image.channels() == 1) { //如果是灰度图 //转化为RGB真彩图 cv::cvtColor(image, image, CV_GRAY2RGB); } else { cv::cvtColor(image, image, CV_BGR2RGB); } cv::Mat image_reshaped; //缩放成固定大小 cv::resize(image, image_reshaped, cv::Size(_iWidth, _iHeight), CV_INTER_LINEAR); convertMat2Bin(image_reshaped, label, fp); }}/** * 将图片转化为矩阵并将每个元素写入二进制文件 * @param image * @param label * @param fp */void BinaDataset::convertMat2Bin(cv::Mat &image, int label, FILE *&fp) { //写入标签 fwrite(&label, sizeof(char), 1, fp); //像素个数 int pixelCount = image.rows * image.cols; //像素的值 char *pData = (char *) image.data; //写入图片的三个通道值 for (int i = 0; i < pixelCount; i++) fwrite(&pData[i * 3], sizeof(char), 1, fp); // R for (int i = 0; i < pixelCount; i++) fwrite(&pData[i * 3 + 1], sizeof(char), 1, fp); // G for (int i = 0; i < pixelCount; i++) fwrite(&pData[i * 3 + 2], sizeof(char), 1, fp); // B}/** * 得到文件名列表 * @param file_folder * @return */std::vector<std::string> BinaDataset::getFileLists(string file_folder) { const char *mystr = file_folder.c_str(); std::vector<std::string> flist; std::string lineStr; std::vector<std::string> extendName; extendName.push_back("jpg"); extendName.push_back("JPG"); extendName.push_back("bmp"); extendName.push_back("png"); extendName.push_back("gif"); wchar_t fn[1000]; mbstowcs(fn, mystr, 999); DIR *dir; struct dirent *ptr; if ((dir = opendir(file_folder.c_str())) == NULL) { perror("打开文件夹失败..."); exit(1); } while ((ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) ///current dir OR parrent dir continue; else if (ptr->d_type == 8) { //文件 lineStr = ptr->d_name; for (int i = 0; i < 4; i++) { if (lineStr.find(extendName[i]) < 999) { flist.push_back(lineStr); break; } } } } return flist;}/** * 裁剪文件的路径名,得到文件的名称 * @param filename 文件路径 * @return */std::string BinaDataset::getFileName(std::string &filename) { int iBeginIndex = filename.find_last_of("/") + 1; int iEndIndex = filename.length(); return filename.substr(iBeginIndex, iEndIndex - iBeginIndex);}
头文件:
#ifndef BINARY_DATASET_H#define BINARY_DATASET_H#pragma once#include <iostream>#include <vector>#include <stdio.h>#include <stdlib.h>#include "string.h"#include <stdio.h>#include <dirent.h>#include <iostream>#include <vector>#include <string.h>#include <algorithm>#include "cv.h"#include "highgui.h"using namespace std;using namespace cv;class BinaDataset {public: BinaDataset() { _iHeight = 32; _iWidth = 32; }public: void images2BinaryFile(std::string filefolder, std::vector<std::string> &img_list, std::vector<int> &img_labels, std::string filename); void mat2Binary(std::string &image_file, int label, FILE *&fp); void convertMat2Bin(cv::Mat &image, int label, FILE *&fp); std::string getFileName(std::string &filename); std::vector<std::string> getFileLists(std::string file_folder);public: int _iHeight; int _iWidth;};#endif // BINARY_DATASET_H
main方法所在文件:
#include "BinaryDataset.h"int main() { std::string filefolder = "/home/weixain/workspace/Clion/cifar2/Samples/train/"; BinaDataset binData; std::vector<std::string> fileLists = binData.getFileLists(filefolder); // load file name const int size_list = fileLists.size(); std::cout << "image count: " << size_list << std::endl; std::vector<int> image_labels(size_list, 0); // generate lables, here are all 0 std::string binfile = "/home/weixain/workspace/Clion/cifar2/Samples/data_batch_1.bin"; binData.images2BinaryFile(filefolder, fileLists, image_labels, binfile); return 0;}
献上完整的项目(Clion项目):
http://download.csdn.net/detail/code_better/9778433
本篇博客参考资料:
http://blog.csdn.net/yhl_leo/article/details/50801226
http://blog.csdn.net/u012005313/article/details/50687297
感谢这两篇博客的帮忙。
- ubuntu下使用C++生成cifar10二进制格式的数据
- Ubuntu下CIFAR10训练过程
- 4用于cifar10的卷积神经网络-4.4/4.5cifar10数据集读取和数据增强扩充(上/下)
- QT 下 json格式数据的 生成 和 解析
- 利用bitset处理二进制格式的数据
- C类对象的二进制格式
- Windows-Caffe Cifar10模型的生成
- Windows-Caffe Cifar10模型的生成
- caffe使用cifar10数据集问题记录
- PHP扩展模块解包(由term_to_binary生成的)Erlang ext term格式的二进制数据
- cifar10数据集的读取Python/Tensorflow
- python实现cifar10数据集的可视化
- tensorflow cifar10数据集的测试
- python显示cifar10数据集中的图片
- python实现cifar10数据集的可视化
- ubuntu eclipse下生成caffe的C/C++ classification工程
- Ubuntu下C-kermit的使用
- ubuntu下C语言的使用
- Ant path匹配规则
- Cocos2dx中英文混合字符串截取
- mqtt服务搭建
- provider: SQL Network Interfaces, error: 26 - 定位指定的服务器/实例时出错
- Linux下设置环境变量
- ubuntu下使用C++生成cifar10二进制格式的数据
- PHP开发web应用安全总结
- 对称加密与非对称加密
- 本地Pypi源搭建
- Poedu_C语言_Lesson25_20161007_字符串处理函数(2)
- Java内存区域与内存溢出(一)
- nginx源代码分析 - 启动(四) 创建后台进程和worker进程
- JS、JQuery和ExtJs的跨域处理
- SDL 崩溃问题