-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
700 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Copyright (C) 2020 RidgeRun, LLC (http://www.ridgerun.com) | ||
# All Rights Reserved. | ||
# | ||
# The contents of this software are proprietary and confidential to RidgeRun, | ||
# LLC. No part of this program may be photocopied, reproduced or translated | ||
# into another programming language without prior written consent of | ||
# RidgeRun, LLC. The user is free to modify the source code after obtaining | ||
# a software license from RidgeRun. All source code changes must be provided | ||
# back to RidgeRun without any encumbrance. | ||
|
||
AM_DEFAULT_SOURCE_EXT = .cc | ||
|
||
if ENABLE_EXAMPLES | ||
|
||
noinst_PROGRAMS = \ | ||
inception | ||
|
||
AM_CXXFLAGS = \ | ||
$(RR_CXXFLAGS) \ | ||
$(CODE_COVERAGE_CXXFLAGS) \ | ||
-I../common/ | ||
|
||
AM_CFLAGS = \ | ||
$(RR_CFLAGS) \ | ||
$(CODE_COVERAGE_CFLAGS) | ||
|
||
AM_CPPFLAGS = \ | ||
$(RR_CPPFLAGS) \ | ||
$(CODE_COVERAGE_CPPFLAGS) | ||
|
||
LDADD = \ | ||
$(RR_LIBS) \ | ||
$(CODE_COVERAGE_LIBS) \ | ||
$(top_builddir)/r2i/libr2inference-@RR_PACKAGE_VERSION@.la | ||
|
||
endif # ENABLE_EXAMPLES |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/* Copyright (C) 2018-2020 RidgeRun, LLC (http://www.ridgerun.com) | ||
* All Rights Reserved. | ||
* | ||
* The contents of this software are proprietary and confidential to RidgeRun, | ||
* LLC. No part of this program may be photocopied, reproduced or translated | ||
* into another programming language without prior written consent of | ||
* RidgeRun, LLC. The user is free to modify the source code after obtaining | ||
* a software license from RidgeRun. All source code changes must be provided | ||
* back to RidgeRun without any encumbrance. | ||
*/ | ||
|
||
#include <algorithm> | ||
#include <fstream> | ||
#include <getopt.h> | ||
#include <iostream> | ||
#include <memory> | ||
#include <string> | ||
#include <vector> | ||
#include <r2i/r2i.h> | ||
|
||
#define STB_IMAGE_IMPLEMENTATION | ||
#include "stb_image.h" | ||
|
||
#define STB_IMAGE_RESIZE_IMPLEMENTATION | ||
#include "stb_image_resize.h" | ||
|
||
void PrintTopPrediction (std::shared_ptr<r2i::IPrediction> prediction) { | ||
r2i::RuntimeError error; | ||
int num_labels = prediction->GetResultSize(); | ||
|
||
std::vector<double> results; | ||
results.resize(num_labels); | ||
|
||
for (int i = 0; i < num_labels; ++i) { | ||
results[i] = prediction->At(i, error); | ||
} | ||
|
||
auto it = std::max_element(results.begin(), results.end()); | ||
std::cout << "Highest probability is label " | ||
<< std::distance(results.begin(), it) << " (" << *it << ")" | ||
<< std::endl; | ||
} | ||
|
||
void PrintUsage() { | ||
std::cerr << "Required arguments: " | ||
<< "-i [JPG input_image] " | ||
<< "-m [Inception TfLite Model] " | ||
<< "-s [Model Input Size] " | ||
<< "-I [Input Node] " | ||
<< "-O [Output Node] \n" | ||
<< " Example: " | ||
<< " ./inception -i cat.jpg -m graph_inceptionv2_tensorflow.pb " | ||
<< "-s 224" | ||
<< std::endl; | ||
} | ||
|
||
std::unique_ptr<float[]> PreProcessImage (const unsigned char *input, | ||
int width, int height, int reqwidth, int reqheight) { | ||
|
||
const int channels = 3; | ||
const int scaled_size = channels * reqwidth * reqheight; | ||
std::unique_ptr<unsigned char[]> scaled (new unsigned char[scaled_size]); | ||
std::unique_ptr<float[]> adjusted (new float[scaled_size]); | ||
|
||
stbir_resize_uint8(input, width, height, 0, scaled.get(), reqwidth, | ||
reqheight, 0, channels); | ||
|
||
for (int i = 0; i < scaled_size; i += channels) { | ||
/* RGB = (RGB - Mean)*StdDev */ | ||
adjusted[i + 0] = (static_cast<float>(scaled[i + 0]) - 127.5) / 127.5; | ||
adjusted[i + 1] = (static_cast<float>(scaled[i + 1]) - 127.5) / 127.5; | ||
adjusted[i + 2] = (static_cast<float>(scaled[i + 2]) - 127.5) / 127.5; | ||
} | ||
|
||
return adjusted; | ||
} | ||
|
||
std::unique_ptr<float[]> LoadImage(const std::string &path, int reqwidth, | ||
int reqheight) { | ||
int channels = 3; | ||
int width, height, cp; | ||
|
||
unsigned char *img = stbi_load(path.c_str(), &width, &height, &cp, channels); | ||
if (!img) { | ||
std::cerr << "The picture " << path << " could not be loaded"; | ||
return nullptr; | ||
} | ||
|
||
auto ret = PreProcessImage(img, width, height, reqwidth, reqheight); | ||
free (img); | ||
|
||
return ret; | ||
} | ||
|
||
bool ParseArgs (int &argc, char *argv[], std::string &image_path, | ||
std::string &model_path, int &index, int &size, | ||
std::string &in_node, std::string &out_node) { | ||
|
||
int option = 0; | ||
while ((option = getopt(argc, argv, "i:m:p:s:I:O:")) != -1) { | ||
switch (option) { | ||
case 'i' : | ||
image_path = optarg; | ||
break; | ||
case 'm' : | ||
model_path = optarg; | ||
break; | ||
case 'p' : | ||
index = std::stoi (optarg); | ||
break; | ||
case 's' : | ||
size = std::stoi (optarg); | ||
break; | ||
case 'I' : | ||
in_node = optarg; | ||
break; | ||
case 'O' : | ||
out_node = optarg; | ||
break; | ||
default: | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
int main (int argc, char *argv[]) { | ||
|
||
r2i::RuntimeError error; | ||
std::string model_path; | ||
std::string image_path; | ||
std::string in_node; | ||
std::string out_node; | ||
int Index = 0; | ||
int size = 0; | ||
|
||
if (false == ParseArgs (argc, argv, image_path, model_path, Index, | ||
size, in_node, out_node)) { | ||
PrintUsage (); | ||
exit (EXIT_FAILURE); | ||
} | ||
|
||
if (image_path.empty() || model_path.empty ()) { | ||
PrintUsage (); | ||
exit (EXIT_FAILURE); | ||
} | ||
|
||
auto factory = r2i::IFrameworkFactory::MakeFactory( | ||
r2i::FrameworkCode::EDGETPU, | ||
error); | ||
|
||
if (nullptr == factory) { | ||
std::cerr << "EdgeTPU backend is not built: " << error << std::endl; | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
std::cout << "Loading Model: " << model_path << std::endl; | ||
auto loader = factory->MakeLoader (error); | ||
std::shared_ptr<r2i::IModel> model = loader->Load (model_path, error); | ||
if (error.IsError ()) { | ||
std::cerr << "Loader error: " << error << std::endl; | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
std::cout << "Setting model to engine" << std::endl; | ||
std::shared_ptr<r2i::IEngine> engine = factory->MakeEngine (error); | ||
error = engine->SetModel (model); | ||
|
||
std::cout << "Loading image: " << image_path << std::endl; | ||
std::unique_ptr<float[]> image_data = LoadImage (image_path, size, size); | ||
|
||
std::cout << "Configuring frame" << std::endl; | ||
std::shared_ptr<r2i::IFrame> frame = factory->MakeFrame (error); | ||
|
||
error = frame->Configure (image_data.get(), size, size, | ||
r2i::ImageFormat::Id::RGB); | ||
|
||
std::cout << "Starting engine" << std::endl; | ||
error = engine->Start (); | ||
if (error.IsError ()) { | ||
std::cerr << "Engine start error: " << error << std::endl; | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
std::cout << "Predicting..." << std::endl; | ||
auto prediction = engine->Predict (frame, error); | ||
if (error.IsError ()) { | ||
std::cerr << "Engine prediction error: " << error << std::endl; | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
PrintTopPrediction (prediction); | ||
|
||
std::cout << "Stopping engine" << std::endl; | ||
error = engine->Stop (); | ||
if (error.IsError ()) { | ||
std::cerr << "Engine stop error: " << error << std::endl; | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Compile examples | ||
app_examples = [ | ||
'inception', | ||
] | ||
|
||
foreach app : app_examples | ||
executable(app, '@0@.cc'.format(app), | ||
include_directories: [configinc, common_inc_dir], | ||
dependencies : [r2inference_lib_dep], | ||
install: false) | ||
endforeach |
Oops, something went wrong.