这个例子展示了如何加载预先训练好的TensorFlow网络并使用它在C++中检测图像中的对象。
这个演示使用了一个基于[使用深度神经网络的可伸缩对象检测]的模型来检测从网络传来的图像中的人命令行。这与Android TensorFlow中使用的模型相同在相机预览中进行实时人员检测和跟踪的演示。
函数int main(int argc, char* argv[])
函数声明情况如下:
函数声明文件如下:
函数流程图如下:
函数逻辑顺序图如下:
main.CC文件的调用关系:
函数原始代码如下:
int main(int argc, char* argv[]) {
//这些是程序可以理解的命令行标志。它们定义了图形和输入数据的位置,以及模型期望的输入类型。如果你训练你自己的模型,或者使用其他模型,你需要更新这些模型。
string image =
"tensorflow/examples/multibox_detector/data/surfers.jpg";
string graph =
"tensorflow/examples/multibox_detector/data/"
"multibox_model.pb";
string box_priors =
"tensorflow/examples/multibox_detector/data/"
"multibox_location_priors.txt";
int32_t input_width = 224;
int32_t input_height = 224;
int32_t input_mean = 128;
int32_t input_std = 128;
int32_t num_detections = 5;
int32_t num_boxes = 784;
string input_layer = "ResizeBilinear";
string output_location_layer = "output_locations/Reshape";
string output_score_layer = "output_scores/Reshape";
string root_dir = "";
string image_out = "";
std::vector<Flag> flag_list = {
Flag("image", &image, "image to be processed"),
Flag("image_out", &image_out,
"location to save output image, if desired"),
Flag("graph", &graph, "graph to be executed"),
Flag("box_priors", &box_priors, "name of file containing box priors"),
Flag("input_width", &input_width, "resize image to this width in pixels"),
Flag("input_height", &input_height,
"resize image to this height in pixels"),
Flag("input_mean", &input_mean, "scale pixel values to this mean"),
Flag("input_std", &input_std, "scale pixel values to this std deviation"),
Flag("num_detections", &num_detections,
"number of top detections to return"),
Flag("num_boxes", &num_boxes,
"number of boxes defined by the location file"),
Flag("input_layer", &input_layer, "name of input layer"),
Flag("output_location_layer", &output_location_layer,
"name of location output layer"),
Flag("output_score_layer", &output_score_layer,
"name of score output layer"),
Flag("root_dir", &root_dir,
"interpret image and graph file names relative to this directory"),
};
string usage = tensorflow::Flags::Usage(argv[0], flag_list);
const bool parse_result = tensorflow::Flags::Parse(&argc, argv, flag_list);
if (!parse_result) {
LOG(ERROR) << usage;
return -1;
}
//我们需要称之为TensorFlow来建立全局状态。
tensorflow::port::InitMain(argv[0], &argc, &argv);
if (argc > 1) {
LOG(ERROR) << "Unknown argument " << argv[1] << "\n" << usage;
return -1;
}
//首先,我们加载并初始化模型。
std::unique_ptr<tensorflow::Session> session;
string graph_path = tensorflow::io::JoinPath(root_dir, graph);
Status load_graph_status = LoadGraph(graph_path, &session);
if (!load_graph_status.ok()) {
LOG(ERROR) << load_graph_status;
return -1;
}
//以浮点数数组的形式从磁盘获取图像,并根据主图形所需的规格调整大小和规格。 std::vector<Tensor> image_tensors;
string image_path = tensorflow::io::JoinPath(root_dir, image);
Status read_tensor_status =
ReadTensorFromImageFile(image_path, input_height, input_width, input_mean,
input_std, &image_tensors);
if (!read_tensor_status.ok()) {
LOG(ERROR) << read_tensor_status;
return -1;
}
const Tensor& resized_tensor = image_tensors[0];
//在模型中实际运行图像。
std::vector<Tensor> outputs;
Status run_status =
session->Run({{input_layer, resized_tensor}},
{output_score_layer, output_location_layer}, {}, &outputs);
if (!run_status.ok()) {
LOG(ERROR) << "Running model failed: " << run_status;
return -1;
}
Status print_status = PrintTopDetections(outputs, box_priors, num_boxes,
num_detections, image_out,
&image_tensors[1]);
if (!print_status.ok()) {
LOG(ERROR) << "Running print failed: " << print_status;
return -1;
}
return 0;
}