diff options
author | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2021-10-05 11:24:38 +0100 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2021-10-05 17:06:06 +0100 |
commit | 3d9c1ac43523dc810c00ebd7b15bc3a5e05b2b32 (patch) | |
tree | c7dbf4d11ccae425a1b9dfb739d22d0a970df589 /mobilenetssd.cpp |
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Diffstat (limited to 'mobilenetssd.cpp')
-rw-r--r-- | mobilenetssd.cpp | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/mobilenetssd.cpp b/mobilenetssd.cpp new file mode 100644 index 0000000..2728f84 --- /dev/null +++ b/mobilenetssd.cpp @@ -0,0 +1,210 @@ +#include <iostream> +#include <fstream> +#include <cstdlib> +#include <vector> +#include <string> +#include <iterator> +#include <unordered_map> +#include <algorithm> +#include <algorithm> +#include <functional> +#include <queue> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <math.h> +#include <stdint.h> +#include <assert.h> +#include <dirent.h> + +#include <opencv2/core.hpp> +#include <opencv2/videoio.hpp> +#include <opencv2/highgui.hpp> +#include <opencv2/imgproc.hpp> + +#include <tensorflow/lite/kernels/register.h> +#include <tensorflow/lite/model.h> +#include <tensorflow/lite/interpreter.h> +#include <tensorflow/lite/delegates/hexagon/hexagon_delegate.h> + +#include <tensorflow/lite/kernels/register.h> +#include <tensorflow/lite/optional_debug_tools.h> +#include <tensorflow/lite/profiling/profiler.h> +#include <tensorflow/lite/string_util.h> +#include <tensorflow/lite/tools/command_line_flags.h> +#include <tensorflow/lite/tools/delegates/delegate_provider.h> +#include <tensorflow/lite/builtin_op_data.h> + +using namespace cv; +using std::cout; using std::cerr; using std::endl; + +#define IMG_HEIGHT 300 +#define IMG_WIDTH 300 +#define IMG_DEPTH 3 +#define IMG_ELEMENT_SIZE 1 +#define BUFFER_SIZE (IMG_ELEMENT_SIZE * IMG_WIDTH * IMG_HEIGHT * IMG_DEPTH) +#define MODEL_NAME "/home/linaro/apps/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite" +#define LABELS_FILE "/home/linaro/apps/labelmap.txt" + +std::vector<std::string> labels; + +int read_labels_from_file(void) +{ + std::ifstream ifs(LABELS_FILE); + if (!ifs.is_open()) { + cout << "File " << LABELS_FILE << " not found" << endl; + return -1; + } + std::string line; + + while (std::getline(ifs, line)) + labels.push_back(line); + + return 0; +} + +/* Max detection Items */ +#define MAX_ITEMS 10 + +/* Minimum Accuracy required in percentage */ +#define MIN_ACCURACY 40 + +struct SSDbox { + float top; + float left; + float bottom; + float right; + uint32_t id; + float score; +}; +static struct SSDbox SSDBoxes[MAX_ITEMS]; + +void SSDshowOutput(float *scores, float *mclasses, float *boxes, Mat *frame) +{ + int fontface = cv::FONT_HERSHEY_PLAIN; + double scale = 1.0; + int thickness = 1; + char label[256]; + int baseline = 0; + int i; + + for ( i = 0; i < MAX_ITEMS; i++) { + SSDBoxes[i].top = frame->rows * boxes[i * 4]; + SSDBoxes[i].left = frame->cols * boxes[i * 4 + 1]; + SSDBoxes[i].bottom = frame->rows * boxes[i * 4 + 2]; + SSDBoxes[i].right = frame->cols * boxes[i * 4 + 3]; + SSDBoxes[i].id = (uint32_t)mclasses[i] + 1; + SSDBoxes[i].score = scores[i] * 100.00; + } + + for ( i = 0; i < MAX_ITEMS; i++) { + if (SSDBoxes[i].score < MIN_ACCURACY) + break; +#if DEBUG + std::cout << i <<":\t" << SSDBoxes[i].score << ":\t" << + labels[(SSDBoxes[i].id) ] <<":\t(" << + (uint32_t) SSDBoxes[i].top << ", " << + (uint32_t)SSDBoxes[i].left << ", " << + (uint32_t) SSDBoxes[i].bottom << ", " << + (uint32_t) SSDBoxes[i].right << ")"<< std::endl; +#endif + sprintf(label, "%02.2f%%, %s", SSDBoxes[i].score, + labels[SSDBoxes[i].id].c_str()); + cv::rectangle(*frame, cv::Point((uint32_t) SSDBoxes[i].left, (uint32_t)SSDBoxes[i].top), + cv::Point( (uint32_t) SSDBoxes[i].right, (uint32_t) SSDBoxes[i].bottom), + cv::Scalar(0,255, 0), 1); + + cv::Size text = cv::getTextSize(label, fontface, scale, thickness, &baseline); + cv::rectangle(*frame, cv::Point((uint32_t) SSDBoxes[i].left, (uint32_t)SSDBoxes[i].top) + + cv::Point(0, baseline), cv::Point((uint32_t) SSDBoxes[i].left, (uint32_t)SSDBoxes[i].top) + + cv::Point(text.width, -text.height), CV_RGB(0,0,0), cv::FILLED); + cv::putText(*frame, label, cv::Point((uint32_t) SSDBoxes[i].left, (uint32_t)SSDBoxes[i].top), + cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(57,255,20), 0.1, LINE_8); + } +} + +int main(int, char**) +{ + std::unique_ptr<tflite::FlatBufferModel> model; + tflite::ops::builtin::BuiltinOpResolver resolver; + std::unique_ptr<tflite::Interpreter> interpreter; + TfLiteHexagonDelegateOptions params = {0}; + const char* path = "/dsp/cdsp/"; + Mat frame, frame1; + size_t label_count; + char img_path[1024]; + int ret, idx = 0; + char fname[16]; + DIR *d; + + model = tflite::FlatBufferModel::BuildFromFile(MODEL_NAME); + if (!model) { + std::cout << "Failed to mmap model "; + exit(-1); + } + tflite::InterpreterBuilder(*model, resolver)(&interpreter); + if (!interpreter) { + std::cout << "Failed to construct interpreter"; + exit(-1); + } + interpreter->SetAllowFp16PrecisionForFp32(false); + interpreter->SetNumThreads(4); + + std::cout << "Enabling Hexagon Delegate!\n"; + + TfLiteHexagonInitWithPath(path); + auto *delegate = TfLiteHexagonDelegateCreate(¶ms); + + interpreter->ModifyGraphWithDelegate(delegate); + + if (interpreter->AllocateTensors() != kTfLiteOk) { + std::cout << "Failed to allocate tensors!" << endl; + exit(-1); + } + + const std::vector<int> inputs = interpreter->inputs(); + const std::vector<int> outputs = interpreter->outputs(); + int input = interpreter->inputs()[0]; + /* We ONLY support UInt8 on this quantized model */ + uint8_t *finput = interpreter->typed_tensor<uint8_t>(input); + float *locations, *classes, *scores, *dcount; + + locations = interpreter->typed_output_tensor<float>(0); + classes = interpreter->typed_output_tensor<float>(1); + scores = interpreter->typed_output_tensor<float>(2); + dcount = interpreter->typed_output_tensor<float>(3); + + if (read_labels_from_file()) + exit(-1); + + Mat rgb_mat(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, finput); + VideoCapture capture(0); + if (!capture.isOpened()) + { + cerr << "ERROR: Can't initialize camera capture" << endl; + return 1; + } + + for (;;) + { + capture >> frame; + if (frame.empty()) + { + cerr << "ERROR: Can't grab camera frame." << endl; + break; + } + /* resize to 300 x 300 */ + cv::resize(frame, frame1, cv::Size(IMG_HEIGHT, IMG_WIDTH)); + cv::cvtColor(frame1, rgb_mat, cv::COLOR_BGR2RGB); + + if (interpreter->Invoke() != kTfLiteOk) { + std::cout << "Failed to invoke tflite!"; + exit(-1); + } + + SSDshowOutput(scores, classes, locations, &frame); + imshow("MoblieNetSSD-Demo", frame); + waitKey(1); + } + return 0; +} |