lable_img里面有个读取文件的信息
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <unistd.h> // NOLINT(build/include_order)
#include "tensorflow/contrib/lite/examples/label_image/bitmap_helpers.h"
#define LOG(x) std::cerr
namespace tflite {
namespace label_image {
uint8_t* decode_bmp(const uint8_t* input, int row_size, uint8_t* const output,
int width, int height, int channels, bool top_down) {
for (int i = 0; i < height; i++) {
int src_pos;
int dst_pos;
for (int j = 0; j < width; j++) {
if (!top_down) {
src_pos = ((height - 1 - i) * row_size) + j * channels;
} else {
src_pos = i * row_size + j * channels;
}
dst_pos = (i * width + j) * channels;
switch (channels) {
case 1:
output[dst_pos] = input[src_pos];
break;
case 3:
// BGR -> RGB
output[dst_pos] = input[src_pos + 2];
output[dst_pos + 1] = input[src_pos + 1];
output[dst_pos + 2] = input[src_pos];
break;
case 4:
// BGRA -> RGBA
output[dst_pos] = input[src_pos + 2];
output[dst_pos + 1] = input[src_pos + 1];
output[dst_pos + 2] = input[src_pos];
output[dst_pos + 3] = input[src_pos + 3];
break;
default:
LOG(FATAL) << "Unexpected number of channels: " << channels;
break;
}
}
}
return output;
}
uint8_t* read_bmp(const std::string& input_bmp_name, int* width, int* height,
int* channels, Settings* s) {
int begin, end;
std::ifstream file(input_bmp_name, std::ios::in | std::ios::binary);
if (!file) {
LOG(FATAL) << "input file " << input_bmp_name << " not found\n";
exit(-1);
}
begin = file.tellg();
file.seekg(0, std::ios::end);
end = file.tellg();
size_t len = end - begin;
if (s->verbose) LOG(INFO) << "len: " << len << "\n";
const uint8_t* img_bytes = new uint8_t[len];
file.seekg(0, std::ios::beg);
file.read((char*)img_bytes, len);
const int32_t header_size =
*(reinterpret_cast<const int32_t*>(img_bytes + 10));
*width = *(reinterpret_cast<const int32_t*>(img_bytes + 18));
*height = *(reinterpret_cast<const int32_t*>(img_bytes + 22));
const int32_t bpp = *(reinterpret_cast<const int32_t*>(img_bytes + 28));
*channels = bpp / 8;
if (s->verbose)
LOG(INFO) << "width, height, channels: " << *width << ", " << *height
<< ", " << *channels << "\n";
// there may be padding bytes when the width is not a multiple of 4 bytes
// 8 * channels == bits per pixel
const int row_size = (8 * *channels * *width + 31) / 32 * 4;
// if height is negative, data layout is top down
// otherwise, it's bottom up
bool top_down = (*height < 0);
// Decode image, allocating tensor once the image size is known
uint8_t* output = new uint8_t[abs(*height) * *width * *channels];
const uint8_t* bmp_pixels = &img_bytes[header_size];
return decode_bmp(bmp_pixels, row_size, output, *width, abs(*height),
*channels, top_down);
}
} // namespace label_image
} // namespace tflite
对应的头文件如下:
#ifndef TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_H_
#define TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_H_
#include "tensorflow/contrib/lite/examples/label_image/bitmap_helpers_impl.h"
#include "tensorflow/contrib/lite/examples/label_image/label_image.h"
namespace tflite {
namespace label_image {
uint8_t* read_bmp(const std::string& input_bmp_name, int* width, int* height,
int* channels, Settings* s);
template <class T>
void resize(T* out, uint8_t* in, int image_height, int image_width,
int image_channels, int wanted_height, int wanted_width,
int wanted_channels, Settings* s);
// explicit instantiation
template void resize<uint8_t>(uint8_t*, unsigned char*, int, int, int, int, int,
int, Settings*);
template void resize<float>(float*, unsigned char*, int, int, int, int, int,
int, Settings*);
} // namespace label_image
} // namespace tflite
#endif // TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_H
resize是自定义的一个函数,直接在头文件中就申明定义了。
#ifndef TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_IMPL_H_
#define TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_IMPL_H_
#include "tensorflow/contrib/lite/builtin_op_data.h"
#include "tensorflow/contrib/lite/interpreter.h"
#include "tensorflow/contrib/lite/kernels/register.h"
#include "tensorflow/contrib/lite/string_util.h"
#include "tensorflow/contrib/lite/version.h"
#include "tensorflow/contrib/lite/builtin_op_data.h"
#include "tensorflow/contrib/lite/interpreter.h"
#include "tensorflow/contrib/lite/kernels/register.h"
#include "tensorflow/contrib/lite/string_util.h"
#include "tensorflow/contrib/lite/version.h"
#include "tensorflow/contrib/lite/examples/label_image/label_image.h"
namespace tflite {
namespace label_image {
template <class T>
void resize(T* out, uint8_t* in, int image_height, int image_width,
int image_channels, int wanted_height, int wanted_width,
int wanted_channels, Settings* s) {
int number_of_pixels = image_height * image_width * image_channels;
std::unique_ptr<Interpreter> interpreter(new Interpreter);
int base_index = 0;
// two inputs: input and new_sizes
interpreter->AddTensors(2, &base_index);
// one output
interpreter->AddTensors(1, &base_index);
// set input and output tensors
interpreter->SetInputs({0, 1});
interpreter->SetOutputs({2});
// set parameters of tensors
TfLiteQuantizationParams quant;
interpreter->SetTensorParametersReadWrite(
0, kTfLiteFloat32, "input",
{1, image_height, image_width, image_channels}, quant);
interpreter->SetTensorParametersReadWrite(1, kTfLiteInt32, "new_size", {2},
quant);
interpreter->SetTensorParametersReadWrite(
2, kTfLiteFloat32, "output",
{1, wanted_height, wanted_width, wanted_channels}, quant);
ops::builtin::BuiltinOpResolver resolver;
TfLiteRegistration* resize_op =
resolver.FindOp(BuiltinOperator_RESIZE_BILINEAR);
auto* params = reinterpret_cast<TfLiteResizeBilinearParams*>(
malloc(sizeof(TfLiteResizeBilinearParams)));
params->align_corners = false;
interpreter->AddNodeWithParameters({0, 1}, {2}, nullptr, 0, params, resize_op,
nullptr);
interpreter->AllocateTensors();
// fill input image
// in[] are integers, cannot do memcpy() directly
auto input = interpreter->typed_tensor<float>(0);
for (int i = 0; i < number_of_pixels; i++) {
input[i] = in[i];
}
// fill new_sizes
interpreter->typed_tensor<int>(1)[0] = wanted_height;
interpreter->typed_tensor<int>(1)[1] = wanted_width;
interpreter->Invoke();
auto output = interpreter->typed_tensor<float>(2);
auto output_number_of_pixels =
wanted_height * wanted_height * wanted_channels;
for (int i = 0; i < output_number_of_pixels; i++) {
if (s->input_floating)
out[i] = (output[i] - s->input_mean) / s->input_std;
else
out[i] = (uint8_t)output[i];
}
}
} // namespace label_image
} // namespace tflite
#endif // TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_BITMAP_HELPERS_IMPL_H_
get_top_n也是外部定义的一个函数
#ifndef TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_H
#define TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_H
#include "tensorflow/contrib/lite/examples/label_image/get_top_n_impl.h"
namespace tflite {
namespace label_image {
template <class T>
void get_top_n(T* prediction, int prediction_size, size_t num_results,
float threshold, std::vector<std::pair<float, int>>* top_results,
bool input_floating);
// explicit instantiation so that we can use them otherwhere
template void get_top_n<uint8_t>(uint8_t*, int, size_t, float,
std::vector<std::pair<float, int>>*, bool);
template void get_top_n<float>(float*, int, size_t, float,
std::vector<std::pair<float, int>>*, bool);
} // namespace label_image
} // namespace tflite
#endif // TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_H
get_top_n也是外部定义的一个函数,直接在头文件中定义就行了
#ifndef TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_IMPL_H
#define TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_IMPL_H
#include <algorithm>
#include <queue>
namespace tflite {
namespace label_image {
extern bool input_floating;
// Returns the top N confidence values over threshold in the provided vector,
// sorted by confidence in descending order.
template <class T>
void get_top_n(T* prediction, int prediction_size, size_t num_results,
float threshold, std::vector<std::pair<float, int>>* top_results,
bool input_floating) {
// Will contain top N results in ascending order.
std::priority_queue<std::pair<float, int>, std::vector<std::pair<float, int>>,
std::greater<std::pair<float, int>>>
top_result_pq;
const long count = prediction_size; // NOLINT(runtime/int)
for (int i = 0; i < count; ++i) {
float value;
if (input_floating)
value = prediction[i];
else
value = prediction[i] / 255.0;
// Only add it if it beats the threshold and has a chance at being in
// the top N.
if (value < threshold) {
continue;
}
top_result_pq.push(std::pair<float, int>(value, i));
// If at capacity, kick the smallest value out.
if (top_result_pq.size() > num_results) {
top_result_pq.pop();
}
}
// Copy to output vector and reverse into descending order.
while (!top_result_pq.empty()) {
top_results->push_back(top_result_pq.top());
top_result_pq.pop();
}
std::reverse(top_results->begin(), top_results->end());
}
} // namespace label_image
} // namespace tflite
#endif // TENSORFLOW_CONTRIB_LITE_EXAMPLES_LABEL_IMAGE_GET_TOP_N_IMPL_H