Skip to content

Commit 9277960

Browse files
authored
Add support for object detection on Rubik Pi 3 (#2005)
1 parent e23df8c commit 9277960

File tree

26 files changed

+545
-70
lines changed

26 files changed

+545
-70
lines changed

.styleguide

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ modifiableFileExclude {
1919
\.webp$
2020
\.ico$
2121
\.rknn$
22+
\.tflite$
2223
\.mp4$
2324
\.ttf$
2425
\.woff2$

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ ext {
4040
javalinVersion = "5.6.2"
4141
libcameraDriverVersion = "v2025.0.3"
4242
rknnVersion = "dev-v2025.0.0-1-g33b6263"
43+
rubikVersion = "v2025.1.0"
4344
frcYear = "2025"
4445
mrcalVersion = "v2025.0.0";
4546

docs/.styleguide

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ modifiableFileExclude {
1111
\.webp$
1212
\.ico$
1313
\.rknn$
14+
\.tflite$
1415
\.svg$
1516
\.woff2$
1617
gradlew

docs/source/docs/objectDetection/about-object-detection.md

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## How does it work?
44

5-
PhotonVision supports object detection using neural network accelerator hardware built into Orange Pi 5/5+ coprocessors. Please note that the Orange Pi 5/5+ are the only coprocessors that are currently supported. The Neural Processing Unit, or NPU, is [used by PhotonVision](https://github.com/PhotonVision/rknn_jni/tree/main) to massively accelerate certain math operations like those needed for running ML-based object detection.
5+
PhotonVision supports object detection using neural network accelerator hardware, commonly known as an NPU. The two coprocessors currently supported are the {ref}`Orange Pi 5 <docs/objectDetection/opi:Orange Pi 5 (and variants) Object Detection>` and the {ref}`Rubik Pi 3 <docs/objectDetection/rubik:Rubik Pi 3 Object Detection>`.
66

77
PhotonVision currently ships with a model trained on the [COCO dataset](https://cocodataset.org/) by [Ultralytics](https://github.com/ultralytics/ultralytics) (this model is licensed under [AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html)). This model is meant to be used for testing and other miscellaneous purposes. It is not meant to be used in competition. For the 2025 post-season, PhotonVision also ships with a pretrained ALGAE model. A model to detect coral is available in the PhotonVision discord, but will not be distributed with PhotonVision.
88

@@ -18,7 +18,7 @@ This model output means that while its fairly easy to say that "this rectangle p
1818

1919
## Tuning and Filtering
2020

21-
Compared to other pipelines, object detection exposes very few tuning handles. The Confidence slider changes the minimum confidence that the model needs to have in a given detection to consider it valid, as a number between 0 and 1 (with 0 meaning completely uncertain and 1 meaning maximally certain). The Non-Maximum Suppresion (NMS) Threshold slider is used to filter out overlapping detections. Lower values mean more detections are allowed through, but may result in false positives. It's generally recommended that teams leave this set at the default, unless they find they're unable to get usable results with solely the Confidence slider.
21+
Compared to other pipelines, object detection exposes very few tuning handles. The Confidence slider changes the minimum confidence that the model needs to have in a given detection to consider it valid, as a number between 0 and 1 (with 0 meaning completely uncertain and 1 meaning maximally certain). The Non-Maximum Suppresion (NMS) Threshold slider is used to filter out overlapping detections. Higher values mean more detections are allowed through, but may result in false positives. It's generally recommended that teams leave this set at the default, unless they find they're unable to get usable results with solely the Confidence slider.
2222

2323
```{raw} html
2424
<video width="85%" controls>
@@ -33,22 +33,19 @@ The same area, aspect ratio, and target orientation/sort parameters from {ref}`r
3333

3434
Photonvision will letterbox your camera frame to 640x640. This means that if you select a resolution that is larger than 640 it will be scaled down to fit inside a 640x640 frame with black bars if needed. Smaller frames will be scaled up with black bars if needed.
3535

36-
## Training Custom Models
36+
It is recommended that you select a resolution that results in the smaller dimension being just greater than, or equal to, 640. Anything above this will not see any increased performance.
3737

38-
:::{warning}
39-
Power users only. This requires some setup, such as obtaining your own dataset and installing various tools. It's additionally advised to have a general knowledge of ML before attempting to train your own model. Additionally, this is not officially supported by Photonvision, and any problems that may arise are not attributable to Photonvision.
40-
:::
38+
## Custom Models
4139

42-
Before beginning, it is necessary to install the [rknn-toolkit2](https://github.com/airockchip/rknn-toolkit2). Then, install the relevant [Ultralytics repository](https://github.com/airockchip?tab=repositories&q=yolo&type=&language=&sort=) from this list. After training your model, export it to `rknn`. This will give you an `onnx` file, formatted for conversion. Copy this file to the relevant folder in [rknn_model_zoo](https://github.com/airockchip/rknn_model_zoo), and use the conversion script located there to convert it. If necessary, modify the script to provide the path to your training database for quantization.
40+
For information regarding converting custom models and supported models for each platform, refer to the page detailing information about your specific coprocessor.
4341

44-
## Managing Custom Models
42+
- {ref}`Orange Pi 5 <docs/objectDetection/opi:Orange Pi 5 (and variants) Object Detection>`
43+
- {ref}`Rubik Pi 3 <docs/objectDetection/rubik:Rubik Pi 3 Object Detection>`
4544

46-
:::{warning}
47-
PhotonVision currently ONLY supports 640x640 Ultralytics YOLOv5, YOLOv8, and YOLOv11 models trained and converted to `.rknn` format for RK3588 CPUs! Other models require different post-processing code and will NOT work. The model conversion process is also highly particular. Proceed with care.
48-
:::
45+
### Training Custom Models
4946

50-
:::{warning}
51-
Non-quantized models are not supported! If you have the option, make sure quantization is enabled when exporting to .rknn format. This will represent the weights and activations of the model as 8-bit integers, instead of 32-bit floats which PhotonVision doesn't support. Quantized models are also much faster for a negligible loss in accuracy.
52-
:::
47+
PhotonVision does not offer any support for training custom models, only conversion. For information on which models are supported for a given coprocessor, use the links above.
48+
49+
### Managing Custom Models
5350

54-
Custom models can now be managed from the Object Detection tab in settings. You can upload a custom model by clicking the "Upload Model" button, selecting your `.rknn` file, and filling out the property fields. Models can also be exported, both individually and in bulk. Models exported in bulk can be imported using the `import bulk` button. Models exported individually must be re-imported as an individual model, and all the relevant metadata is stored in the filename of the model.
51+
Custom models can now be managed from the Object Detection tab in settings. You can upload a custom model by clicking the "Upload Model" button, selecting your model file, and filling out the property fields. Models can also be exported, both individually and in bulk. Models exported in bulk can be imported using the `import bulk` button. Models exported individually must be re-imported as an individual model, and all the relevant metadata is stored in the filename of the model.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Object Detection
22

33
```{toctree}
4-
:maxdepth: 0
5-
:titlesonly: true
64
75
about-object-detection
6+
opi
7+
rubik
88
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Orange Pi 5 (and variants) Object Detection
2+
3+
## How it works
4+
5+
PhotonVision runs object detection on the Orange Pi 5 by use of the RKNN model architecture, and [this JNI code](https://github.com/PhotonVision/rknn_jni).
6+
7+
## Supported models
8+
9+
PhotonVision currently ONLY supports 640x640 Ultralytics YOLOv5, YOLOv8, and YOLOv11 models trained and converted to `.rknn` format for RK3588 SOCs! Other models require different post-processing code and will NOT work.
10+
11+
## Converting Custom Models
12+
13+
:::{warning}
14+
Only quantized models are supported, so take care when exporting to select the option for quantization.
15+
:::
16+
17+
PhotonVision now ships with a [Python Notebook](https://github.com/PhotonVision/photonvision/blob/main/scripts/rknn-convert-tool/rknn_conversion.ipynb) that you can use in [Google Colab](https://colab.research.google.com) or in a local environment. In Google Colab, you can simply paste the PhotonVision GitHub URL into the "GitHub" tab and select the `rknn_conversion.ipynb` notebook without needing to manually download anything.
18+
19+
Please ensure that the model you are attempting to convert is among the {ref}`supported models <docs/objectDetection/opi:Supported Models>` and using the PyTorch format.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Rubik Pi 3 Object Detection
2+
3+
## How it works
4+
5+
PhotonVision runs object detection on the Rubik Pi 3 by use of [TensorflowLite](https://github.com/tensorflow/tensorflow), and [this JNI code](https://github.com/PhotonVision/rubik_jni).
6+
7+
## Supported models
8+
9+
PhotonVision currently ONLY supports 640x640 Ultralytics YOLOv8 and YOLOv11 models trained and converted to `.tflite` format for QCS6490 SOCs! Other models require different post-processing code and will NOT work.
10+
11+
## Converting Custom Models
12+
13+
:::{warning}
14+
Only quantized models are supported, so take care when exporting to select the option for quantization.
15+
:::
16+
17+
PhotonVision now ships with a [Python Notebook](https://github.com/PhotonVision/photonvision/blob/main/scripts/rubik_conversion.ipynb) that you can use in [Google Colab](https://colab.research.google.com) or in a local environment. In Google Colab, you can simply paste the PhotonVision GitHub URL into the "GitHub" tab and select the `rubik_conversion.ipynb` notebook without needing to manually download anything.
18+
19+
Please ensure that the model you are attempting to convert is among the {ref}`supported models <docs/objectDetection/rubik:Supported Models>` and using the PyTorch format.
20+
21+
## Benchmarking
22+
23+
Before you can perform benchmarking, it's necessary to install `tensorflow-lite-qcom-apps` with apt.
24+
25+
By SSHing into your Rubik Pi and running this command, replacing `PATH/TO/MODEL` with the path to your model, `benchmark_model --graph=src/test/resources/yolov8nCoco.tflite --external_delegate_path=/usr/lib/libQnnTFLiteDelegate.so --external_delegate_options=backend_type:htp --external_delegate_options=htp_use_conv_hmx:1 --external_delegate_options=htp_performance_mode:2` you can determine how long it takes for inference to be performed with your model.

photon-client/src/components/dashboard/tabs/ObjectDetectionTab.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const selectedModel = computed({
9090
class="pt-2"
9191
:slider-cols="interactiveCols"
9292
label="NMS Threshold"
93-
tooltip="The Non-Maximum Suppression threshold used to filter out overlapping detections. Lower values mean more detections are allowed through, but may result in false positives."
93+
tooltip="The Non-Maximum Suppression threshold used to filter out overlapping detections. Higher values mean more detections are allowed through, but may result in false positives."
9494
:min="0"
9595
:max="1"
9696
:step="0.01"

photon-client/src/components/settings/ObjectDetectionCard.vue

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import pvInput from "@/components/common/pv-input.vue";
88
import { useTheme } from "vuetify";
99
1010
const theme = useTheme();
11-
1211
const showImportDialog = ref(false);
1312
const showInfo = ref({ show: false, model: {} as ObjectDetectionModelProperties });
1413
const confirmDeleteDialog = ref({ show: false, model: {} as ObjectDetectionModelProperties });
@@ -303,11 +302,33 @@ const handleBulkImport = () => {
303302
<v-card color="surface" dark>
304303
<v-card-title class="pb-0">Import New Object Detection Model</v-card-title>
305304
<v-card-text>
306-
Upload a new object detection model to this device that can be used in a pipeline. Note that ONLY
307-
640x640 YOLOv5, YOLOv8, and YOLOv11 models trained and converted to `.rknn` format for RK3588 CPUs are
308-
currently supported!
305+
<span v-if="useSettingsStore().general.supportedBackends?.includes('RKNN')"
306+
>Upload a new object detection model to this device that can be used in a pipeline. Note that ONLY
307+
640x640 YOLOv5, YOLOv8, and YOLOv11 models trained and converted to `.rknn` format for RK3588 SOCs are
308+
currently supporter!</span
309+
>
310+
<span v-else-if="useSettingsStore().general.supportedBackends?.includes('RUBIK')"
311+
>Upload a new object detection model to this device that can be used in a pipeline. Note that ONLY
312+
640x640 YOLOv8 and YOLOv11 models trained and converted to `.tflite` format for QCS6490 compatible
313+
backends are currently supported!
314+
</span>
315+
<span v-else>
316+
If you're seeing this, something broke; please file a ticket and tell us the details of your
317+
situation.</span
318+
>
309319
<div class="pa-5 pb-0">
310-
<v-file-input v-model="importModelFile" variant="underlined" label="Model File" accept=".rknn" />
320+
<v-file-input
321+
v-model="importModelFile"
322+
variant="underlined"
323+
label="Model File"
324+
:accept="
325+
useSettingsStore().general.supportedBackends?.includes('RKNN')
326+
? '.rknn'
327+
: useSettingsStore().general.supportedBackends?.includes('RUBIK')
328+
? '.tflite'
329+
: ''
330+
"
331+
/>
311332
<v-text-field
312333
v-model="importLabels"
313334
label="Labels"
@@ -321,7 +342,11 @@ const handleBulkImport = () => {
321342
v-model="importVersion"
322343
variant="underlined"
323344
label="Model Version"
324-
:items="['YOLOv5', 'YOLOv8', 'YOLO11']"
345+
:items="
346+
useSettingsStore().general.supportedBackends?.includes('RKNN')
347+
? ['YOLOv5', 'YOLOv8', 'YOLO11']
348+
: ['YOLOv8', 'YOLO11']
349+
"
325350
/>
326351
<v-btn
327352
color="buttonActive"

photon-client/src/types/SettingTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface ObjectDetectionModelProperties {
2020
labels: string[];
2121
resolutionWidth: number;
2222
resolutionHeight: number;
23-
family: "RKNN";
23+
family: "RKNN" | "RUBIK";
2424
version: "YOLOV5" | "YOLOV8" | "YOLOV11";
2525
}
2626

0 commit comments

Comments
 (0)