深度学习框架Caffe学习笔记(4)-MNIST数据集转换成可视化图片

MNIST图片文件格式

train-images-idx3-ubyte

文件偏移量 数据类型 描述
0000 32位整型 2051 魔数(大端存储)
0004 32位整型 60000 文件包涵条目总数
0008 32位整型 28 行数
0012 32位整型 28 列数
0016 8位字节 像素值(0~255)
0017 8位字节 像素值(0~255)

train-labels-idx1-ubyte

文件偏移量 数据类型 描述
0000 32位整型 2051 魔数(大端存储)
0004 32位整型 60000 文件包涵条目总数
0008 8位字节 标签值(0~9)
0009 8位字节 标签值(0~9)

测试集的数据格式和训练及相同

MNIST数据集格式转换

在训练网络前我们使用create_mnist.sh脚本将MNIST数据集转换成lmdb格式,在该脚本中调用了convert_mnist_data.bin,这个可执行文件的源代码在examples/mnist/convert_mnist_data.cpp中。通过修改convert_mnist_data.cpp中的代码,可以将MNIST数据集转换成图片。在examples/mnist/目录下新建convert_mnist_image.cpp文件,内容如下:

// This script converts the MNIST dataset to image (png) format
// Usage:
//    convert_mnist_image [FLAGS] input_image_file output_png_file
// The MNIST dataset could be downloaded at
//    http://yann.lecun.com/exdb/mnist/

#include <gflags/gflags.h>
#include <glog/logging.h>

#include <stdint.h>
#include <sys/stat.h>

#include <fstream>  // NOLINT(readability/streams)
#include <string>

#include "opencv2/core/core.hpp"  
#include "opencv2/highgui/highgui.hpp"  
#include "opencv2/imgproc/imgproc.hpp" 

using std::string;

DEFINE_int32(rows, 25, "The rows of index in image");
DEFINE_int32(cols, 40, "The cols of index in image");
DEFINE_int32(offset, 0, "The offset of index in raw image");

//大端模式小端模式转换
uint32_t swap_endian(uint32_t val) {
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
    return (val << 16) | (val >> 16);
}

//数据集转换函数,输入参数:MNIST数据集文件,图片文件
void convert_image(const char* image_filename, const char* png_filename) {
  // Open files
  std::ifstream image_file(image_filename, std::ios::in | std::ios::binary);
  CHECK(image_file) << "Unable to open file " << image_filename;
  // Read the magic and the meta data
  uint32_t magic;
  uint32_t num_items;
  uint32_t rows;
  uint32_t cols;

  //读取魔数
  image_file.read(reinterpret_cast<char*>(&magic), 4);
  magic = swap_endian(magic);
  CHECK_EQ(magic, 2051) << "Incorrect image file magic.";
  //读取数据条目总数
  image_file.read(reinterpret_cast<char*>(&num_items), 4);
  num_items = swap_endian(num_items);
  //读取行数
  image_file.read(reinterpret_cast<char*>(&rows), 4);
  rows = swap_endian(rows);
  //读取列数
  image_file.read(reinterpret_cast<char*>(&cols), 4);
  cols = swap_endian(cols);

  //命令行参数读取
  const int flag_rows = FLAGS_rows;
  const int flag_cols = FLAGS_cols;
  const int offset = FLAGS_offset;
  const int width = flag_cols*cols;
  const int height = flag_rows*rows;

  char* pixels = new char[rows * cols];
  cv::Mat tp = cv::Mat::zeros(height, width, CV_8UC1);
  //使用读取MINST数据,写入到opencv中的Mat类对象中
  image_file.seekg(offset*rows*cols, std::ios::cur);
  for(int i=0; i<flag_rows; i++) {
    for(int j=0; j<flag_cols; j++) {
      if(!image_file.eof()) {
        image_file.read(pixels, rows * cols);
        for(int k=0; k<rows; k++) {
          for(int l=0; l<cols; l++) {
            tp.at<uchar>(k + i*rows, j*cols + l) = (int)pixels[k*cols+l]; 
          }
        }
      }
      else {
        for(int k=0; k<rows; k++) {
          for(int l=0; l<cols; l++) {
            tp.at<uchar>(k + i*rows, j*cols + l) = 0; 
          }
        }
      }
    }
  }
  //调用opencv中的函数保存图片
  cv::imwrite(png_filename, tp); 
}

int main(int argc, char** argv) {
#ifndef GFLAGS_GFLAGS_H_
  namespace gflags = google;
#endif

  FLAGS_alsologtostderr = 1;
  // 设设置命令行参数帮助信息
  gflags::SetUsageMessage("This script converts the MNIST dataset to\n"
        "image(png) format.\n"
        "Usage:\n"
        "    convert_mnist_data [FLAGS] input_image_file "
        "output_png_file\n"
        "The MNIST dataset could be downloaded at\n"
        "    http://yann.lecun.com/exdb/mnist/\n"
        "You should gunzip them after downloading,"
        "or directly use data/mnist/get_mnist.sh\n");
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  if (argc != 3) {
    gflags::ShowUsageWithFlagsRestrict(argv[0],
        "examples/mnist/convert_mnist_data");
  } else {
    google::InitGoogleLogging(argv[0]);
    //转换图片
    convert_image(argv[1], argv[2]);
  }
  return 0;
}

在Caffe根目录下执行make命令就可以完成该文件的编译

$ make

在build/examples/mnist/目录下会生成convert_mnist_image.bin文件。通过执行这个文件可以生成图片。

$ ./build/examples/mnist/convert_mnist_image.bin data/mnist/train-images-idx3-ubyte examples/mnist/image.png

执行该命令后输出如下图片:
这里写图片描述
图片默认横向40个数据,纵向25个数据。可以加命令行参数,如-cols=20 -rows=15改变图像大小为横向20个数据,纵向15个数据。

阅读更多
个人分类: 深度学习
上一篇深度学习框架Caffe学习笔记(3)-MNIST例程深入
下一篇深度学习框架Caffe学习笔记(5)-使用gflags解析命令行参数
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭