stm32mpu-ai: recipes-samples: verbatim copy of npu samples from st beta branch

Current samples were not working properly due to problems with libraries and
the runtime frameworks.

This commit brings the updated samples recipes with the new folder structure
that have been proved to work as they were in the st beta branch, using commit
with SHA256: 68686850c75061f1c7c4e756a313a41ca810f6ae

https://onedigi.atlassian.net/browse/CCS-12

Signed-off-by: David Escalona <david.escalona@digi.com>
This commit is contained in:
David Escalona 2024-09-16 17:25:27 +02:00 committed by Javier Viguera
parent 983df1b9cb
commit 1f678d39a3
159 changed files with 25408 additions and 0 deletions

View File

@ -0,0 +1,63 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite C++ API Computer Vision image classification application example running on the EdgeTPU"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit pkgconfig
DEPENDS += "tensorflow-lite libedgetpu gtk+3 opencv gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad "
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
EXTRA_OEMAKE += 'EDGETPU=TRUE'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/tflite/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/coral/
# install applications into the demo launcher
install -m 0755 ${S}/tflite/111-coral-image-classification-cpp.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_image_classification ${D}${prefix}/local/demo-ai/image-classification/coral/coral_image_classification
install -m 0755 ${S}/tflite/launch_coral_bin*.sh ${D}${prefix}/local/demo-ai/image-classification/coral
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gstreamer1.0-plugins-base-videoconvertscale \
gtk+3 \
libedgetpu \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
coral-models-mobilenetv1 \
application-resources \
bash \
"

View File

@ -0,0 +1,39 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite Python Computer Vision image classification application examples running on the EdgeTPU"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/coral
install -d ${D}${prefix}/local/demo-ai/image-classification/resources
# install applications into the demo launcher
install -m 0755 ${S}/tflite/110-coral-image-classification-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_image_classification.py ${D}${prefix}/local/demo-ai/image-classification/coral/coral_image_classification.py
install -m 0755 ${S}/tflite/launch_coral_python*.sh ${D}${prefix}/local/demo-ai/image-classification/coral/
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-tensorflow-lite \
libedgetpu \
coral-models-mobilenetv1 \
application-resources \
bash \
"

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v3
Icon: ../demo-ai/resources/nbg_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/nbg/launch_bin_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,29 @@
OPENCV_PKGCONFIG?="opencv4"
SYSROOT?=""
TARGET_BIN = nbg_image_classification
CXXFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0 $(OPENCV_PKGCONFIG) gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
CXXFLAGS += -std=c++17
LDFLAGS = $(shell pkg-config --libs gtk+-3.0 gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
LDFLAGS += -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_imgcodecs
LDFLAGS += -L$(SYSROOT)/usr/lib -ljpeg -lovxlib -lOpenVX -lOpenVXU
LDFLAGS += -Wl,--no-as-needed
ifeq ($(NEW_GST_WAYLAND_API), 1)
CXXFLAGS += -DNEW_GST_WAYLAND_API
endif
SRCS = nbg_image_classification.cc vnn_utils.cc
OBJS = $(SRCS:.cc=.o)
all: $(TARGET_BIN)
$(TARGET_BIN): $(OBJS)
$(CXX) -o $@ $^ $(LDFLAGS)
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c $^
clean:
rm -rf $(OBJS) $(TARGET_BIN)

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/image-classification/nbg/nbg_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.nb -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL\_nbg.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/image-classification/nbg/nbg_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.nb -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL\_nbg.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,124 @@
/*
* vnn_utils.h
*
* This provides helper functions for nbg-benchmark tool and wrappers around OpenVX lib
* function. The function are mainly used for converting data types and loading
* network binary graph.
*
* Author: Othmane AHL ZOUAOUI <othmane.ahlzouaoui@st.com> for STMicroelectronics.
*
* Copyright (c) 2023 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.opensource.org/licenses/BSD-3-Clause
*/
#ifndef _VNN_UTILS_H_
#define _VNN_UTILS_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <assert.h>
#include <VX/vx_khr_cnn.h>
#include <VX/vx_khr_import_kernel.h>
#include <VX/vx_lib_extras.h>
#define MAX_NUM_DIMS 6
#define MAX_IO_NAME_LENGTH 128
#define VSI_NN_MAX_DEBUG_BUFFER_LEN 1024
#define ZEROS(a) memset(a,0,sizeof(a))
#define _CHECK_OBJ(ptr, label) \
do \
{ \
if ((ptr) == NULL) \
{ \
printf("create fail: file=%s,line = %d\n", __FILE__,__LINE__); \
goto label; \
} \
} while(0)
#define _CHECK_STATUS(status, label) \
do \
{ \
if (status != VX_SUCCESS) \
{ \
printf("process fail,status=%d, file=%s,line = %d\n",status,__FILE__, __LINE__); \
goto label; \
} \
} while(0)
typedef struct _inout_param
{
vx_uint32 dim_count;
vx_uint32 dim_size[MAX_NUM_DIMS];
vx_enum data_format;
vx_enum data_type;
vx_enum quan_format;
vx_int8 fixed_pos;
vx_float32 tf_scale;
vx_int32 tf_zerop;
vx_char name[MAX_IO_NAME_LENGTH];
} inout_param;
typedef struct _inout_obj
{
vx_enum data_type;//image or tensor
union
{
vx_reference ref;
vx_image image;
vx_tensor tensor;
vx_array array;
vx_scalar scalar;
}u;
}inout_obj;
typedef enum _file_type
{
FILE_TYPE_TEXT,
FILE_TYPE_BIN,
FILE_TYPE_NOT_SUPPORT
}file_type;
vx_int8 vnn_Fp32toInt8(vx_float32 val, vx_int8 fixedPointPos);
vx_float32 vnn_Int8toFp32(vx_int8 val, vx_int8 fixedPointPos);
vx_uint8 vnn_Fp32toUint8(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale);
vx_float32 vnn_Uint8toFp32(vx_uint8 val, vx_int32 zeroPoint, vx_float32 scale);
vx_float32 vnn_Int16toFp32(vx_int16 val, vx_int8 fixedPointPos);
vx_int16 vnn_Fp32toInt16(vx_float32 val, vx_int8 fixedPointPos);
vx_int16 vnn_Fp32toFp16(vx_float32 val);
vx_float32 vnn_Fp16toFp32(const vx_uint16 in);
vx_int8 vnn_Fp32toAsymInt8(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale);
vx_float32 vnn_AsymInt8toFp32(vx_int8 val, vx_int32 zeroPoint, vx_float32 scale);
vx_int16 vnn_Fp32toAsymInt16(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale);
vx_float32 vnn_AsymInt16toFp32(vx_int16 val, vx_int32 zeroPoint, vx_float32 scale);
vx_uint32 vnn_GetTypeSize(vx_enum format);
vx_uint32 vnn_GetTensorSize(vx_tensor tensor);
vx_uint32 vnn_GetTensorDims(vx_tensor tensor);
vx_uint32 vnn_GetTensorBufferSize(vx_tensor tensor);
vx_status vnn_CopyTensorToData(vx_tensor tensor,void **buf);
vx_status vnn_CopyTensorToFloat32Data(vx_tensor tensor,vx_float32 **buf);
vx_status vnn_CopyDataToTensor(vx_tensor tensor,void *buf);
vx_status vnn_CopyFloat32DataToTensor(vx_tensor tensor,vx_float32 *buf);
vx_status vnn_LoadTensorFromFile(vx_tensor tensor,char *filename);
vx_status vnn_SaveTensorToFileAsFloat32(vx_tensor tensor,char *filename);
vx_status vnn_SaveTensorToFileAsBinary(vx_tensor tensor,char *filename);
vx_status vnn_ShowTensorTop5(vx_tensor tensor);
vx_status vnn_ShowTop5(inout_obj* obj);
vx_status vnn_LoadDataFromFile(inout_obj* obj,char *filename);
vx_status vnn_LoadTensorRandom(vx_tensor tensor);
vx_status vnn_SaveDataToFile(inout_obj* obj,char *filename);
vx_status vnn_QueryInputsAndOutputsParam(vx_kernel kernel,inout_param *input,vx_int32 *in_cnt,inout_param *output,vx_int32 *out_cnt);
vx_status vnn_CreateObject(vx_context context, inout_param *param, inout_obj *obj);
vx_status vnn_ReleaseObject(inout_obj *obj);
vx_bool get_top(float *pfProb, float *pfMaxProb, uint32_t *pMaxClass, uint32_t outputCount, uint32_t topNum);
void vnn_Log(const char *fmt, ...);
#endif

View File

@ -0,0 +1,347 @@
/*
* wrapper_tfl.hpp
*
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
*
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.opensource.org/licenses/BSD-3-Clause
*
*
*
* Inspired by:
* https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/examples/label_image
* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef WRAPPER_NBG_HPP_
#define WRAPPER_NBG_HPP_
#include <algorithm>
#include <functional>
#include <queue>
#include <memory>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sstream>
#include <fstream>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <assert.h>
#include <getopt.h>
#include <iostream>
#include <time.h>
#include <pthread.h>
#include "vnn_utils.h"
#define GPU_CLK_FD "/sys/kernel/debug/gc/clk"
#define NUM_OF_INPUT_MAX 32
#define NUM_OF_OUTPUT_MAX 32
#define BILLION 1000000000
#define LOG(x) std::cerr
namespace wrapper_nbg
{
double get_ms(struct timeval t) { return (t.tv_sec * 1000 + t.tv_usec / 1000); }
struct Config
{
bool verbose;
std::string input_file;
std::string model_name;
std::string labels_file_name;
int number_of_results = 5;
};
struct Label_Results
{
float accuracy[10];
int index[10];
float inference_time;
};
class NBG_Wrapper
{
private:
vx_context m_context;
vx_graph m_graph;
vx_kernel m_kernel;
vx_node m_node;
vx_status m_status;
vx_tensor m_input_tensor;
vx_tensor m_output_tensor;
vx_int32 m_input_count;
vx_int32 m_output_count;
vx_uint32 m_width;
vx_uint32 m_height;
bool m_verbose;
bool m_inputFloating;
float m_inferenceTime;
int m_numberOfResults;
std::string m_model;
inout_obj m_inputs[NUM_OF_INPUT_MAX];
inout_obj m_outputs[NUM_OF_OUTPUT_MAX];
inout_param m_inputs_param[NUM_OF_INPUT_MAX];
inout_param m_outputs_param[NUM_OF_OUTPUT_MAX];
public:
NBG_Wrapper() {}
void Initialize(Config *conf)
{
m_context = {NULL};
m_graph = {NULL};
m_kernel = {NULL};
m_node = {NULL};
m_status = VX_FAILURE;
m_input_tensor = NULL;
m_output_tensor = NULL;
m_input_count = 0;
m_output_count = 0;
m_width = 0;
m_height = 0;
m_inputFloating = false;
m_inferenceTime = 0;
m_model = conf->model_name;
m_verbose = conf->verbose;
m_numberOfResults = conf->number_of_results;
if (!m_model.c_str())
{
LOG(ERROR) << "no model file name\n";
exit(-1);
}
LOG(INFO) << "Loaded model " << m_model << "\n";
char *char_model = const_cast<char *>(m_model.c_str());
ZEROS(m_inputs_param);
ZEROS(m_outputs_param);
m_context = vxCreateContext();
if (m_context == NULL)
{
LOG(FATAL) << "create fail: file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_graph = vxCreateGraph(m_context);
if (m_graph == NULL)
{
LOG(FATAL) << "create fail: file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_kernel = vxImportKernelFromURL(m_context, VX_VIVANTE_IMPORT_KERNEL_FROM_FILE, char_model);
m_status = vxGetStatus((vx_reference)m_kernel);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_node = vxCreateGenericNode(m_graph, m_kernel);
m_status = vxGetStatus((vx_reference)m_node);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_status = vnn_QueryInputsAndOutputsParam(m_kernel, m_inputs_param, &m_input_count, m_outputs_param, &m_output_count);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
for (int j = 0; j < m_input_count; j++)
{
m_status |= vnn_CreateObject(m_context, &m_inputs_param[j], &m_inputs[j]);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_status |= vxSetParameterByIndex(m_node, j, (vx_reference)m_inputs[j].u.ref);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
}
for (int j = 0; j < m_output_count; j++)
{
m_status |= vnn_CreateObject(m_context, &m_outputs_param[j], &m_outputs[j]);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
m_status |= vxSetParameterByIndex(m_node, j + m_input_count, (vx_reference)m_outputs[j].u.ref);
;
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
}
uint64_t tmsStart, tmsEnd, msVal, usVal;
LOG(INFO) << "Info: Compiling and verifying graph...\n";
tmsStart = get_perf_count();
m_status = vxVerifyGraph(m_graph);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
tmsEnd = get_perf_count();
msVal = (tmsEnd - tmsStart) / 1000000;
usVal = (tmsEnd - tmsStart) / 1000;
LOG(INFO) << "Info: Verifying graph took: " << msVal << " ms | " << usVal << " us\n";
inout_obj *obj = &m_inputs[0];
m_input_tensor = obj->u.tensor;
vx_int32 num_of_dims = vnn_GetTensorDims(m_input_tensor);
vx_uint32 size[6];
vxQueryTensor(m_input_tensor, VX_TENSOR_DIMS, size, sizeof(size));
m_width = size[1];
m_height = size[2];
}
static uint64_t get_perf_count()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)((uint64_t)ts.tv_nsec + (uint64_t)ts.tv_sec * BILLION);
}
void RunInference(uint8_t *img, Label_Results *results)
{
uint64_t tmsStart, tmsEnd;
float msAvg, usAvg;
float rUtil = 0;
float rtime = 0;
vnn_CopyDataToTensor(m_input_tensor, img);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
tmsStart = get_perf_count();
m_status = vxProcessGraph(m_graph);
tmsEnd = get_perf_count();
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
msAvg = (float)(tmsEnd - tmsStart) / 1000000;
usAvg = (float)(tmsEnd - tmsStart) / 1000;
m_inferenceTime = msAvg;
if (m_verbose)
{
LOG(INFO) << "Info: Initialized the graph\n";
LOG(INFO) << "Info: Inf time Average: " << msAvg << " ms | " << usAvg << " us\n";
}
vx_float32 *buf = NULL;
vx_int32 num = vnn_GetTensorSize(m_outputs->u.tensor);
if (m_verbose)
LOG(INFO) << "Num of output: " << num << "\n";
uint32_t MaxClass[5];
vx_float32 fMaxProb[5];
m_status |= vnn_CopyTensorToFloat32Data(m_outputs->u.tensor, &buf);
if (m_status != VX_SUCCESS)
{
LOG(FATAL) << "process fail: status=" << m_status << ", file=" << __FILE__ << ",line =" << __LINE__ << "\n";
exit(1);
}
if (!get_top(buf, fMaxProb, MaxClass, num, m_numberOfResults))
{
LOG(FATAL) << "Fail to show result.\n";
if (buf)
{
free(buf);
exit(1);
}
}
/* Get results */
for (int i = 0; i < m_numberOfResults; i++)
{
if (m_verbose)
{
LOG(INFO) << "________________________________________\n________________________________________\n";
LOG(INFO) << MaxClass[i] << " : " << fMaxProb[i] << "\n";
LOG(INFO) << "________________________________________\n";
}
results->accuracy[i] = fMaxProb[i];
results->index[i] = MaxClass[i];
}
results->inference_time = m_inferenceTime;
if (buf)
{
free(buf);
}
}
int GetInputWidth()
{
return int(m_width);
}
int GetInputHeight()
{
return int(m_height);
}
// Takes a file name, and loads a list of labels from it, one per line, and
// returns a vector of the strings. It pads with empty strings so the length
// of the result is a multiple of 16, because our model expects that.
vx_status ReadLabelsFile(const std::string &file_name,
std::vector<std::string> *result,
size_t *found_label_count)
{
std::ifstream file(file_name);
if (!file)
{
LOG(FATAL) << "Labels file " << file_name << " not found\n";
return VX_FAILURE;
}
result->clear();
std::string line;
while (std::getline(file, line))
{
result->push_back(line);
}
*found_label_count = result->size();
const int padding = 16;
while (result->size() % padding)
{
result->emplace_back();
}
return VX_SUCCESS;
}
};
} // namespace wrapper_tfl
#endif // WRAPPER_TFL_HPP_

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v3
Icon: ../demo-ai/resources/onnx_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/onnx/launch_python_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v1
Icon: ../demo-ai/resources/onnx_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/onnx/launch_python_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/onnx/onnx_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.onnx -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL_onnx.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,11 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/onnx/onnx_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.onnx -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL_onnx.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v3
Icon: ../demo-ai/resources/tfl_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/tflite/launch_python_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v1
Icon: ../demo-ai/resources/tfl_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/tflite/launch_python_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v3
Icon: ../demo-ai/resources/tfl_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/tflite/launch_bin_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v1
Icon: ../demo-ai/resources/tfl_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/tflite/launch_bin_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v1
Icon: ../demo-ai/resources/coral_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/coral/launch_coral_python_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Image Classification
Description: Mobilenet v1
Icon: ../demo-ai/resources/coral_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/image-classification/coral/launch_coral_bin_image_classification.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,36 @@
OPENCV_PKGCONFIG?="opencv4"
SYSROOT?=""
EDGETPU?=""
ARCHITECTURE?=""
TARGET_BIN = tflite_image_classification
CXXFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0 $(OPENCV_PKGCONFIG) gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
CXXFLAGS += -std=c++17
CXXFLAGS += -I$(SYSROOT)/usr/include/tensorflow/lite/flatbuffers/include
CXXFLAGS += -I$(SYSROOT)/usr/include/tensorflow/lite/abseil-cpp
LDFLAGS = $(shell pkg-config --libs gtk+-3.0 gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
LDFLAGS += -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -ltensorflow-lite
ifneq (,$(findstring stm32mp2_npu,$(ARCHITECTURE)))
CXXFLAGS += -DVSI_OP
LDFLAGS += -lvx_custom_op
endif
ifneq (,$(findstring TRUE,$(EDGETPU)))
CXXFLAGS += -DEDGETPU
LDFLAGS += -ledgetpu
endif
SRCS = tflite_image_classification.cc
OBJS = $(SRCS:.cc=.o)
all: $(TARGET_BIN)
$(TARGET_BIN): $(OBJS)
$(CXX) -o $@ $^ $(LDFLAGS)
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c $^
clean:
rm -rf $(OBJS) $(TARGET_BIN)

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/image-classification/tflite/tflite_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/image-classification/tflite/tflite_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/ $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/image-classification/coral/coral_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/mobilenet_v1_1.0_224_quant_edgetpu.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/labels.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
cmd="/usr/local/demo-ai/image-classification/coral/coral_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/mobilenet_v1_1.0_224_quant_edgetpu.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/labels.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/ --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/coral/coral_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/mobilenet_v1_1.0_224_quant_edgetpu.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/labels.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,11 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/coral/coral_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/mobilenet_v1_1.0_224_quant_edgetpu.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/labels.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/ --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/tflite/tflite_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/image-classification/tflite/tflite_image_classification.py -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.tflite -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/ $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,385 @@
/*
* wrapper_tfl.hpp
*
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
*
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.opensource.org/licenses/BSD-3-Clause
*
*
*
* Inspired by:
* https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/examples/label_image
* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef WRAPPER_TFL_HPP_
#define WRAPPER_TFL_HPP_
#include <algorithm>
#include <functional>
#include <fstream>
#include <queue>
#include <memory>
#include <string>
#include <sys/time.h>
#include <vector>
#include <fstream>
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/optional_debug_tools.h"
#ifdef EDGETPU
#include "tflite/public/edgetpu.h"
#endif
#include "tensorflow/lite/delegates/external/external_delegate.h"
#include "tensorflow/lite/interpreter.h"
#ifdef VSI_OP
#include "VX/vsi_npu_custom_op.h"
#endif
#define LOG(x) std::cerr
namespace wrapper_tfl {
double get_ms(struct timeval t) { return (t.tv_sec * 1000 + t.tv_usec / 1000); }
struct Config {
bool verbose;
float input_mean = 127.5f;
float input_std = 127.5f;
int number_of_threads = 2;
int number_of_results = 5;
std::string model_name;
std::string labels_file_name;
bool edgetpu;
bool accel;
std::string external_delegate_path;
};
struct Label_Results {
float accuracy[10];
int index[10];
float inference_time;
};
class Tfl_Wrapper {
private:
// Taking a reference to the (const) model data avoids lifetime-related issues
// and complexity with the TFL_Model's existence.
#ifdef EDGETPU
std::shared_ptr<edgetpu::EdgeTpuContext> m_edgetpu_ctx;
#endif
std::unique_ptr<tflite::FlatBufferModel> m_model;
std::unique_ptr<tflite::Interpreter> m_interpreter;
bool m_verbose;
bool m_inputFloating;
bool m_allow_fp16;
float m_inputMean;
float m_inputStd;
float m_inferenceTime;
int m_numberOfThreads;
int m_numberOfResults;
bool m_edgetpu;
bool m_accel;
bool m_npu;
const char * m_external_delegate_path;
std::string m_vxdelegate;
public:
Tfl_Wrapper() {}
void Initialize(Config* conf)
{
m_inputFloating = false;
m_allow_fp16 = false;
m_inferenceTime = 0;
m_verbose = conf->verbose;
m_inputMean = conf->input_mean;
m_inputStd = conf->input_std;
m_numberOfThreads = conf->number_of_threads;
m_numberOfResults = conf->number_of_results;
m_edgetpu = conf->edgetpu;
if (m_edgetpu) {
/* Check if the Edge TPU is connected */
int status = system("lsusb -d 1a6e:");
status &= system("lsusb -d 18d1:");
if (status) {
std::cout << "ERROR: Edge TPU not connected.\n";
exit(-1);
}
/* Load EDGEPTU */
#ifdef EDGETPU
m_edgetpu_ctx = edgetpu::EdgeTpuManager::GetSingleton()->OpenDevice();
#endif
}
m_inputFloating = false;
m_allow_fp16 = false;
m_inferenceTime = 0;
m_verbose = conf->verbose;
m_inputMean = conf->input_mean;
m_inputStd = conf->input_std;
m_numberOfThreads = conf->number_of_threads;
m_numberOfResults = conf->number_of_results;
m_accel = conf->accel;
m_external_delegate_path = conf->external_delegate_path.c_str();
m_vxdelegate = "libvx_delegate";
m_npu = false;
/* Check which delegate is used */
std::size_t found = conf->external_delegate_path.find(m_vxdelegate);
if (found!=std::string::npos) {
/* vx_delegate found */
m_npu = true;
}
if (!conf->model_name.c_str()) {
LOG(ERROR) << "no model file name\n";
exit(-1);
}
std::unique_ptr<tflite::FlatBufferModel> model;
std::unique_ptr<tflite::Interpreter> interpreter;
model = tflite::FlatBufferModel::BuildFromFile(conf->model_name.c_str());
if (!model) {
LOG(FATAL) << "\nFailed to mmap model " << conf->model_name << "\n";
exit(-1);
}
LOG(INFO) << "Loaded model " << conf->model_name << "\n";
model->error_reporter();
tflite::ops::builtin::BuiltinOpResolver resolver;
if(m_edgetpu){
#ifdef EDGETPU
resolver.AddCustom(edgetpu::kCustomOp, edgetpu::RegisterCustomOp());
#endif
}
#ifdef VSI_OP
if(m_accel && m_npu) {
resolver.AddCustom(kNbgCustomOp, tflite::ops::custom::Register_VSI_NPU_PRECOMPILED());
}
#endif
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
if (!interpreter) {
LOG(FATAL) << "Failed to construct interpreter\n";
exit(-1);
}
#ifdef VSI_OP
if(m_accel) {
const char * delegate_path = m_external_delegate_path;
auto ext_delegate_option = TfLiteExternalDelegateOptionsDefault(delegate_path);
ext_delegate_option.insert(&ext_delegate_option, "cache_file_path", "/usr/local/demo-ai/image-classification/models/mobilenet/mobilenet_v3_large_100_224_quant.nb");
ext_delegate_option.insert(&ext_delegate_option, "allowed_cache_mode", "true");
auto ext_delegate_ptr = TfLiteExternalDelegateCreate(&ext_delegate_option);
interpreter->ModifyGraphWithDelegate(ext_delegate_ptr);
}
#endif
int input = interpreter->inputs()[0];
if (interpreter->tensor(input)->type == kTfLiteFloat32) {
m_inputFloating = true;
LOG(INFO) << "Floating point Tensorflow Lite Model\n";
}
if(m_edgetpu){
#ifdef EDGETPU
interpreter->SetExternalContext(kTfLiteEdgeTpuContext, m_edgetpu_ctx.get());
#endif
} else {
interpreter->SetAllowFp16PrecisionForFp32(m_allow_fp16);
}
if (m_numberOfThreads != -1) {
interpreter->SetNumThreads(m_numberOfThreads);
}
m_interpreter = std::move(interpreter);
m_model = std::move(model);
}
void DisplaySettings()
{
LOG(INFO) << "input_floating " << m_inputFloating << "\n";
LOG(INFO) << "allow_fp16 " << m_allow_fp16 << "\n";
LOG(INFO) << "input_mean " << m_inputMean << "\n";
LOG(INFO) << "input_std " << m_inputStd << "\n";
LOG(INFO) << "number_of_threads " << m_numberOfThreads << "\n";
LOG(INFO) << "number_of_results " << m_numberOfResults << "\n";
LOG(INFO) << "edgetpu " << m_edgetpu << "\n";
}
void DisplayModelInformation()
{
LOG(INFO) << "tensors size: " << m_interpreter->tensors_size() << "\n";
LOG(INFO) << "nodes size: " << m_interpreter->nodes_size() << "\n";
LOG(INFO) << "inputs: " << m_interpreter->inputs().size() << "\n";
LOG(INFO) << "input(0) name: " << m_interpreter->GetInputName(0) << "\n";
int t_size = m_interpreter->tensors_size();
for (int i = 0; i < t_size; i++) {
if (m_interpreter->tensor(i)->name)
LOG(INFO) << i << ": " << m_interpreter->tensor(i)->name << ", "
<< m_interpreter->tensor(i)->bytes << ", "
<< m_interpreter->tensor(i)->type << ", "
<< m_interpreter->tensor(i)->params.scale << ", "
<< m_interpreter->tensor(i)->params.zero_point << "\n";
}
}
bool IsModelQuantized()
{
return !m_inputFloating;
}
int GetInputWidth()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[2];
}
int GetInputHeight()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[1];
}
int GetInputChannels()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[3];
}
unsigned int GetNumberOfInputs()
{
const std::vector<int> inputs = m_interpreter->inputs();
return inputs.size();
}
unsigned int GetNumberOfOutputs()
{
const std::vector<int> outputs = m_interpreter->outputs();
return outputs.size();
}
unsigned int GetOutputSize(int index)
{
int output = m_interpreter->outputs()[index];
TfLiteIntArray* output_dims = m_interpreter->tensor(output)->dims;
// assume output dims to be something like (1, 1, ... ,size)
return output_dims->data[output_dims->size - 1];
}
void RunInference(uint8_t* img, Label_Results* results)
{
if (m_inputFloating)
RunInference<float>(img, results);
else
RunInference<uint8_t>(img, results);
}
template <class T>
void RunInference(uint8_t* img, Label_Results* results)
{
int input_height = GetInputHeight();
int input_width = GetInputWidth();
int input_channels = GetInputChannels();
auto sizeInBytes = input_height * input_width * input_channels;
int input = m_interpreter->inputs()[0];
if (m_verbose) {
LOG(INFO) << "input: " << input << "\n";
LOG(INFO) << "number of inputs: " << GetNumberOfInputs() << "\n";
LOG(INFO) << "number of outputs: " << GetNumberOfOutputs() << "\n";
}
if (m_interpreter->AllocateTensors() != kTfLiteOk) {
LOG(FATAL) << "Failed to allocate tensors!";
}
if (m_verbose)
tflite::PrintInterpreterState(m_interpreter.get());
auto in = m_interpreter->typed_tensor<T>(input);
if (m_inputFloating) {
for (int i = 0; i < sizeInBytes; i++)
in[i] = (img[i] - m_inputMean) / m_inputStd;
} else {
for (int i = 0; i < sizeInBytes; i++)
in[i] = img[i];
}
struct timeval start_time, stop_time;
gettimeofday(&start_time, nullptr);
if (m_interpreter->Invoke() != kTfLiteOk) {
LOG(FATAL) << "Failed to invoke tflite!\n";
}
gettimeofday(&stop_time, nullptr);
m_inferenceTime = (get_ms(stop_time) - get_ms(start_time));
/* Get results */
T* output = m_interpreter->typed_output_tensor<T>(0);
auto output_size = GetOutputSize(0);
for (int i = 0; i < m_numberOfResults; i++) {
results->index[i] = std::distance(&output[0], std::max_element(&output[0], &output[output_size]));
if (m_inputFloating)
results->accuracy[i] = output[results->index[i]];
else
results->accuracy[i] = output[results->index[i]] / 255.0;
output[results->index[i]] = 0;
}
results->inference_time = m_inferenceTime;
}
// Takes a file name, and loads a list of labels from it, one per line, and
// returns a vector of the strings. It pads with empty strings so the length
// of the result is a multiple of 16, because our model expects that.
TfLiteStatus ReadLabelsFile(const std::string& file_name,
std::vector<std::string>* result,
size_t* found_label_count)
{
std::ifstream file(file_name);
if (!file) {
LOG(FATAL) << "Labels file " << file_name << " not found\n";
return kTfLiteError;
}
result->clear();
std::string line;
while (std::getline(file, line)) {
result->push_back(line);
}
*found_label_count = result->size();
const int padding = 16;
while (result->size() % padding) {
result->emplace_back();
}
return kTfLiteOk;
}
};
} // namespace wrapper_tfl
#endif // WRAPPER_TFL_HPP_

View File

@ -0,0 +1,24 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV1 models for EdgeTPU "
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " https://raw.githubusercontent.com/google-coral/edgetpu/master/test_data/mobilenet_v1_1.0_224_quant_edgetpu.tflite;subdir=${BPN}-${PV}/mobilenet_v1_1.0_224_quant_edgetpu;name=mobilenet_v1_1.0_224_quant_edgetpu.tflite"
SRC_URI[mobilenet_v1_1.0_224_quant_edgetpu.tflite.md5sum] = "06b5764f4a5063903cac48c9fc96d8e5"
SRC_URI[mobilenet_v1_1.0_224_quant_edgetpu.tflite.sha256sum] = "e17124a57e78f51af6600a561a76cc13866ab9d039378b3dc83507941957f4b0"
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
# install mobilenet models
install -m 0644 ${S}/mobilenet_v1_1.0_224_quant_edgetpu/*.tflite ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " tflite-models-mobilenetv1 "

View File

@ -0,0 +1,26 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV1 models"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
#NBG model files need to be pre-compiled using STM32AI-MPU offline compiler tool.
#This package contain an example compiled for gcnano driver 6.4.13
SRC_URI = " file://mobilenet_v3_large_100_224_quant.nb \
file://labels_mobilenet_nbg.txt "
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/testdata
# install mobilenet models
install -m 0644 ${S}/labels_mobilenet_nbg.txt ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/labels_mobilenet_v3_nbg.txt
install -m 0644 ${S}/*.nb ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,30 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV1/2 models"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
# These models are not available in the onnx/models repository and integrating the tf2onnx
# converter in the yocto workflow (to convert them from tflite) would require integrating
# tensorflow (not lite) and bazel as well, which is a pretty big undertaking.
# So, for now, we will simply include the converted models manually.
SRC_URI = " file://mobilenet_v1_0.5_128.onnx \
file://mobilenet_v1_0.5_128_quant.onnx \
file://mobilenet_v1_1.0_224_quant.onnx \
file://labels_mobilenet_onnx.txt "
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/testdata
# install mobilenet models
install -m 0644 ${S}/label*.txt ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/labels_onnx.txt
install -m 0644 ${S}/*.onnx ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,28 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV1/2 models"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
# These models are not available in the onnx/models repository and integrating the tf2onnx
# converter in the yocto workflow (to convert them from tflite) would require integrating
# tensorflow (not lite) and bazel as well, which is a pretty big undertaking.
# So, for now, we will simply include the converted models manually.
SRC_URI = " file://mobilenet_v3_large_100_224_quant.onnx \
file://labels_mobilenet_onnx.txt "
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/testdata
# install mobilenet models
install -m 0644 ${S}/label*.txt ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/labels_mobilenet_v3_onnx.txt
install -m 0644 ${S}/*.onnx ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,34 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV1 models"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_1.0_224_quant_and_labels.zip;subdir=${BPN}-${PV}/mobilenet_v1_1.0_224_quant;name=mobilenet_v1_1.0_224_quant "
SRC_URI[mobilenet_v1_1.0_224_quant.md5sum] = "38ac0c626947875bd311ef96c8baab62"
SRC_URI[mobilenet_v1_1.0_224_quant.sha256sum] = "2f8054076cf655e1a73778a49bd8fd0306d32b290b7e576dda9574f00f186c0f"
SRC_URI += " https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_128_quant.tgz;subdir=${BPN}-${PV}/mobilenet_v1_0.5_128_quant;name=mobilenet_v1_0.5_128_quant "
SRC_URI[mobilenet_v1_0.5_128_quant.md5sum] = "5cc8484cf04a407fc90993296f3f02db"
SRC_URI[mobilenet_v1_0.5_128_quant.sha256sum] = "0a5b18571d3df4d85a5ac6cb5be829d141dd5855243ea04422ca7d19f730a506"
SRC_URI += " https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_0.5_128.tgz;subdir=${BPN}-${PV}/mobilenet_v1_0.5_128_float;name=mobilenet_v1_0.5_128_float "
SRC_URI[mobilenet_v1_0.5_128_float.md5sum] = "1950d02e12e2c85613c6f973b1213d1b"
SRC_URI[mobilenet_v1_0.5_128_float.sha256sum] = "5a0def0d844327526385b110cdcaa6428d0828ff6d07515ef25bf3976e049d88"
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/testdata
# install mobilenet models
install -m 0644 ${S}/mobilenet_v1_1.0_224_quant/label*.txt ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/labels.txt
install -m 0644 ${S}/mobilenet_v1_1.0_224_quant/*.tflite ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
install -m 0644 ${S}/mobilenet_v1_0.5_128_quant/*.tflite ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
install -m 0644 ${S}/mobilenet_v1_0.5_128_float/*.tflite ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,29 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing MobileNetV3 model"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " https://tfhub.dev/iree/lite-model/mobilenet_v3_large_100_224/uint8/1?lite-format=tflite;subdir=mobilenet_v3_large_100_224_quant;name=mobilenet_v3_large_100_224_quant "
SRC_URI += " file://labels_mobilenet_tflite.txt "
SRC_URI[mobilenet_v3_large_100_224_quant.md5sum] = "68451f4fdc681bca5c548c595386b918"
SRC_URI[mobilenet_v3_large_100_224_quant.sha256sum] = "78c5eddce8533ca95b4d122ec291694263b91c285616a9487f470c6a930a63cd"
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet
install -d ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/testdata
#the model is fetched with a bad name -> rename it before installation
mv ${S}/mobilenet_v3_large_100_224_quant/1\?lite-format\=tflite ${S}/mobilenet_v3_large_100_224_quant/mobilenet_v3_large_100_224_quant.tflite
# install mobilenetV3 model + corresponding label file
install -m 0644 ${S}/label*.txt ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/labels_mobilenet_v3.txt
install -m 0644 ${S}/mobilenet_v3_large_100_224_quant/*.tflite ${D}${prefix}/local/demo-ai/image-classification/models/mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,64 @@
# Copyright (C) 2023, STMicroelectronics - All Rights Reserved
SUMMARY = "NBG C++ Computer Vision image classification application example"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
inherit pkgconfig
COMPATIBLE_MACHINE = "stm32mp25common"
DEPENDS += "jpeg gcnano-driver-stm32mp gcnano-userland opencv gstreamer1.0-plugins-base gstreamer1.0-plugins-bad "
SRC_URI = " file://nbg;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} NEW_GST_WAYLAND_API=${NEW_GST_WAYLAND_API} -C ${S}/nbg/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/nbg
# install applications into the demo launcher
install -m 0755 ${S}/nbg/130-nbg-image-classification-C++.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/nbg/nbg_image_classification ${D}${prefix}/local/demo-ai/image-classification/nbg
install -m 0755 ${S}/nbg/launch_bin*.sh ${D}${prefix}/local/demo-ai/image-classification/nbg
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gtk+3 \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
application-resources \
nbg-models-mobilenetv3 \
bash \
"
#Depending of the Gstreamer version supported by the Yocto version the RDEPENDS differs
RDEPENDS:${PN} += "${@bb.utils.contains('DISTRO_CODENAME', 'kirkstone', ' gstreamer1.0-plugins-base-videoscale gstreamer1.0-plugins-base-videoconvert ', ' gstreamer1.0-plugins-base-videoconvertscale ', d)}"

View File

@ -0,0 +1,43 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "OnnxRuntime Python Computer Vision image classification application example"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://onnx;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/onnx
# install applications into the demo launcher
install -m 0755 ${S}/onnx/120-onnx-image-classification-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/onnx/onnx_image_classification.py ${D}${prefix}/local/demo-ai/image-classification/onnx
install -m 0755 ${S}/onnx/launch_python*.sh ${D}${prefix}/local/demo-ai/image-classification/onnx
}
do_install:append:stm32mp25common(){
install -m 0755 ${S}/onnx/120-onnx-image-classification-python-mp2.yaml ${D}${prefix}/local/demo/application/120-onnx-image-classification-python.yaml
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-onnxruntime \
application-resources \
bash \
"
RDEPENDS:${PN}:append:stm32mp25common = " onnx-models-mobilenetv3 "
RDEPENDS:${PN}:append:stm32mp1common = " onnx-models-mobilenetv1 "

View File

@ -0,0 +1,76 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite C++ API Computer Vision image classification application example"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit pkgconfig
DEPENDS += " tensorflow-lite gtk+3 opencv gstreamer1.0-plugins-base gstreamer1.0-plugins-bad"
DEPENDS:append:stm32mp25common = " tflite-vx-delegate"
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
BOARD_USED:stm32mp1common = "stm32mp1"
BOARD_USED:stm32mp25common = "stm32mp2_npu"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
EXTRA_OEMAKE += 'ARCHITECTURE="${BOARD_USED}"'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/tflite/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/tflite
# install applications into the demo launcher
install -m 0755 ${S}/tflite/101-tflite-image-classification-cpp.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_image_classification ${D}${prefix}/local/demo-ai/image-classification/tflite
install -m 0755 ${S}/tflite/launch_bin*.sh ${D}${prefix}/local/demo-ai/image-classification/tflite
}
do_install:append:stm32mp25common(){
install -m 0755 ${S}/tflite/101-tflite-image-classification-cpp-mp2.yaml ${D}${prefix}/local/demo/application/101-tflite-image-classification-cpp.yaml
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gstreamer1.0-plugins-base-videoconvertscale \
gtk+3 \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
tensorflow-lite \
application-resources \
bash \
"
#Depending of the Gstreamer version supported by the Yocto version the RDEPENDS differs
RDEPENDS:${PN} += "${@bb.utils.contains('DISTRO_CODENAME', 'kirkstone', ' gstreamer1.0-plugins-base-videoscale gstreamer1.0-plugins-base-videoconvert ', ' gstreamer1.0-plugins-base-videoconvertscale ', d)}"
RDEPENDS:${PN}:append:stm32mp25common = " tflite-models-mobilenetv3 "
RDEPENDS:${PN}:append:stm32mp25common = " nbg-models-mobilenetv3 "
RDEPENDS:${PN}:append:stm32mp1common = " tflite-models-mobilenetv1 "

View File

@ -0,0 +1,44 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite Python Computer Vision image classification application example"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/image-classification/tflite
# install applications into the demo launcher
install -m 0755 ${S}/tflite/100-tflite-image-classification-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_image_classification.py ${D}${prefix}/local/demo-ai/image-classification/tflite
install -m 0755 ${S}/tflite/launch_python*.sh ${D}${prefix}/local/demo-ai/image-classification/tflite
}
do_install:append:stm32mp25common(){
install -m 0755 ${S}/tflite/100-tflite-image-classification-python-mp2.yaml ${D}${prefix}/local/demo/application/100-tflite-image-classification-python.yaml
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-tensorflow-lite \
application-resources \
bash \
"
RDEPENDS:${PN}:append:stm32mp25common = " tflite-models-mobilenetv3 "
RDEPENDS:${PN}:append:stm32mp25common = " nbg-models-mobilenetv3 "
RDEPENDS:${PN}:append:stm32mp1common = " tflite-models-mobilenetv1 "

View File

@ -0,0 +1,63 @@
# Copyright (C) 2020, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite C++ API Computer Vision object detection application example running on the EdgeTPU"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit pkgconfig
DEPENDS += "tensorflow-lite libedgetpu gtk+3 opencv gstreamer1.0 rapidjson gstreamer1.0-plugins-base gstreamer1.0-plugins-bad "
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
EXTRA_OEMAKE += 'EDGETPU=TRUE'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/tflite/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/coral
# install applications into the demo launcher
install -m 0755 ${S}/tflite/211-coral-object-detection-C++.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_object_detection ${D}${prefix}/local/demo-ai/object-detection/coral/coral_object_detection
install -m 0755 ${S}/tflite/launch_coral_bin*.sh ${D}${prefix}/local/demo-ai/object-detection/coral
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gstreamer1.0-plugins-base-videoconvertscale \
gtk+3 \
libedgetpu \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
coral-models-coco-ssd-mobilenetv1 \
application-resources \
bash \
"

View File

@ -0,0 +1,38 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite Python Computer Vision object detection application examples running on the EdgeTPU"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/coral
# install applications into the demo launcher
install -m 0755 ${S}/tflite/210-coral-object-detection-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_object_detection.py ${D}${prefix}/local/demo-ai/object-detection/coral/coral_object_detection.py
install -m 0755 ${S}/tflite/launch_coral_python*.sh ${D}${prefix}/local/demo-ai/object-detection/coral
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-tensorflow-lite \
libedgetpu \
coral-models-coco-ssd-mobilenetv1 \
application-resources \
bash \
"

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/onnx_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/onnx/launch_python_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/onnx_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/onnx/launch_bin_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,26 @@
OPENCV_PKGCONFIG?="opencv4"
SYSROOT?=""
TARGET_BIN = onnx_object_detection
CXXFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0 $(OPENCV_PKGCONFIG) gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
CXXFLAGS += -std=c++17
CXXFLAGS += -I$(SYSROOT)/usr/include/rapidjson
CXXFLAGS += -I$(SYSROOT)/usr/include/onnxruntime
CXXFLAGS += -I$(SYSROOT)/usr/include/onnxruntime/core/session
LDFLAGS = $(shell pkg-config --libs gtk+-3.0 gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
LDFLAGS += -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lonnxruntime
SRCS = onnx_object_detection.cc
OBJS = $(SRCS:.cc=.o)
all: $(TARGET_BIN)
$(TARGET_BIN): $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c $^
clean:
rm -rf $(OBJS) $(TARGET_BIN)

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/object-detection/onnx/onnx_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.onnx -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet_onnx.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/object-detection/onnx/onnx_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.onnx -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet_onnx.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/onnx/onnx_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.onnx -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet_onnx.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/onnx/onnx_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.onnx -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet_onnx.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,400 @@
/*
* wrapper_onnx.hpp
*
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
* Co-Author : Youssef Khemakhem <youssef.khemakhem@st.com> for STMicroelectronics.
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.opensource.org/licenses/BSD-3-Clause
*
*
*
*/
#ifndef WRAPPER_ONNX_HPP_
#define WRAPPER_ONNX_HPP_
#include <algorithm>
#include <functional>
#include <fstream>
#include <queue>
#include <memory>
#include <string>
#include <sys/time.h>
#include <vector>
#include <cmath>
#include <numeric>
#include "onnxruntime_cxx_api.h"
#define LOG(x) std::cerr
namespace wrapper_onnx {
double get_ms(struct timeval t) { return (t.tv_sec * 1000 + t.tv_usec / 1000); }
bool first_call = true;
struct Config {
bool verbose;
float input_mean = 127.5f;
float input_std = 127.5f;
int number_of_threads = 2;
int number_of_results = 5;
std::string model_name;
std::string labels_file_name;
};
struct ObjDetect_Location {
float y0, x0, y1, x1;
};
struct ObjDetect_Results {
int classe;
float score;
ObjDetect_Location location;
};
struct Frame_Results {
std::vector<ObjDetect_Results> vect_ObjDetect_Results;
float inference_time;
};
std::nullptr_t t ;
class Onnx_Wrapper {
private:
Ort::Session m_session ;
Ort::AllocatorWithDefaultOptions m_allocator;
bool m_verbose;
bool m_inputFloating;
float m_inputMean;
float m_inputStd;
float m_inferenceTime;
int m_numberOfThreads;
int m_numberOfResults;
public:
Onnx_Wrapper():m_session(t) {}
void Initialize(Config* conf)
{
m_inputFloating = false;
m_inferenceTime = 0;
m_verbose = conf->verbose;
m_inputMean = conf->input_mean;
m_inputStd = conf->input_std;
m_numberOfThreads = conf->number_of_threads;
m_numberOfResults = conf->number_of_results;
if (!conf->model_name.c_str()) {
LOG(ERROR) << "no model file name\n";
exit(-1);
}
/* create an environment */
Ort::Env m_env(ORT_LOGGING_LEVEL_WARNING, "Onnx_environment");
/* create session options */
Ort::SessionOptions m_session_options;
/* Define number of threads */
if (m_numberOfThreads != -1) {
m_session_options.SetIntraOpNumThreads(m_numberOfThreads);
if (m_verbose) {
m_session_options.SetLogSeverityLevel(0);
}
}
m_session_options.DisableCpuMemArena();
/* create a session from the ONNX model file */
Ort::Session session(m_env,conf->model_name.c_str(), m_session_options);
if (session==nullptr)
{ ORT_CXX_API_THROW("", OrtErrorCode::ORT_NO_MODEL );}
LOG(INFO) << "Loaded model " << conf->model_name << "\n";
Ort::TypeInfo inputTypeInfo = session.GetInputTypeInfo(0);
auto tensorInfo = inputTypeInfo.GetTensorTypeAndShapeInfo();
if (tensorInfo.GetElementType()== ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT)
{
m_inputFloating = true;
LOG(INFO) << "Floating point Onnx Model\n";
}
m_session=std::move(session) ;
}
void DisplaySettings()
{
LOG(INFO) << "input_floating " << m_inputFloating << "\n";
LOG(INFO) << "input_mean " << m_inputMean << "\n";
LOG(INFO) << "input_std " << m_inputStd << "\n";
LOG(INFO) << "number_of_threads " << m_numberOfThreads << "\n";
LOG(INFO) << "number_of_results " << m_numberOfResults << "\n";
}
void DisplayModelInformation()
{
auto input_name = m_session.GetInputNameAllocated(0, m_allocator);
const size_t num_input_nodes = m_session.GetInputCount();
size_t num_output_nodes = m_session.GetOutputCount();
LOG(INFO) << "tensors size: " << num_input_nodes + num_output_nodes << "\n";
LOG(INFO) << "inputs: " << num_input_nodes << "\n";
LOG(INFO) << "input(0) name: " << input_name.get() << "\n";
/* Log information about input tensors */
size_t numInputNodes = m_session.GetInputCount();
for (size_t i = 0; i < numInputNodes; i++) {
Ort::TypeInfo inputTypeInfo = m_session.GetInputTypeInfo(i);
auto tensor_info = inputTypeInfo.GetTensorTypeAndShapeInfo();
auto tensor_input_name = m_session.GetInputNameAllocated(i, m_allocator);
if (tensor_input_name.get())
{
LOG(INFO) << i << ": " << tensor_input_name.get() << ", "
<< tensor_info.GetElementCount() << ", " // the number of elements specified by the tensor shape (all dimensions multiplied by each other)
<< tensor_info.GetElementType() << ", "
<< tensor_info.GetDimensionsCount() << "\n" ;
}
}
/* Log information about output tensors */
size_t numOutputNodes = m_session.GetOutputCount();
for (size_t i = 0; i < numOutputNodes; i++)
{
Ort::TypeInfo outputTypeInfo = m_session.GetOutputTypeInfo(i);
auto tensor_info = outputTypeInfo.GetTensorTypeAndShapeInfo();
auto tensor_output_name = m_session.GetOutputNameAllocated(i, m_allocator);
if (tensor_output_name.get())
{
LOG(INFO) << i << ": " << tensor_output_name.get() << ", "
<< tensor_info.GetElementCount()<< ", "
<< tensor_info.GetElementType()<< ", "
<< tensor_info.GetDimensionsCount() << "\n" ;
}
}
}
bool IsModelQuantized()
{
return !m_inputFloating;
}
int GetInputWidth()
{
std::vector<int64_t> input_shape = m_session.GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
return input_shape[2];
}
int GetInputHeight()
{
std::vector<int64_t> input_shape = m_session.GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
return input_shape[1];
}
int GetInputChannels()
{
std::vector<int64_t> input_shape = m_session.GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
return input_shape[3];
}
unsigned int GetNumberOfInputs()
{
return m_session.GetInputCount();
}
unsigned int GetNumberOfOutputs()
{
return m_session.GetOutputCount();
}
unsigned int GetOutputSize(int index)
{
Ort::TypeInfo type_info = m_session.GetOutputTypeInfo(index);
// assume output dims to be something like (1, 1, ... ,size)
return type_info.GetTensorTypeAndShapeInfo().GetShape()[type_info.GetTensorTypeAndShapeInfo().GetShape().size() - 1];
}
void RunInference(uint8_t* img, Frame_Results* results)
{
if (m_inputFloating)
RunInference<float>(img, results);
else
RunInference<uint8_t>(img, results);
}
template <typename T>
T Vector_Product(const std::vector<T>& vect)
{
return accumulate(vect.begin(), vect.end(), 1, std::multiplies<T>());
}
template <class T>
void RunInference(uint8_t* img, Frame_Results* results)
{
int input_height = GetInputHeight();
int input_width = GetInputWidth();
int input_channels = GetInputChannels();
auto sizeInBytes = input_height * input_width * input_channels;
auto input_name = m_session.GetInputNameAllocated(0, m_allocator);
if (m_verbose) {
LOG(INFO) << "input: " << input_name.get() << "\n";
LOG(INFO) << "number of inputs: " << GetNumberOfInputs() << "\n";
LOG(INFO) << "number of outputs: " << GetNumberOfOutputs() << "\n";
}
/* Prepare input output tensors */
std::vector<Ort::Value> inputTensors;
std::vector<Ort::Value> outputTensors;
std::vector< int64_t > inputDims=m_session.GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
size_t inputTensorSize =Vector_Product(inputDims); //sizeInBytes
std::vector<int64_t> outputDims = m_session.GetOutputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
size_t outputTensorSize = Vector_Product(outputDims);
Ort::MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
/* Prepare empty output tensor */
std::vector<float> outputTensorValues(outputTensorSize);
outputTensors.push_back(Ort::Value::CreateTensor(memoryInfo, outputTensorValues.data(), outputTensorSize, outputDims.data(), outputDims.size()));
/* Get input */
float* in ;
if (m_inputFloating) {
for (int i = 0; i < sizeInBytes; i++){
in[i] =(img[i] - m_inputMean) / m_inputStd;
inputTensors.push_back(Ort::Value::CreateTensor(memoryInfo, &(in[i]) , inputTensorSize, inputDims.data(),inputDims.size()));}
} else {
for (int i = 0; i < sizeInBytes; i++)
inputTensors.push_back(Ort::Value::CreateTensor(memoryInfo, &(img[i]), inputTensorSize, inputDims.data(),inputDims.size()));
}
/* Get input names */
size_t num_input_nodes = GetNumberOfInputs();
input_name = m_session.GetInputNameAllocated(0, m_allocator);
const char* inputNames[] = {input_name.get()};
/* Get Output names */
size_t num_output_nodes = m_session.GetOutputCount();
std::vector<std::string> output_names(num_output_nodes);
for (size_t i = 0; i != num_output_nodes; ++i) {
auto output_name = m_session.GetOutputNameAllocated(i, m_allocator);
assert(output_name != nullptr);
output_names[i] = output_name.get();
}
std::vector<const char*> outputNames(num_output_nodes);
{
for (size_t i = 0; i != num_output_nodes; ++i) {
outputNames[i] = output_names[i].c_str();
}
}
/* Run Inference */
Ort::RunOptions run_options;
if (m_verbose) {
run_options.SetRunLogSeverityLevel(0);
}
struct timeval start_time, stop_time;
gettimeofday(&start_time, nullptr);
std::cout << "Running inference ..." << std::endl;
outputTensors = m_session.Run(run_options, inputNames, inputTensors.data(), num_input_nodes, outputNames.data(), num_output_nodes);
gettimeofday(&stop_time, nullptr);
m_inferenceTime = (get_ms(stop_time) - get_ms(start_time));
/* Get results */
float *locations = outputTensors[0].GetTensorMutableData<float>();
float *classes = outputTensors[1].GetTensorMutableData<float>();
float *scores = outputTensors[2].GetTensorMutableData<float>();
// get the output size by getting the size of the
// output tensor 1 that represents the classes
auto output_size = GetOutputSize(1);
// creation of an ObjDetect_Results struct to store values
// of detected object of the frame
ObjDetect_Results Obj_detected;
// the outputs are already sorted by descending order
if (first_call){
for (unsigned int i = 0; i < output_size; i++) {
Obj_detected.classe =(int)classes[i];
Obj_detected.score = scores[i];
Obj_detected.location.y0 = locations[(i * 4) + 0];
Obj_detected.location.x0 = locations[(i * 4) + 1];
Obj_detected.location.y1 = locations[(i * 4) + 2];
Obj_detected.location.x1 = locations[(i * 4) + 3];
results->vect_ObjDetect_Results.push_back(Obj_detected);
}
results->inference_time = m_inferenceTime;
} else {
for (unsigned int i = 0; i < output_size; i++) {
results->vect_ObjDetect_Results.erase(results->vect_ObjDetect_Results.begin()+i);
Obj_detected.classe =(int)classes[i];
Obj_detected.score = scores[i];
Obj_detected.location.y0 = locations[(i * 4) + 0];
Obj_detected.location.x0 = locations[(i * 4) + 1];
Obj_detected.location.y1 = locations[(i * 4) + 2];
Obj_detected.location.x1 = locations[(i * 4) + 3];
results->vect_ObjDetect_Results.insert(results->vect_ObjDetect_Results.begin()+i,Obj_detected);
}
results->inference_time = m_inferenceTime;
}
first_call = false;
}
// Takes a file name, and loads a list of labels from it, one per line, and
// returns a vector of the strings. It pads with empty strings so the length
// of the result is a multiple of 16, because our model expects that.
bool ReadLabelsFile(const std::string& file_name,
std::vector<std::string>* result,
size_t* found_label_count)
{
std::ifstream file(file_name);
if (!file) {
LOG(FATAL) << "Labels file " << file_name << " not found\n";
return 0;
}
result->clear();
std::string line;
while (std::getline(file, line)) {
result->push_back(line);
}
*found_label_count = result->size();
const int padding = 16;
while (result->size() % padding) {
result->emplace_back();
}
return 1;
}
};
} // namespace wrapper_onnx
#endif // WRAPPER_ONNX_HPP_

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: YoloV4 tiny
Icon: ../demo-ai/resources/tfl_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/tflite/launch_python_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/tfl_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/tflite/launch_python_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/tfl_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/tflite/launch_bin_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/coral_python.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/coral/launch_coral_python_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,15 @@
Application:
Name: Object Detection
Description: COCO SSD v1
Icon: ../demo-ai/resources/coral_cpp.png
Board:
List: all
Type: script
Script:
Exist:
File: /usr/local/demo-ai/resources/check_camera_preview.sh
Msg_false: Camera is not connected
Start: ../demo-ai/object-detection/coral/launch_coral_bin_object_detection.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox

View File

@ -0,0 +1,37 @@
OPENCV_PKGCONFIG?="opencv4"
SYSROOT?=""
EDGETPU?=""
ARCHITECTURE?=""
TARGET_BIN = tflite_object_detection
CXXFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0 $(OPENCV_PKGCONFIG) gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
CXXFLAGS += -std=c++17
CXXFLAGS += -I$(SYSROOT)/usr/include/tensorflow/lite/flatbuffers/include
CXXFLAGS += -I$(SYSROOT)/usr/include/tensorflow/lite/abseil-cpp
CXXFLAGS += -I$(SYSROOT)/usr/include/rapidjson
LDFLAGS = $(shell pkg-config --libs gtk+-3.0 gstreamer-plugins-base-1.0 gstreamer-wayland-1.0)
LDFLAGS += -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -ltensorflow-lite
ifneq (,$(findstring stm32mp2_npu,$(ARCHITECTURE)))
CXXFLAGS += -DVSI_OP
LDFLAGS += -lvx_custom_op
endif
ifneq (,$(findstring TRUE,$(EDGETPU)))
CXXFLAGS += -DEDGETPU
LDFLAGS += -ledgetpu
endif
SRCS = tflite_object_detection.cc
OBJS = $(SRCS:.cc=.o)
all: $(TARGET_BIN)
$(TARGET_BIN): $(OBJS)
$(CXX) -o $@ $^ $(LDFLAGS)
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c $^
clean:
rm -rf $(OBJS) $(TARGET_BIN)

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/object-detection/tflite/tflite_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/object-detection/tflite/tflite_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/ $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="/usr/local/demo-ai/object-detection/coral/coral_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet_edgetpu.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
cmd="/usr/local/demo-ai/object-detection/coral/coral_object_detection -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet_edgetpu.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/ --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/coral/coral_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet_edgetpu.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT --edgetpu"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
cmd="python3 /usr/local/demo-ai/object-detection/coral/coral_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet_edgetpu.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/ --edgetpu "
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/tflite/tflite_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/tflite/tflite_object_detection.py -m /usr/local/demo-ai/object-detection/models/yolov4-tiny/yolov4_tiny_416_quant.tflite -l /usr/local/demo-ai/object-detection/models/yolov4-tiny/labels_yolov4_tiny.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/tflite/tflite_object_detection.py -m /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.tflite -l /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt -i /usr/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata/ $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}')
source /usr/local/demo-ai/resources/config_board.sh
cmd="python3 /usr/local/demo-ai/object-detection/tflite/tflite_object_detection.py -m /usr/local/demo-ai/object-detection/models/yolov4-tiny/yolov4_tiny_416_quant.tflite -l /usr/local/demo-ai/object-detection/models/yolov4-tiny/labels_yolov4_tiny.txt -i /usr/local/demo-ai/object-detection/models/yolov4-tiny/testdata/ $COMPUTE_ENGINE"
if [ "$weston_user" != "root" ]; then
echo "user : "$weston_user
script -qc "su -l $weston_user -c '$cmd'"
else
$cmd
fi

View File

@ -0,0 +1,407 @@
/*
* wrapper_tfl.hpp
*
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
*
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.opensource.org/licenses/BSD-3-Clause
*
*
*
* Inspired by:
* https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/examples/label_image
* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef WRAPPER_TFL_HPP_
#define WRAPPER_TFL_HPP_
#include <algorithm>
#include <functional>
#include <fstream>
#include <queue>
#include <memory>
#include <string>
#include <sys/time.h>
#include <vector>
#include <fstream>
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/optional_debug_tools.h"
#ifdef EDGETPU
#include "tflite/public/edgetpu.h"
#endif
#include "tensorflow/lite/delegates/external/external_delegate.h"
#include "tensorflow/lite/interpreter.h"
#ifdef VSI_OP
#include "VX/vsi_npu_custom_op.h"
#endif
#define LOG(x) std::cerr
namespace wrapper_tfl {
double get_ms(struct timeval t) { return (t.tv_sec * 1000 + t.tv_usec / 1000); }
bool first_call = true;
struct Config {
bool verbose;
float input_mean = 127.5f;
float input_std = 127.5f;
int number_of_threads = 2;
int number_of_results = 5;
std::string model_name;
std::string labels_file_name;
bool edgetpu;
bool accel;
std::string external_delegate_path;
};
struct ObjDetect_Location {
float y0, x0, y1, x1;
};
struct ObjDetect_Results {
int classe;
float score;
ObjDetect_Location location;
};
struct Frame_Results {
std::vector<ObjDetect_Results> vect_ObjDetect_Results;
float inference_time;
};
class Tfl_Wrapper {
private:
// Taking a reference to the (const) model data avoids lifetime-related issues
// and complexity with the TFL_Model's existence.
#ifdef EDGETPU
std::shared_ptr<edgetpu::EdgeTpuContext> m_edgetpu_ctx;
#endif
std::unique_ptr<tflite::FlatBufferModel> m_model;
std::unique_ptr<tflite::Interpreter> m_interpreter;
bool m_verbose;
bool m_inputFloating;
bool m_allow_fp16;
float m_inputMean;
float m_inputStd;
float m_inferenceTime;
int m_numberOfThreads;
int m_numberOfResults;
bool m_edgetpu;
bool m_accel;
bool m_npu;
const char * m_external_delegate_path;
std::string m_vxdelegate;
public:
Tfl_Wrapper() {}
void Initialize(Config* conf)
{
m_inputFloating = false;
m_allow_fp16 = false;
m_inferenceTime = 0;
m_verbose = conf->verbose;
m_inputMean = conf->input_mean;
m_inputStd = conf->input_std;
m_numberOfThreads = conf->number_of_threads;
m_numberOfResults = conf->number_of_results;
m_accel = conf->accel;
m_external_delegate_path = conf->external_delegate_path.c_str();
m_vxdelegate = "libvx_delegate";
m_npu = false;
m_edgetpu = conf->edgetpu;
if (m_edgetpu) {
/* Check if the Edge TPU is connected */
int status = system("lsusb -d 1a6e:");
status &= system("lsusb -d 18d1:");
if (status) {
std::cout << "ERROR: Edge TPU not connected.\n";
exit(1);
}
/* Load EDGETPU */
#ifdef EDGETPU
m_edgetpu_ctx = edgetpu::EdgeTpuManager::GetSingleton()->OpenDevice();
#endif
}
/* Check which delegate is used */
std::size_t found = conf->external_delegate_path.find(m_vxdelegate);
if (found!=std::string::npos) {
/* vx_delegate found */
m_npu = true;
}
if (!conf->model_name.c_str()) {
LOG(ERROR) << "no model file name\n";
exit(-1);
}
std::unique_ptr<tflite::FlatBufferModel> model;
std::unique_ptr<tflite::Interpreter> interpreter;
model = tflite::FlatBufferModel::BuildFromFile(conf->model_name.c_str());
if (!model) {
LOG(FATAL) << "\nFailed to mmap model " << conf->model_name << "\n";
exit(-1);
}
LOG(INFO) << "Loaded model " << conf->model_name << "\n";
model->error_reporter();
tflite::ops::builtin::BuiltinOpResolver resolver;
if(m_edgetpu){
#ifdef EDGETPU
resolver.AddCustom(edgetpu::kCustomOp, edgetpu::RegisterCustomOp());
#endif
}
#ifdef VSI_OP
if(m_accel && m_npu) {
resolver.AddCustom(kNbgCustomOp, tflite::ops::custom::Register_VSI_NPU_PRECOMPILED());
}
#endif
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
if (!interpreter) {
LOG(FATAL) << "Failed to construct interpreter\n";
exit(-1);
}
#ifdef VSI_OP
if(m_accel) {
const char * delegate_path = m_external_delegate_path;
auto ext_delegate_option = TfLiteExternalDelegateOptionsDefault(delegate_path);
auto ext_delegate_ptr = TfLiteExternalDelegateCreate(&ext_delegate_option);
interpreter->ModifyGraphWithDelegate(ext_delegate_ptr);
}
#endif
int input = interpreter->inputs()[0];
if (interpreter->tensor(input)->type == kTfLiteFloat32) {
m_inputFloating = true;
LOG(INFO) << "Floating point Tensorflow Lite Model\n";
}
if(m_edgetpu){
#ifdef EDGETPU
interpreter->SetExternalContext(kTfLiteEdgeTpuContext, m_edgetpu_ctx.get());
#endif
} else {
interpreter->SetAllowFp16PrecisionForFp32(m_allow_fp16);
}
if (m_numberOfThreads != -1) {
interpreter->SetNumThreads(m_numberOfThreads);
}
m_interpreter = std::move(interpreter);
m_model = std::move(model);
}
void DisplaySettings()
{
LOG(INFO) << "input_floating " << m_inputFloating << "\n";
LOG(INFO) << "allow_fp16 " << m_allow_fp16 << "\n";
LOG(INFO) << "input_mean " << m_inputMean << "\n";
LOG(INFO) << "input_std " << m_inputStd << "\n";
LOG(INFO) << "number_of_threads " << m_numberOfThreads << "\n";
LOG(INFO) << "number_of_results " << m_numberOfResults << "\n";
LOG(INFO) << "edgetpu " << m_edgetpu << "\n";
}
void DisplayModelInformation()
{
LOG(INFO) << "tensors size: " << m_interpreter->tensors_size() << "\n";
LOG(INFO) << "nodes size: " << m_interpreter->nodes_size() << "\n";
LOG(INFO) << "inputs: " << m_interpreter->inputs().size() << "\n";
LOG(INFO) << "input(0) name: " << m_interpreter->GetInputName(0) << "\n";
int t_size = m_interpreter->tensors_size();
for (int i = 0; i < t_size; i++) {
if (m_interpreter->tensor(i)->name)
LOG(INFO) << i << ": " << m_interpreter->tensor(i)->name << ", "
<< m_interpreter->tensor(i)->bytes << ", "
<< m_interpreter->tensor(i)->type << ", "
<< m_interpreter->tensor(i)->params.scale << ", "
<< m_interpreter->tensor(i)->params.zero_point << "\n";
}
}
bool IsModelQuantized()
{
return !m_inputFloating;
}
int GetInputWidth()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[2];
}
int GetInputHeight()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[1];
}
int GetInputChannels()
{
int input = m_interpreter->inputs()[0];
TfLiteIntArray* input_dims = m_interpreter->tensor(input)->dims;
return input_dims->data[3];
}
unsigned int GetNumberOfInputs()
{
const std::vector<int> inputs = m_interpreter->inputs();
return inputs.size();
}
unsigned int GetNumberOfOutputs()
{
const std::vector<int> outputs = m_interpreter->outputs();
return outputs.size();
}
unsigned int GetOutputSize(int index)
{
int output = m_interpreter->outputs()[index];
TfLiteIntArray* output_dims = m_interpreter->tensor(output)->dims;
// assume output dims to be something like (1, 1, ... ,size)
return output_dims->data[output_dims->size - 1];
}
void RunInference(uint8_t* img, Frame_Results* results)
{
if (m_inputFloating)
RunInference<float>(img, results);
else
RunInference<uint8_t>(img, results);
}
template <class T>
void RunInference(uint8_t* img, Frame_Results* results)
{
int input_height = GetInputHeight();
int input_width = GetInputWidth();
int input_channels = GetInputChannels();
auto sizeInBytes = input_height * input_width * input_channels;
int input = m_interpreter->inputs()[0];
if (m_verbose) {
LOG(INFO) << "input: " << input << "\n";
LOG(INFO) << "number of inputs: " << GetNumberOfInputs() << "\n";
LOG(INFO) << "number of outputs: " << GetNumberOfOutputs() << "\n";
}
if (m_interpreter->AllocateTensors() != kTfLiteOk) {
LOG(FATAL) << "Failed to allocate tensors!";
}
if (m_verbose)
tflite::PrintInterpreterState(m_interpreter.get());
auto in = m_interpreter->typed_tensor<T>(input);
if (m_inputFloating) {
for (int i = 0; i < sizeInBytes; i++)
in[i] = (img[i] - m_inputMean) / m_inputStd;
} else {
for (int i = 0; i < sizeInBytes; i++)
in[i] = img[i];
}
struct timeval start_time, stop_time;
gettimeofday(&start_time, nullptr);
if (m_interpreter->Invoke() != kTfLiteOk) {
LOG(FATAL) << "Failed to invoke tflite!\n";
}
gettimeofday(&stop_time, nullptr);
m_inferenceTime = (get_ms(stop_time) - get_ms(start_time));
/* Get results */
float *locations = m_interpreter->typed_output_tensor<float>(0);
float *classes = m_interpreter->typed_output_tensor<float>(1);
float *scores = m_interpreter->typed_output_tensor<float>(2);
// get the output size by geting the size of the
// output tensor 1 that represente the classes
auto output_size = GetOutputSize(1);
// creation of an ObjDetect_Results struct to store values
// of detected object the frame
ObjDetect_Results Obj_detected;
// the outputs are already sort by descending order
if (first_call){
for (unsigned int i = 0; i < output_size; i++) {
Obj_detected.classe =(int)classes[i];
Obj_detected.score = scores[i];
Obj_detected.location.y0 = locations[(i * 4) + 0];
Obj_detected.location.x0 = locations[(i * 4) + 1];
Obj_detected.location.y1 = locations[(i * 4) + 2];
Obj_detected.location.x1 = locations[(i * 4) + 3];
results->vect_ObjDetect_Results.push_back(Obj_detected);
}
results->inference_time = m_inferenceTime;
} else {
for (unsigned int i = 0; i < output_size; i++) {
results->vect_ObjDetect_Results.erase(results->vect_ObjDetect_Results.begin()+i);
Obj_detected.classe =(int)classes[i];
Obj_detected.score = scores[i];
Obj_detected.location.y0 = locations[(i * 4) + 0];
Obj_detected.location.x0 = locations[(i * 4) + 1];
Obj_detected.location.y1 = locations[(i * 4) + 2];
Obj_detected.location.x1 = locations[(i * 4) + 3];
results->vect_ObjDetect_Results.insert(results->vect_ObjDetect_Results.begin()+i,Obj_detected);
}
results->inference_time = m_inferenceTime;
}
first_call = false;
}
// Takes a file name, and loads a list of labels from it, one per line, and
// returns a vector of the strings. It pads with empty strings so the length
// of the result is a multiple of 16, because our model expects that.
TfLiteStatus ReadLabelsFile(const std::string& file_name,
std::vector<std::string>* result,
size_t* found_label_count)
{
std::ifstream file(file_name);
if (!file) {
LOG(FATAL) << "Labels file " << file_name << " not found\n";
return kTfLiteError;
}
result->clear();
std::string line;
while (std::getline(file, line)) {
result->push_back(line);
}
*found_label_count = result->size();
const int padding = 16;
while (result->size() % padding) {
result->emplace_back();
}
return kTfLiteOk;
}
};
} // namespace wrapper_tfl
#endif // WRAPPER_TFL_HPP_

View File

@ -0,0 +1,21 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing COCO SSD MobileNetV1 models for Edge TPU"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " file://coco_ssd_mobilenet_edgetpu.tflite;subdir=${BPN}-${PV}"
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet
install -m 0644 ${S}/*_edgetpu.tflite ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " tflite-models-coco-ssd-mobilenetv1 "

View File

@ -0,0 +1,90 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
???
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
???
backpack
umbrella
???
???
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
???
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
???
dining table
???
???
toilet
???
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
???
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

View File

@ -0,0 +1,80 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
dining table
toilet
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

View File

@ -0,0 +1,27 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing COCO SSD MobileNetV1 models"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
# This model is not available in the onnx/models repository and integrating the tf2onnx
# converter in the yocto workflow (to convert it from tflite) would require integrating
# tensorflow (not lite) and bazel as well, which is a pretty big undertaking.
# So, for now, we will simply include the converted model manually.
SRC_URI = " file://coco_ssd_mobilenet.onnx \
file://labels_coco_ssd_mobilenet_onnx.txt"
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet
install -d ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata
# install coco ssd mobilenet model
install -m 0644 ${S}/label*.txt ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet_onnx.txt
install -m 0644 ${S}/*.onnx ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,30 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing COCO SSD MobileNetV1 models used for the \
application examples"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " http://storage.googleapis.com/download.tensorflow.org/models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip;subdir=${BPN}-${PV}/coco_ssd_mobilenet_v1_1.0_quant;name=coco_ssd_mobilenet_v1_1.0_quant "
SRC_URI[coco_ssd_mobilenet_v1_1.0_quant.md5sum] = "3764f289165250252d2323d718c04d83"
SRC_URI[coco_ssd_mobilenet_v1_1.0_quant.sha256sum] = "a809cd290b4d6a2e8a9d5dad076e0bd695b8091974e0eed1052b480b2f21b6dc"
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet
install -d ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/testdata
# install coco ssd mobilenet model
# label file of the coco ssd mobilenet may be wrong, patch it before installation
if [ "$(sed -n '/^???/p;q' ${S}/coco_ssd_mobilenet_v1_1.0_quant/label*.txt)" = "???" ]; then
# if the first line match '???' string, remove it
sed -i '1d' ${S}/coco_ssd_mobilenet_v1_1.0_quant/label*.txt
fi;
install -m 0644 ${S}/coco_ssd_mobilenet_v1_1.0_quant/label*.txt ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/labels_coco_ssd_mobilenet.txt
install -m 0644 ${S}/coco_ssd_mobilenet_v1_1.0_quant/*.tflite ${D}${prefix}/local/demo-ai/object-detection/models/coco_ssd_mobilenet/coco_ssd_mobilenet.tflite
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,27 @@
# Copyright (C) 2019, STMicroelectronics - All Rights Reserved
SUMMARY = "Create package containing yolov4_tiny model"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
#yolov4_tiny model weights and config come from https://github.com/AlexeyAB/darknet/#pre-trained-models
#yolov4_tiny model has been generated and exported in tflite using tensorflow python API
#pre-trained yolov4_tiny model has been trained on MS COCO dataset
SRC_URI = " file://yolov4_tiny_416_quant.tflite \
file://labels_yolov4_tiny.txt "
S = "${WORKDIR}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo-ai/object-detection/models/yolov4-tiny
install -d ${D}${prefix}/local/demo-ai/object-detection/models/yolov4-tiny/testdata
# install coco ssd mobilenet model
install -m 0644 ${S}/label*.txt ${D}${prefix}/local/demo-ai/object-detection/models/yolov4-tiny/labels_yolov4_tiny.txt
install -m 0644 ${S}/*.tflite ${D}${prefix}/local/demo-ai/object-detection/models/yolov4-tiny/
}
FILES:${PN} += "${prefix}/local/"

View File

@ -0,0 +1,67 @@
# Copyright (C) 2020, STMicroelectronics - All Rights Reserved
SUMMARY = "onnx C++ API Computer Vision object detection application example"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit pkgconfig
DEPENDS += "onnxruntime gtk+3 opencv gstreamer1.0 rapidjson gstreamer1.0-plugins-base gstreamer1.0-plugins-bad"
SRC_URI = " file://onnx;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/onnx/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/onnx
# install applications into the demo launcher
install -m 0755 ${S}/onnx/221-onnx-object-detection-C++.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/onnx/onnx_object_detection ${D}${prefix}/local/demo-ai/object-detection/onnx
install -m 0755 ${S}/onnx/launch_bin*.sh ${D}${prefix}/local/demo-ai/object-detection/onnx
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gstreamer1.0-plugins-base-videoconvertscale \
gtk+3 \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
onnxruntime \
onnx-models-coco-ssd-mobilenetv1 \
application-resources\
rapidjson \
bash \
"
#Depending of the Gstreamer version supported by the Yocto version the RDEPENDS differs
RDEPENDS:${PN} += "${@bb.utils.contains('DISTRO_CODENAME', 'kirkstone', ' gstreamer1.0-plugins-base-videoscale gstreamer1.0-plugins-base-videoconvert ', ' gstreamer1.0-plugins-base-videoconvertscale ', d)}"

View File

@ -0,0 +1,37 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "onnx Python Computer Vision object detection application example"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://onnx;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/onnx
# install applications into the demo launcher
install -m 0755 ${S}/onnx/220-onnx-object-detection-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/onnx/onnx_object_detection.py ${D}${prefix}/local/demo-ai/object-detection/onnx
install -m 0755 ${S}/onnx/launch_python*.sh ${D}${prefix}/local/demo-ai/object-detection/onnx
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-onnxruntime \
onnx-models-coco-ssd-mobilenetv1 \
application-resources \
bash \
"

View File

@ -0,0 +1,71 @@
# Copyright (C) 2020, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite C++ API Computer Vision object detection application example"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit pkgconfig
DEPENDS += "tensorflow-lite gtk+3 opencv gstreamer1.0 rapidjson gstreamer1.0-plugins-base gstreamer1.0-plugins-bad"
DEPENDS:append:stm32mp25common = " tflite-vx-delegate "
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
BOARD_USED:stm32mp1common = "stm32mp1"
BOARD_USED:stm32mp25common = "stm32mp2_npu"
EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"'
EXTRA_OEMAKE += 'ARCHITECTURE="${BOARD_USED}"'
do_compile() {
#Check the version of OpenCV and fill OPENCV_VERSION accordingly
FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc
if [ -f "$FILE" ]; then
OPENCV_VERSION=opencv4
else
OPENCV_VERSION=opencv
fi
oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/tflite/
}
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/tflite
# install applications into the demo launcher
install -m 0755 ${S}/tflite/201-tflite-object-detection-C++.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_object_detection ${D}${prefix}/local/demo-ai/object-detection/tflite
install -m 0755 ${S}/tflite/launch_bin*.sh ${D}${prefix}/local/demo-ai/object-detection/tflite
}
FILES:${PN} += "${prefix}/local/"
INSANE_SKIP:${PN} = "ldflags"
RDEPENDS:${PN} += " \
gstreamer1.0-plugins-bad-waylandsink \
gstreamer1.0-plugins-bad-debugutilsbad \
gstreamer1.0-plugins-base-app \
gstreamer1.0-plugins-base-videorate \
gstreamer1.0-plugins-good-video4linux2 \
gstreamer1.0-plugins-base-videoconvertscale \
gtk+3 \
libopencv-core \
libopencv-imgproc \
libopencv-imgcodecs \
tensorflow-lite \
tflite-models-coco-ssd-mobilenetv1 \
application-resources \
rapidjson \
bash \
"
#Depending of the Gstreamer version supported by the Yocto version the RDEPENDS differs
RDEPENDS:${PN} += "${@bb.utils.contains('DISTRO_CODENAME', 'kirkstone', ' gstreamer1.0-plugins-base-videoscale gstreamer1.0-plugins-base-videoconvert ', ' gstreamer1.0-plugins-base-videoconvertscale ', d)}"

View File

@ -0,0 +1,46 @@
# Copyright (C) 2022, STMicroelectronics - All Rights Reserved
SUMMARY = "TensorFlowLite Python Computer Vision object detection application example"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " file://tflite;subdir=${BPN}-${PV} "
S = "${WORKDIR}/${BPN}-${PV}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo-ai/object-detection/tflite
# install applications into the demo launcher
install -m 0755 ${S}/tflite/200-tflite-object-detection-python.yaml ${D}${prefix}/local/demo/application
# install application binaries and launcher scripts
install -m 0755 ${S}/tflite/tflite_object_detection.py ${D}${prefix}/local/demo-ai/object-detection/tflite
install -m 0755 ${S}/tflite/launch_python_object_detection.sh ${D}${prefix}/local/demo-ai/object-detection/tflite
install -m 0755 ${S}/tflite/launch_python_object_detection_testdata.sh ${D}${prefix}/local/demo-ai/object-detection/tflite
}
do_install:append:stm32mp25common(){
install -m 0755 ${S}/tflite/200-tflite-object-detection-python-mp2.yaml ${D}${prefix}/local/demo/application/200-tflite-object-detection-python.yaml
install -m 0755 ${S}/tflite/launch_python_object_detection_mp2.sh ${D}${prefix}/local/demo-ai/object-detection/tflite/launch_python_object_detection.sh
install -m 0755 ${S}/tflite/launch_python_object_detection_testdata_mp2.sh ${D}${prefix}/local/demo-ai/object-detection/tflite/launch_python_object_detection_testdata.sh
}
FILES:${PN} += "${prefix}/local/"
RDEPENDS:${PN} += " \
python3-core \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pygobject \
python3-tensorflow-lite \
application-resources \
bash \
"
RDEPENDS:${PN}:append:stm32mp25common = " tflite-models-yolov4-tiny "
RDEPENDS:${PN}:append:stm32mp1common = " tflite-models-coco-ssd-mobilenetv1 "

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tflite.iml" filepath="$PROJECT_DIR$/.idea/tflite.iml" />
</modules>
</component>
</project>

Some files were not shown because too many files have changed in this diff Show More