Skip to content

Commit 6ba4dda

Browse files
committed
V1.0
0 parents  commit 6ba4dda

19 files changed

+10855
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cmake-build-debug

.idea/codeStyles/Project.xml

+29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/tensorflow_c++_detection_for_web_service_example.iml

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

+347
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CMakeLists.txt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
cmake_minimum_required(VERSION 3.7)
2+
#project(TF_CPP_DETECT)
3+
4+
set(CMAKE_CXX_STANDARD 11)
5+
ADD_COMPILE_OPTIONS(-fPIC)
6+
7+
set(SOURCE_FILES detect.cpp main.cpp base64.cpp base64.h)
8+
add_executable(tf_detect_crow ${SOURCE_FILES})
9+
SET_TARGET_PROPERTIES(tf_detect_crow PROPERTIES PREFIX "")
10+
11+
# crow lib
12+
#include_directories("/usr/local/include")
13+
14+
# OpenCV libs
15+
find_package(OpenCV REQUIRED)
16+
include_directories(${OpenCV_INCLUDE_DIRS})
17+
target_link_libraries(tf_detect_crow ${OpenCV_LIBS})
18+
19+
# boost lib
20+
find_package(Boost REQUIRED COMPONENTS system thread)
21+
include_directories( ${Boost_INCLUDE_DIRS} )
22+
target_link_libraries(tf_detect_crow ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY})
23+
24+
# pthread link
25+
target_link_libraries(tf_detect_crow -lpthread -lm)
26+
# ==================== PATHS TO SPECIFY! ==================== #
27+
28+
# Eigen lib headers
29+
include_directories("/usr/local/include/eigen3")
30+
include_directories("/usr/local/include/google")
31+
32+
# TensorFlow headers
33+
include_directories("/usr/local/include/tf/")
34+
include_directories("/usr/local/include/tf/bazel-genfiles/")
35+
include_directories("/usr/local/include/tf/tensorflow/")
36+
include_directories("/usr/local/include/tf/third-party/")
37+
38+
# Link TensorFlow libs
39+
target_link_libraries(tf_detect_crow "/usr/local/lib/libtensorflow_cc.so")
40+
target_link_libraries(tf_detect_crow "/usr/local/lib/libtensorflow_framework.so")

README.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
This is an example how to run a TensorFlow object detection model as web server in TensorFlow C++ API.
2+
3+
### Brief Introduction
4+
1). Construct a class for TF model like this:
5+
```c++
6+
class Detector {
7+
std::unique_ptr<tensorflow::Session> session;
8+
public:
9+
int loadModel();
10+
int detect();
11+
};
12+
```
13+
First, `loadModel` to initialize and load graph into session, then use
14+
session in `detect` for prediction.
15+
16+
2). use crow the start a web server in `main` (crow is inspired by python `FLASK`.
17+
If you are familiar with FLASK, crow is easy to use.)
18+
19+
### Requirements
20+
- [TensorFlow 1.8.0rc1](https://github.com/tensorflow)
21+
- [OpenCV 3.4.0](https://opencv.org/releases.html)
22+
- Boost 1.5.8
23+
- Ubuntu 16.04
24+
25+
### Install
26+
**Install TensorFlow C++ and OpenCV**: see this [blog](https://medium.com/@fanzongshaoxing/use-tensorflow-c-api-with-opencv3-bacb83ca5683)
27+
28+
**Install Boost** <br>
29+
```bash
30+
sudo apt-get install libboost-all-dev
31+
```
32+
33+
### Usage
34+
1. compile the project
35+
```bash
36+
cmake .
37+
make
38+
```
39+
2. run tf-cpp web service
40+
```bash
41+
./tf_detect_crow
42+
```
43+
44+
3. test with python script
45+
```
46+
python test_cpp_api.py
47+
```
48+
49+
### Acknowledgement
50+
Great appreciation to following project and code snippet:
51+
52+
- [opencv_tensor.cc](https://gist.github.com/kyrs/9adf86366e9e4f04addb)
53+
- [tensorflow object detection cpp](https://github.com/lysukhin/tensorflow-object-detection-cpp)
54+
- [crow example](https://github.com/jolks/crow-template/blob/master/src/example.cpp)
55+
- [Encoding and decoding base 64 with c++](https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp)

base64.cpp

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//
2+
// Code source: https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
3+
//
4+
5+
#include "base64.h"
6+
#include <iostream>
7+
8+
static const std::string base64_chars =
9+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
10+
"abcdefghijklmnopqrstuvwxyz"
11+
"0123456789+/";
12+
13+
14+
static inline bool is_base64(unsigned char c) {
15+
return (isalnum(c) || (c == '+') || (c == '/'));
16+
}
17+
18+
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
19+
std::string ret;
20+
int i = 0;
21+
int j = 0;
22+
unsigned char char_array_3[3];
23+
unsigned char char_array_4[4];
24+
25+
while (in_len--) {
26+
char_array_3[i++] = *(bytes_to_encode++);
27+
if (i == 3) {
28+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
29+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
30+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
31+
char_array_4[3] = char_array_3[2] & 0x3f;
32+
33+
for(i = 0; (i <4) ; i++)
34+
ret += base64_chars[char_array_4[i]];
35+
i = 0;
36+
}
37+
}
38+
39+
if (i)
40+
{
41+
for(j = i; j < 3; j++)
42+
char_array_3[j] = '\0';
43+
44+
char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
45+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
46+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
47+
48+
for (j = 0; (j < i + 1); j++)
49+
ret += base64_chars[char_array_4[j]];
50+
51+
while((i++ < 3))
52+
ret += '=';
53+
54+
}
55+
56+
return ret;
57+
58+
}
59+
60+
std::string base64_decode(std::string const& encoded_string) {
61+
int in_len = encoded_string.size();
62+
int i = 0;
63+
int j = 0;
64+
int in_ = 0;
65+
unsigned char char_array_4[4], char_array_3[3];
66+
std::string ret;
67+
68+
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
69+
char_array_4[i++] = encoded_string[in_]; in_++;
70+
if (i ==4) {
71+
for (i = 0; i <4; i++)
72+
char_array_4[i] = base64_chars.find(char_array_4[i]);
73+
74+
char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4);
75+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
76+
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
77+
78+
for (i = 0; (i < 3); i++)
79+
ret += char_array_3[i];
80+
i = 0;
81+
}
82+
}
83+
84+
if (i) {
85+
for (j = 0; j < i; j++)
86+
char_array_4[j] = base64_chars.find(char_array_4[j]);
87+
88+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
89+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
90+
91+
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
92+
}
93+
94+
return ret;
95+
}

base64.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// Code source: https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
3+
4+
//
5+
6+
#ifndef PROJECT_BASE64_H
7+
#define PROJECT_BASE64_H
8+
#include <string>
9+
10+
std::string base64_encode(unsigned char const* , unsigned int len);
11+
std::string base64_decode(std::string const& s);
12+
13+
#endif //PROJECT_BASE64_H

0 commit comments

Comments
 (0)