Programming¶
Outdated Script Versions
The versions of the Python scripts shown in this subsection are currently
not up-to-date with the versions in the
insect-detect
GitHub repo. Will be updated as soon as possible.
Adapt the software to your use case
You will find all Python scripts to deploy the Insect Detect DIY camera trap for automated insect monitoring in this section, together with suggestions on possible modifications. Click on the symbol to open the code annotations for more information. More details about the API that is used can be found at the Luxonis Docs.
If you run into any problems, find a bug or something that could be optimized, please create a GitHub issue.
RuntimeError: X_LINK_DEVICE_ALREADY_IN_USE
If you try to run one of the following Python scripts and the error above occurs, the most common cause is that a previously started script is already running and communicating with the OAK camera (e.g. cron job at boot). You can see all currently running processes by using Raspberry Pi's task manager htop. Start the task manager by running:
If you see one of the Python scripts in the list of processes, you can hit
F9 with the script selected. This will open the SIGTERM
option and by
confirming with Enter the process will be stopped. Close htop by pressing
Q and you should now be able to successfully run the script.
OAK camera preview¶
The following Python script will create and configure the ColorCamera node to send downscaled LQ frames (e.g. 320x320 px) to the host (Raspberry Pi) and show them in a new window. If you are connected to the RPi via SSH, X11 forwarding has to be set up, together with an started and active X server to show the frames in a window on your local PC.
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Optional arguments
Add after env_insdet/bin/python3 insect-detect/cam_preview.py
, separated by space:
-af CM_MIN CM_MAX
set auto focus range in cm (min distance, max distance)-big
show a bigger preview window with 640x640 px size
Stop the script by pressing Ctrl+C in the Terminal or by hitting Q with the preview window selected.
- More info about the Pipeline and creation of nodes.
- More info about the ColorCamera node and possible configurations.
- If your image is shown upside down, you can rotate it
on-device by activating this configuration (remove the
#
). THE_1080_P
= 1920x1080 pixel (aspect ratio: 16:9). You can check all supported sensors and their respective resolutions at the DepthAI Docs. IMX378 is used in the OAK-1.- More info about other possible downscaling options.
- The XLinkOut node sends data from the OAK device to the host (e.g. Raspberry Pi) via XLink.
- If your host (e.g. RPi Zero 2 W) has no USB 3 port or you aren't using a
USB 3 cable, it is recommended to
force USB2 communication
by setting
maxUsbSpeed=dai.UsbSpeed.HIGH
. Remove themaxUsbSpeed
limit for full USB 3 support. - You can specify different queue configurations, by changing the maximum queue size or the blocking behaviour.
- More info about the
cv2.putText()
function to customize your output.
YOLO preview¶
With the following Python script you can run a custom YOLO object detection model (.blob format) on the OAK device with downscaled LQ frames (e.g. 320x320 px) as model input and show the frames together with the model output (bounding box, label, confidence score) in a new window.
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Optional arguments
Add after env_insdet/bin/python3 insect-detect/yolo_preview.py
, separated by space:
-af CM_MIN CM_MAX
set auto focus range in cm (min distance, max distance)-ae
use bounding box coordinates from detections to set auto exposure region-log
print available Raspberry Pi memory, RPi CPU utilization + temperature, OAK memory + CPU usage and OAK chip temperature
Stop the script by pressing Ctrl+C in the Terminal or by hitting Q with the preview window selected.
yolo_preview.py | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
|
- Specify the path to your detection model (.blob format) and config JSON that the OAK can use it for on-device inference.
- For testing purposes, adjust the camera fps to the maximum fps of the YOLO model that is used for inference (more info).
- More info about the YoloDetectionNetwork node.
- The downscaled LQ preview frames are used as model input. More info about linking nodes.
- To avoid freezing of the pipeline, we will set
blocking=False
for the frames that are used as model input. - All metadata that is necessary to successfully run the model on-device is read from the corresponding config .json file. However, you could also change your IoU or confidence threshold here for experimenting with different settings.
- To match the output frequency of the OAK logs
(
device.setLogOutputLevel()
), the interval for printing the RPi logs is set to one second. Increase this interval for easier reading of the logs. - The
-ae
setting is still experimental and can lead to unexpected behaviour in some cases. By default, the bounding box coordinates from the earliest detection are used to set the auto exposure region.
YOLO + object tracker preview¶
In the following Python script an ObjectTracker, node based on the Intel DL Streamer framework, is added to the pipeline. The object tracker uses the detection model output as input for tracking detected objects and assigning unique tracking IDs on-device. The frames, together with the model and tracker output (bounding box from tracker output and bbox from detection model, label, confidence score, tracking ID, tracking status), are shown in a new window.
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Optional arguments
Add after env_insdet/bin/python3 insect-detect/yolo_tracker_preview.py
, separated by space:
-af CM_MIN CM_MAX
set auto focus range in cm (min distance, max distance)-ae
use bounding box coordinates from detections to set auto exposure region-log
print available Raspberry Pi memory, RPi CPU utilization + temperature, OAK memory + CPU usage and OAK chip temperature
Stop the script by pressing Ctrl+C in the Terminal or by hitting Q with the preview window selected.
yolo_tracker_preview.py | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
|
- Maximum fps of the detection model is slightly lower (~2 fps) when adding the object tracker.
- More info about the ObjectTracker node.
- More info about the supported tracking types.
- The
-ae
setting is still experimental and can lead to unexpected behaviour in some cases. By default, the bounding box coordinates from the latest tracking ID are used to set the auto exposure region. - You can use the bounding box coordinates from the tracker output, as defined in this segment, and/or the bbox coordinates from the passthrough detections to draw the bboxes on the frame. The bboxes from the passthrough detections are usually more stable than from the object tracker output, you can decide for yourself which one is best for your use case.
Automated monitoring script¶
Outdated Script Versions
The versions of the Python scripts shown in this subsection are currently
not up-to-date with the versions in the
insect-detect
GitHub repo. Will be updated as soon as possible.
The following Python script is the main script for fully automated insect monitoring.
All relevant configuration parameters can be modified in the
configs/config_custom.yaml
file.
Processing pipeline for the
yolo_tracker_save_hqsync.py
script that can be used for automated insect monitoring:
- A custom YOLO insect detection model is run in real time on device (OAK) and uses a continuous stream of downscaled LQ frames as input (default: 320x320 px at 20 fps).
- An object tracker uses the bounding box coordinates of detected insects to assign a unique tracking ID to each individual present in the frame and track its movement through time.
- The tracker + model output from inference on LQ frames is synchronized with MJPEG-encoded HQ frames (default: 3840x2160 px) on device (OAK) using the respective timestamps.
- The encoded HQ frames are saved to the microSD card at the configured intervals if an insect is detected (default: 1 s) and independent of detections (default: 10 min).
- Corresponding metadata from the detection model and tracker output (including timestamp, label, confidence score, tracking ID, tracking status and bounding box coordinates) is saved to a metadata .csv file for each detected and tracked insect at the configured interval.
- The metadata can be used to crop detected insects from the HQ frames and save them as individual .jpg images. Depending on the post-processing configuration, the original HQ frames will be optionally deleted after the processing to save storage space.
- During the recording, a maximum pipeline speed of ~19 FPS for 4K resolution (3840x2160) and ~42 FPS for 1080p resolution (1920x1080) can be reached if the capture interval is set to 0 and the camera frame rate is adjusted accordingly.
- With the default configuration, the recording pipeline consumes ~3.8 W of power.
- If a power management board (Witty Pi 4 L3V7 or PiJuice Zero) is connected and enabled in the configuration, intelligent power management is activated which includes battery charge level monitoring and conditional recording durations.
For fully automated monitoring in the field, set up a cron job that will run the script automatically after each boot.
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Stop the script by pressing Ctrl+C in the Terminal.
yolo_tracker_save_hqsync_pijuice.py | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
|
- In this line you can change the time interval with which the cropped detections will be saved to .jpg. This does not affect the detection model and object tracker speed, which are both run on-device even if no detections are saved.
- If you are using the optional argument
-full freq
, e.g. to collect training data, you can specify the frequency to save full frames in this line. Full frames will be saved at the specified frequency, even if no detections are made. With the default configuration, the overall pipeline speed will not decrease even if saving the full frames at a high frequency (> ~5). -
With the logger set up, you can write any information you need (e.g. for finding problems if something went wrong) to the log file. This is a good alternative to
print()
, if you don't have a terminal output. You can add your own custom logging command in any line with: -
If the PiJuice battery charge level or the free space left on the microSD card is below the specified threshold, no recording will be made and the Raspberry Pi is immediately shut down. You can specify your custom thresholds (e.g. when using a different battery capacity) above.
- You can specify your own recording durations and charge level thresholds in this code section. The suggested values can provide an efficient recording behaviour if you are using the 12,000 mAh PiJuice battery and set up the Wakeup Alarm for 3-6 times per day. Depending on the number of Wakeups per day, as well as the season and sun exposure of the solar panel, it can make sense to increase or decrease the recording duration.
- Activate this option only if you have two batteries installed! Disable charging of the PiJuice battery if the charge level is higher than the specified threshold to extend battery life. The charge level is checked again at the end of the script to re-enable charging if the charge level dropped below a specified threshold.
- The recording will be stopped after the recording time is finished or if the charge level of the PiJuice battery drops below the specified threshold for ten times. This avoids immediate stopping of the recording if the battery charge level is falsely returned < 10, which can happen sometimes.
- A tracked object can have 4 possible statuses:
NEW
,TRACKED
,LOST
andREMOVED
. It is highly recommended to save the cropped detections only whentracking status == TRACKED
, but you could change this configuration here and e.g. write thetrack.status.name
as additional column to the metadata .csv. - This function will be called after a recording interval is finished, or if
an error occurs during the recording and will write some info about the
respective recording interval to
record_log.csv
. - If you are still in the testing phase, comment out the shutdown command in
this line by adding
#
in front of the line. Otherwise your Raspberry Pi will automatically shut down everytime you run (and stop) the script.
Frame capture¶
If you want to only capture images, e.g. for training data collection, you can use the following script to save HQ frames (e.g. 1920x1080 px) to .jpg at a specified time interval. Optionally, the downscaled LQ frames (e.g. 320x320 px) can be saved to .jpg additionally, e.g. to include them in the training data, as the detection model will use LQ frames for inference. However, it is recommended to use the original HQ images for annotation and downscale them only before/during training.
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Optional arguments
Add after env_insdet/bin/python3 insect-detect/frame_capture.py
, separated by space:
-min
set recording time in minutes (default: 2)-4k
set camera resolution to 4K (3840x2160 px) (default: 1080p)-lq
additionally save downscaled LQ frames (e.g. 320x320 px)-af CM_MIN CM_MAX
set auto focus range in cm (min distance, max distance)-zip
store data in an uncompressed .zip file for each day and delete original directory
Stop the script by pressing Ctrl+C in the Terminal.
frame_capture.py | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
|
- You can increase the capture frequency in this line, e.g. if you want to only save a frame every 10 seconds, every minute etc. Keep in mind that the image processing will take some time and test different values until the frames are saved with your desired time interval.
Video capture¶
With the following Python script you can save encoded HQ frames (1080p or 4K resolution) with H.265 (HEVC) compression to a .mp4 video file. As there is no encoding happening on the host (RPi), CPU and RAM usage is minimal, which makes it possible to record 4K 30 fps video with almost no load on the Raspberry Pi. As 4K 30 fps video can take up a lot of disk space, the remaining free disk space is checked while recording and the recording is stopped if the free space left drops below a specified threshold (e.g. 100 MB).
If you don't need the 25 fps you can decrease the frame rate which will
lead to a smaller video file size (e.g. -fps 20
).
Run the script with the Python interpreter from the virtual environment where
you installed the required packages (e.g. env_insdet
):
Optional arguments
Add after env_insdet/bin/python3 insect-detect/video_capture.py
, separated by space:
-min
set recording time in minutes (default: 2)-4k
set camera resolution to 4K (3840x2160 px) (default: 1080p)-fps
set camera frame rate (default: 25 fps)-af CM_MIN CM_MAX
set auto focus range in cm (min distance, max distance)
Stop the script by pressing Ctrl+C in the Terminal.
video_capture.py | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
|
- More info about the VideoEncoder node.