** "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;//返回图片数据
}