"mindspore\lite\examples\transfer_learning\src\dataset.cc"注释1

** "mindspore\lite\examples\transfer_learning\src\dataset.cc"注释1**

一、代码用处

该代码块主要用于读取图片文件

二、代码注释

#include "src/dataset.h"  //导入下相关头文件
#include <dirent.h>
#include <arpa/inet.h>
#include <map>
#include <iostream>
#include <fstream>
#include <memory>
#include "src/utils.h"

#pragma pack(push, 1)

typedef struct {  typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。此处定义一个结构体
  uint16_t type;  // Magic identifier: 0x4d42
  uint32_t size;
  uint16_t reserved1;
  uint16_t reserved2;
  uint32_t offset;
  uint32_t dib_header_size;
  int32_t width;
  int32_t height;
  uint16_t channels;
  uint16_t bits_per_pixel;
  uint32_t compression;
  uint32_t image_size_bytes;
  int32_t x_resolution_ppm;
  int32_t y_resolution_ppm;
  uint32_t num_colors;
  uint32_t important_colors;
} bmp_header;//位图文件头  提供文件的格式、大小等信息

#pragma pack(pop)

float CH_MEAN[3] = {0.485, 0.456, 0.406};//定义两个数组
float CH_STD[3] = {0.229, 0.224, 0.225};

using LabelId = std::map<std::string, int>;//更新数据类型

static char *ReadBitmapFile(const std::string &filename, size_t *size) {//定义一个静态方法读取位图文件
  MS_ASSERT(size != nullptr);
  *size = 0;
  bmp_header bitmap_header;
  std::ifstream ifs(filename);//打开指定文件
  if (!ifs.good() || !ifs.is_open()) {//判断文件是否打开成功
    std::cerr << "file: " << filename << " does not exist or failed to open";
    return nullptr;
  }

  ifs.read(reinterpret_cast<char *>(&bitmap_header), sizeof(bmp_header));//读取相应数据
  if (bitmap_header.type != 0x4D42) {
    std::cerr << "file: " << filename << " magic number does not match BMP";
    ifs.close();
    return nullptr;
  }

  ifs.seekg(bitmap_header.offset, std::ios::beg);//文件输入流(ifstream)读到文件尾之后,调用seekg 重定向 读pos

  unsigned char *bmp_image = reinterpret_cast<unsigned char *>(malloc(bitmap_header.image_size_bytes));// reinterpret_cast强制转换类型
  if (bmp_image == nullptr) {//判断是否转换成功
    ifs.close();
    return nullptr;
  }

  ifs.read(reinterpret_cast<char *>(bmp_image), bitmap_header.image_size_bytes);//读取该图片

  size_t buffer_size = bitmap_header.width * bitmap_header.height * 3;//计算图片的大小
  float *hwc_bin_image = new (std::nothrow) float[buffer_size];//在内存不足时,new (std::nothrow)并不抛出异常,而是将指针置NULL
  if (hwc_bin_image == nullptr) {
    free(bmp_image);
    ifs.close();
    return nullptr;
  }

  // 交换 R 和 B 值以获得 RGB(位图为 BGR)
  // 交换列(在 BMP 中,第一个像素在左下角......)
  const size_t channels = 3;
  const size_t hStride = channels * bitmap_header.width;
  const size_t height = bitmap_header.height;

  for (int h = 0; h < bitmap_header.height; h++) {//进行交换
    for (int w = 0; w < bitmap_header.width; w++) {
      hwc_bin_image[h * hStride + w * channels + 0] =
        (((static_cast<float>(bmp_image[(height - h - 1) * hStride + w * channels + 2])) / 255.0) - CH_MEAN[0]) /
        CH_STD[0];
      hwc_bin_image[h * hStride + w * channels + 1] =
        (((static_cast<float>(bmp_image[(height - h - 1) * hStride + w * channels + 1])) / 255.0) - CH_MEAN[1]) /
        CH_STD[1];
      hwc_bin_image[h * hStride + w * channels + 2] =
        (((static_cast<float>(bmp_image[(height - h - 1) * hStride + w * channels + 0])) / 255.0) - CH_MEAN[2]) 
        CH_STD[2];
    }
  }

  *size = buffer_size * sizeof(float);
  free(bmp_image);
  ifs.close();
  char *ret_buf = reinterpret_cast<char *>(hwc_bin_image);
  return ret_buf;//返回图片数据
}
上一篇:1329:【例8.2】细胞


下一篇:教你彻底搞懂Cocos Creator Tween