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:
parent
983df1b9cb
commit
1f678d39a3
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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_
|
||||
|
|
@ -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 "
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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)}"
|
||||
|
|
@ -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 "
|
||||
|
|
@ -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 "
|
||||
|
|
@ -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 "
|
||||
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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_
|
||||
|
|
@ -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 "
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Binary file not shown.
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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/"
|
||||
|
|
@ -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)}"
|
||||
|
|
@ -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 \
|
||||
"
|
||||
|
|
@ -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)}"
|
||||
|
|
@ -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 "
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
Loading…
Reference in New Issue