Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(WORK IN PROGRESS): Add ArmNN and rknn2 detectors. Add docs about orange pi 5 #5733

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"

ENV PATH="/usr/lib/btbn-ffmpeg/bin:/usr/local/go2rtc/bin:/usr/local/nginx/sbin:${PATH}"

# Install mpp empowerred ffmpeg for arm64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this going to run for all arm64 builds?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason this ffmpeg build wouldn't work for all arm64 use cases? Could/Should we move it to be called from the install_deps.sh to be used instead of the raspbian repo?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rpi hwaccel has been very finicky #3780 so would definitely need testing on that

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in Docker, we have only one arm64, what "all" builds are you referring to?
Am I missing anything?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in Docker, we have only one arm64, what "all" builds are you referring to?

You are right

my question is basically that I don't see any path where HAS_FFMPEG isn't set to 1 and the mpp ffmpeg will always be used basically

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this mpp - it's just one of other hwaccell we can have all compiled in
then end-user will chose in config which one to use for his specific board/environment

RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \
--mount=type=bind,source=docker/mpp.sh,target=/deps/mpp.sh \
/deps/mpp.sh

# Install dependencies
RUN --mount=type=bind,source=docker/install_deps.sh,target=/deps/install_deps.sh \
/deps/install_deps.sh
Expand Down
15 changes: 11 additions & 4 deletions docker/build_nginx.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ RTMP_MODULE_VERSION="1.2.1"

cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list
sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list
apt-get update
apt-get -qq update

apt-get -yqq build-dep nginx

apt-get -yqq install --no-install-recommends ca-certificates wget
# TODO: move all apt-get installs to dedicated script for having it in a single Docker layer = performance of reruns.
apt-get -yqq install --no-install-recommends ca-certificates wget libaio-dev
update-ca-certificates -f
mkdir /tmp/nginx
wget -nv https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
Expand Down Expand Up @@ -52,15 +53,21 @@ rm v${RTMP_MODULE_VERSION}.tar.gz

cd /tmp/nginx

ARCH=$(uname -m)
CC_OPT="-O3 -Wno-error=implicit-fallthrough"

if [ "$ARCH" = "aarch64" ]; then
CC_OPT="${CC_OPT} -march=armv8-a+crc -mfpu=neon-fp-armv8 -mfloat-abi=hard"
fi

./configure --prefix=/usr/local/nginx \
--with-file-aio \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing with this branch I had to add this option back for frigate to work.

--with-http_sub_module \
--with-http_ssl_module \
--with-threads \
--add-module=../nginx-vod-module \
--add-module=../nginx-secure-token-module \
--add-module=../nginx-rtmp-module \
--with-cc-opt="-O3 -Wno-error=implicit-fallthrough"
--with-cc-opt="${CC_OPT}"

make -j$(nproc) && make install
rm -rf /usr/local/nginx/html /usr/local/nginx/conf/*.default
10 changes: 10 additions & 0 deletions docker/install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -euxo pipefail

apt-get -qq update

# TODO: move all apt-get installs to dedicated script for having it in a single Docker layer = performance of reruns.
apt-get -qq install --no-install-recommends -y \
apt-transport-https \
gnupg \
Expand Down Expand Up @@ -47,13 +48,22 @@ if [[ "${TARGETARCH}" == "arm" ]]; then
fi

# ffmpeg -> arm64
if command -v ffmpeg >/dev/null 2>&1; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in which cases would HAS_FFMPEG be 0 for this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with all if\else logic for all platforms, so ensuring here my part will work as it should be without breaking other's people work

HAS_FFMPEG=1
else
HAS_FFMPEG=0
fi

if [[ "${HAS_FFMPEG}" == 0 ]]; then
if [[ "${TARGETARCH}" == "arm64" ]]; then
# add raspberry pi repo
gpg --no-default-keyring --keyring /usr/share/keyrings/raspbian.gpg --keyserver keyserver.ubuntu.com --recv-keys 82B129927FA3303E
echo "deb [signed-by=/usr/share/keyrings/raspbian.gpg] https://archive.raspberrypi.org/debian/ bullseye main" | tee /etc/apt/sources.list.d/raspi.list
apt-get -qq update
apt-get -qq install --no-install-recommends --no-install-suggests -y ffmpeg
fi
Comment on lines 58 to 64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this may need to be indented since it is nested if ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, agree, needs consistency
But keeping this as is while Work in Progress

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll go ahead and mark the PR as draft as well 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, thanks for the assistance.

I'm finalizing mpp + ffmpeg work, hopefully to get it sorted today
next week to work on adding armnn libs and binaries and then to finish what @gilankpam created in his fork
After all of that - to add predefined preset for ffmpeg and test everything on real hardware

BTW, do we have any solution for how to run arm64 Docker on OSX ( x86_64 )? @NickM-27

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, do we have any solution for how to run arm64 Docker on OSX ( x86_64 )? @NickM-27

I am not sure unfortunately. I dev on an M1 Pro based macbook so not sure. You'd probably need to run parallels or something similar

fi


# arch specific packages
if [[ "${TARGETARCH}" == "amd64" ]]; then
Expand Down
115 changes: 115 additions & 0 deletions docker/mpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/bin/bash

set -euxo pipefail

apt-get -qq update
apt install -y pkg-config

if [ -e /usr/local/include/mpp/mpp.h ] || [ -e /usr/include/mpp/mpp.h ] || pkg-config --exists rockchip-mpp; then
HAS_MPP=1
else
# Install mpp from sources
apt-get -qq update
# TODO: move all apt-get installs to dedicated script for having it in a single Docker layer = performance of reruns.
apt-get install -y git build-essential yasm pkg-config \
libtool coreutils autoconf automake build-essential cmake \
doxygen git graphviz imagemagick libasound2-dev libass-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \
libavutil-dev libfreetype6-dev libgmp-dev libmp3lame-dev \
libopencore-amrnb-dev libopencore-amrwb-dev libopus-dev \
librtmp-dev libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev \
libsdl2-net-dev libsdl2-ttf-dev libsnappy-dev libsoxr-dev \
libssh-dev libssl-dev libtool libv4l-dev libva-dev libvdpau-dev \
libvo-amrwbenc-dev libvorbis-dev libwebp-dev libx264-dev libx265-dev \
libxcb-shape0-dev libxcb-shm0-dev libxcb-xfixes0-dev libxcb1-dev \
libxml2-dev lzma-dev meson nasm pkg-config python3-dev \
python3-pip texinfo wget yasm zlib1g-dev libdrm-dev libaom-dev libdav1d-dev \
libmp3lame-dev

cd /tmp
git clone https://github.com/rockchip-linux/mpp.git
cd mpp
mkdir build || true && cd build

ARCH=$(uname -m)
EXTRA_CFLAGS=""
EXTRA_CXXFLAGS=""

if [ "$ARCH" = "aarch64" ]; then
EXTRA_CFLAGS="-march=armv8-a+crc -mfpu=neon-fp-armv8 -mfloat-abi=hard"
EXTRA_CXXFLAGS="-march=armv8-a+crc -mfpu=neon-fp-armv8 -mfloat-abi=hard"
podarok marked this conversation as resolved.
Show resolved Hide resolved
fi

cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_C_FLAGS="${EXTRA_CFLAGS}" -DCMAKE_CXX_FLAGS="${EXTRA_CXXFLAGS}" ../
make -j$(nproc)
make install
ldconfig

fi

# TODO: consider moving ffmpeg compillation to a dedicated ffmpeg.sh script
if command -v ffmpeg >/dev/null 2>&1; then
HAS_FFMPEG=1
else
HAS_FFMPEG=0
fi

if [[ "${HAS_FFMPEG}" == 1 ]]; then
# To avoid possible race condition.
apt -y remove ffmpeg
fi
# Compile ffmpeg

cd /tmp
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg

ARCH=$(uname -m)
EXTRA_CFLAGS="-I/usr/local/include"
EXTRA_LDFLAGS="-L/usr/local/lib"

if [ "$ARCH" = "aarch64" ]; then
EXTRA_CFLAGS="${EXTRA_CFLAGS} -march=armv8-a+crc -mfpu=neon-fp-armv8 -mfloat-abi=hard"
fi

PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure \
--enable-rkmpp \
--extra-cflags="${EXTRA_CFLAGS}" \
--extra-ldflags="${EXTRA_LDFLAGS}" \
--extra-libs="-lpthread -lm -latomic" \
--arch=arm64 \
--enable-gmp \
--enable-gpl \
--enable-libaom \
--enable-libass \
--enable-libdav1d \
--enable-libdrm \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopencore-amrnb \
--enable-libopencore-amrwb \
--enable-libopus \
--enable-librtmp \
--enable-libsnappy \
--enable-libsoxr \
--enable-libssh \
--enable-libvorbis \
--enable-libzimg \
podarok marked this conversation as resolved.
Show resolved Hide resolved
--enable-libwebp \
--enable-libx264 \
--enable-libx265 \
--enable-libxml2 \
--enable-nonfree \
--enable-version3 \
--target-os=linux \
--enable-pthreads \
--enable-openssl \
--enable-hardcoded-tables

make -j$(nproc)
make install
ldconfig

cd /tmp
rm -rf mpp
rm -rf FFmpeg
23 changes: 23 additions & 0 deletions docs/docs/configuration/detectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,29 @@ model:
labelmap_path: /path/to/coco_80cl.txt
```

### ArmNN detector ( orange pi 5 )

You need to put ArmNN binaries for them to be located in a way, when `/usr/lib/ArmNN-linux-aarch64/libarmnnDelegate.so` is correct.
Download binaries from https://github.com/ARM-software/armnn/releases for your platform


```yaml
detectors:
armnn:
type: armnn
num_threads: 8
# model:
# path: //cpu_model.tflite # used by default.

model:
width: 320
height: 320

```

In order for GPU to work you need to have `armnn-latest-all` installed as well as `clinfo` should show
output for the GPU support. See [hardware acceleration](hardware_acceleration.md).

### Intel NCS2 VPU and Myriad X Setup

Intel produces a neural net inference accelleration chip called Myriad X. This chip was sold in their Neural Compute Stick 2 (NCS2) which has been discontinued. If intending to use the MYRIAD device for accelleration, additional setup is required to pass through the USB device. The host needs a udev rule installed to handle the NCS2 device.
Expand Down
72 changes: 72 additions & 0 deletions docs/docs/configuration/hardware_acceleration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,78 @@ ffmpeg:
hwaccel_args: preset-rpi-64-h264
```

### Orange Pi 5 ( ArmNN )

Ensure you have installed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this an install script similar to the way TensorRT detector has?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid we need to stop overwhelming Dockerfile with if/if/else spaghetti and have Dockerfile / board / arch

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just moved away from an approach like that to support multiarch builds with multiple detectors. I also don't see what that script would have to do with the Dockerfile

Copy link
Author

@podarok podarok Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no sense to have armnn related detector for x86_64 board. No need to install packages from rkmpp scope for raspberry PI board, no need to have rknpu libraries for raspberry pi
We should stop using raspberry pi PPAs for non raspberry PI boards

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an architect I see us start decoupling frigate from Docker
frigate should become an app, which is used by specific Docker as part of the whole system, depending from the hardware available

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no sense to have armnn related detector for x86_64 board. No need to install packages from rkmpp scope for raspberry PI board, no need to have rknpu libraries for raspberry pi We should stop using raspberry pi PPAs for non raspberry PI boards

of course, frigate already has examples of this case like how there is only a tensorrt image for amd64. However, you may very well want to run the ArmNN detector alongside OpenVINO via NCS2, Coral, etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, makes sense @NickM-27
I'll check if I can add proper PPAs and script for installing proper ffmpeg for hardware acceleration on this board


```sh
ffmpeg/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,upgradable to: 7:5.1.2-3]
libavcodec58/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libavdevice58/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libavfilter7/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libavformat58/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libavutil56/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libpostproc55/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
librockchip-mpp1/jammy,now 1.5.0-1+git230210.c145c84~jammy1 arm64 [installed,automatic]
libswresample3/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
libswscale5/jammy,now 7:4.4.2-0ubuntu0.22.04.1+rkmpp20230207 arm64 [installed,automatic]
```
from https://github.com/orangepi-xunlong/rk-rootfs-build/tree/rk3588_packages_jammy

```yaml
ffmpeg:
hwaccel_args: -hwaccel drm -hwaccel_device /dev/dri/renderD128 -c:v h264_rkmpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this an ffmpeg preset?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet, because we need to get specifically compiled ffmpeg for this board

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How big is the ffmpeg binary? We may be able to include both in the image.

But if this pattern starts to be a thing, we need to reconsider. One approach is to download the ffmpeg binary automatically to /data/ on container startup, or skip it if the SHA validation of the existing binary passes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be difficult for docker users since /data/ isn't mapped and we don't want to be pulling on each startup. I'm wondering how including both would work, how would frigate / go2rtc know which to use?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On container startup we can relocate the binaries according to the Frigate config, for example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About /data, you are right. Maybe after #5219 the binary could be downloaded to /config.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But wait a sec, even /data would be fine, I think. When containers are restarted in docker, they are not recreated, so the data is kept (different than add-ons where restart=recreate, but in that case /data is kept anyway).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean, that could definitely make sense. Perhaps ffmpeg acceleration support for these devices would make sense as a separate PR and leave this PR just for the detector addition

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But wait a sec, even /data would be fine, I think. When containers are restarted in docker, they are not recreated, so the data is kept (different than add-ons where restart=recreate, but in that case /data is kept anyway).

It is bad practice to write to storage which is not mapped to user storage and only contained in the container, so that is not an option

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a script as you requested podarok#8 @NickM-27

```

Also, for the CPU and GPU accelleration you should use `armnn` detector on this board [see](detectors.md)

Install packages [see tutorials](https://github.com/ARM-software/armnn/blob/branches/armnn_23_02/InstallationViaAptRepository.md)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, can this be an install script?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully yes in this case


```sh
armnn-latest-all/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
armnn-latest-cpu-gpu-ref/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
armnn-latest-cpu-gpu/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
armnn-latest-cpu/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
armnn-latest-gpu/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
armnn-latest-ref/jammy,now 23.02-1~ubuntu22.04 arm64 [installed]
libarmnn-cpuacc-backend32/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
libarmnn-cpuref-backend32/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
libarmnn-gpuacc-backend32/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
libarmnn22/unstable,now 20.08-12 arm64 [installed,automatic]
libarmnn32/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
libarmnnaclcommon22/unstable,now 20.08-12 arm64 [installed]
libarmnnaclcommon32/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
libarmnntfliteparser24/jammy,now 23.02-1~ubuntu22.04 arm64 [installed,automatic]
```

In order for the GPU to work install packages

```sh
libmali-g610-x11/jammy,now 1.0.2.4 arm64 [installed]
libmali-valhall-g610-g6p0-x11-gbm/now 1.9-1 arm64 [installed,local]
```

for Ubuntu

```sh
apt install ocl-icd-opencl-dev
mkdir -p /etc/OpenCL/vendors/
dpkg -i libmali-valhall-g610-g6p0-x11_1.9-1_arm64.deb
```

`clinfo | grep 'Device Name'` should show you a full output of available data about Mali GPU

```sh
root@23cfa5ff7203:/opt/frigate# clinfo | grep 'Device Name'
Device Name Mali-LODX r0p0
Device Name Mali-LODX r0p0
Device Name Mali-LODX r0p0
Device Name Mali-LODX r0p0
```




### Intel-based CPUs (<10th Generation) via VAAPI

VAAPI supports automatic profile selection so it will work automatically with both H.264 and H.265 streams. VAAPI is recommended for all generations of Intel-based CPUs if QSV does not work.
Expand Down
78 changes: 78 additions & 0 deletions frigate/detectors/plugins/armnn_tfl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import logging
import numpy as np

from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
from typing import Literal
from pydantic import Extra, Field

try:
from tflite_runtime.interpreter import Interpreter
except ModuleNotFoundError:
from tensorflow.lite.python.interpreter import Interpreter

logger = logging.getLogger(__name__)

DETECTOR_KEY = "armnn"


class ArmNNDetectorConfig(BaseDetectorConfig):
type: Literal[DETECTOR_KEY]
num_threads: int = Field(default=8, title="Number of detection threads")


def load_armnn_delegate(library_path, options=None):
try:
from tflite_runtime.interpreter import load_delegate
except ModuleNotFoundError:
from tensorflow.lite.python.interpreter import load_delegate

if options is None:
options = {"backends": "CpuAcc,GpuAcc,CpuRef", "logging-severity": "info"}

return load_delegate(library_path, options=options)


class ArmNNTfl(DetectionApi):
type_key = DETECTOR_KEY

def __init__(self, detector_config: ArmNNDetectorConfig):
armnn_delegate = load_armnn_delegate("/usr/lib/ArmNN-linux-aarch64/libarmnnDelegate.so")

self.interpreter = Interpreter(
model_path=detector_config.model.path or "/cpu_model.tflite",
num_threads=detector_config.num_threads or 8,
experimental_delegates=[armnn_delegate],
)

self.interpreter.allocate_tensors()

self.tensor_input_details = self.interpreter.get_input_details()
self.tensor_output_details = self.interpreter.get_output_details()

def detect_raw(self, tensor_input):
self.interpreter.set_tensor(self.tensor_input_details[0]["index"], tensor_input)
self.interpreter.invoke()

boxes = self.interpreter.tensor(self.tensor_output_details[0]["index"])()[0]
class_ids = self.interpreter.tensor(self.tensor_output_details[1]["index"])()[0]
scores = self.interpreter.tensor(self.tensor_output_details[2]["index"])()[0]
count = int(
self.interpreter.tensor(self.tensor_output_details[3]["index"])()[0]
)

detections = np.zeros((20, 6), np.float32)

for i in range(count):
if scores[i] < 0.4 or i == 20:
break
detections[i] = [
class_ids[i],
float(scores[i]),
boxes[i][0],
boxes[i][1],
boxes[i][2],
boxes[i][3],
]

return detections