Skip to content

Instantly share code, notes, and snippets.

@kyrs
Created April 23, 2016 12:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyrs/a20c691624e007f4b769f4a1894af61e to your computer and use it in GitHub Desktop.
Save kyrs/a20c691624e007f4b769f4a1894af61e to your computer and use it in GitHub Desktop.
/*
Following file take opencv mat file as an input and convert it to proper tensor object
Created by : Kumar Shubham
Date : 27-03-2016
*/
//Loading Opencv fIles for processing
//#include <opencv2/opencv.hpp>
//#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/framework/tensor.h"
#include <fstream>
#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/graph/graph_def_builder.h"
#include "tensorflow/core/lib/io/path.h"
// COde for reading an Image file and converting it into tensor
int ReadTensorFromImageFile(std::string file_name, const int input_height,
const int input_width, const float input_mean,
const float input_std,
std::vector<tensorflow::Tensor>* out_tensors){
tensorflow::GraphDefBuilder b;
std::string input_name = "file_reader";
std::string output_name = "normalized";
tensorflow::Node* file_render;
tensorflow::Node* file_reader =
tensorflow::ops::ReadFile(tensorflow::ops::Const(file_name, b.opts()),
b.opts().WithName(input_name));
// Now try to figure out what kind of file it is and decode it.
const int wanted_channels = 3;
tensorflow::Node* image_reader;
if (tensorflow::StringPiece(file_name).ends_with(".png")) {
image_reader = tensorflow::ops::DecodePng(
file_reader,
b.opts().WithAttr("channels", wanted_channels).WithName("png_reader"));
} else {
// Assume if it's not a PNG then it must be a JPEG.
image_reader = tensorflow::ops::DecodeJpeg(
file_reader,
b.opts().WithAttr("channels", wanted_channels).WithName("jpeg_reader"));
}
// Now cast the image data to float so we can do normal math on it.
tensorflow::Node* float_caster = tensorflow::ops::Cast(
image_reader, tensorflow::DT_FLOAT, b.opts().WithName("float_caster"));
// The convention for image ops in TensorFlow is that all images are expected
// to be in batches, so that they're four-dimensional arrays with indices of
// [batch, height, width, channel]. Because we only have a single image, we
// have to add a batch dimension of 1 to the start with ExpandDims().
tensorflow::Node* dims_expander = tensorflow::ops::ExpandDims(
float_caster, tensorflow::ops::Const(0, b.opts()), b.opts());
// Bilinearly resize the image to fit the required dimensions.
tensorflow::Node* resized = tensorflow::ops::ResizeBilinear(
dims_expander, tensorflow::ops::Const({input_height, input_width},
b.opts().WithName("size")),
b.opts());
// Subtract the mean and divide by the scale.
tensorflow::ops::Div(
tensorflow::ops::Sub(
resized, tensorflow::ops::Const({input_mean}, b.opts()), b.opts()),
tensorflow::ops::Const({input_std}, b.opts()),
b.opts().WithName(output_name));
// This runs the GraphDef network definition that we've just constructed, and
// returns the results in the output tensor.
tensorflow::GraphDef graph;
tensorflow::Status toGraph_status = b.ToGraphDef(&graph);
if(!toGraph_status.ok()){
return 1;
}
std::unique_ptr<tensorflow::Session> session(
tensorflow::NewSession(tensorflow::SessionOptions()));
tensorflow::Status createGraph_status = session->Create(graph);
if(!createGraph_status.ok()){
return 1;
}
tensorflow::Status run_status = session->Run({}, {output_name}, {}, out_tensors);
if (!run_status.ok()){
return 1;
}
return 0;
}
int main(int argc, char** argv)
{
// Loading the file path provided in the arg into a mat objects
std::string path = argv[1];
// cv::Mat readImage = cv::imread(path);
// std::cerr << "read image=" << path << std::endl;
// converting the image to the necessary dim and for normalization
int height = 299;
int width = 299;
int mean = 128;
int std = 128;
// cv::Size s(height,width);
// cv::Mat Image;
// std::cerr << "resizing\n";
// cv::resize(readImage,Image,s,0,0,cv::INTER_CUBIC);
// std::cerr << "success resizing\n";
// int depth = Image.channels();
// //std::cerr << "height=" << height << " / width=" << width << " / depth=" << depth << std::endl;
// // creating a Tensor for storing the data
// tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1,height,width,depth}));
// auto input_tensor_mapped = input_tensor.tensor<float, 4>();
// cv::Mat Image2;
// Image.convertTo(Image2, CV_32FC1);
// Image = Image2;
// Image = Image-mean;
// Image = Image/std;
// const float * source_data = (float*) Image.data;
// // copying the data into the corresponding tensor
// for (int y = 0; y < height; ++y) {
// const float* source_row = source_data + (y * width * depth);
// for (int x = 0; x < width; ++x) {
// const float* source_pixel = source_row + (x * depth);
// for (int c = 0; c < depth; ++c) {
// const float* source_value = source_pixel + c;
// input_tensor_mapped(0, y, x, c) = *source_value;
// }
// }
// }
/****************************************************************
*
* Function calling the tensorflow Library for Loading the Image
*
*****************************************************************/
std::vector<tensorflow::Tensor> input_tensor_vector;
int readTensorStatus = ReadTensorFromImageFile(path, height,
width, mean,
std,
&input_tensor_vector);
if(readTensorStatus){
return 1;
}
const tensorflow::Tensor& input_tensor = input_tensor_vector[0];
// initializing the graph
tensorflow::GraphDef graph_def;
// Name of the folder in which inception graph is present
std::string graphFile = "../../model/tensorflow_inception_graph.pb";
// Loading the graph to the given variable
tensorflow::Status graphLoadedStatus = ReadBinaryProto(tensorflow::Env::Default(),graphFile,&graph_def);
if (!graphLoadedStatus.ok()){
std::cout << graphLoadedStatus.ToString()<<std::endl;
return 1;
}
// creating a session with the grap
std::unique_ptr<tensorflow::Session> session_inception(tensorflow::NewSession(tensorflow::SessionOptions()));
//session->reset(tensorflow::NewSession(tensorflow::SessionOptions()));
tensorflow::Status session_create_status = session_inception->Create(graph_def);
if (!session_create_status.ok()){
return 1;
}
// running the loaded graph
std::vector<tensorflow::Tensor> finalOutput;
std::string InputName = "Mul";
std::string OutputName = "softmax";
tensorflow::Status run_status = session_inception->Run({{InputName,input_tensor}},{OutputName},{},&finalOutput);
// finding the labels for prediction
std::cerr << "final output size=" << finalOutput.size() << std::endl;
tensorflow::Tensor output = std::move(finalOutput.at(0));
auto scores = output.flat<float>();
std::cerr << "scores size=" << scores.size() << std::endl;
// Label File Name
std::string labelfile = "../../model/imagenet_comp_graph_label_strings.txt";
std::ifstream label(labelfile);
std::string line;
// sorting the file to find the top labels
std::vector<std::pair<float,std::string>> sorted;
for (unsigned int i =0; i<=1000 ;++i){
std::getline(label,line);
sorted.emplace_back(scores(i),line);
//std::cout << scores(i) << " / line=" << line << std::endl;
}
std::sort(sorted.begin(),sorted.end());
std::reverse(sorted.begin(),sorted.end());
std::cout << "size of the sorted file is "<<sorted.size()<< std::endl;
for(unsigned int i =0 ; i< 5;++i){
std::cout << "The output of the current graph has category " << sorted[i].second << " with probability "<< sorted[i].first << std::endl;
}
/*cv::namedWindow("imageOpencv",CV_WINDOW_KEEPRATIO);
cv::imshow("imgOpencv",Image);
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment