Skip to content

Commit 1f0863c

Browse files
Fixed broken person_detection example
- Bumped esp32_s3_eye dependency version number - Made changes to CMakeLists.txt to fix BSP packages not getting installed - Fixed issues with LVGL which caused the display to fail
1 parent 2312aff commit 1f0863c

File tree

10 files changed

+109
-70
lines changed

10 files changed

+109
-70
lines changed

examples/person_detection/CMakeLists.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@ cmake_minimum_required(VERSION 3.5)
33
set(EXTRA_COMPONENT_DIRS static_images)
44
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
55

6-
function(add_bsp SDKCONFIG BSP TARGET)
6+
# Helper function to set required environment variables as per configuration set by user
7+
function(add_bsp SDKCONFIG BSP)
78
string(REGEX MATCH "CONFIG_${BSP}=y" REGEX_RESULT ${SDKCONFIG})
89
if (REGEX_RESULT)
9-
set(ENV{${BSP}} "${TARGET}")
10+
set(ENV{${BSP}} 1) # If the config option is set then set corresponding environment variable to 1
1011
endif()
1112
endfunction()
1213

13-
# 1. Define all variables used in main/idf_component.yml
14-
set(ENV{TFLITE_USE_BSP_S3_EYE} "false")
15-
set(ENV{TFLITE_USE_BSP_KORVO_2} "false")
16-
set(ENV{TFLITE_USE_BSP_KALUGA} "false")
14+
# 1. Define all variables used in main/idf_component.yml and set them to zero
15+
set(ENV{TFLITE_USE_BSP_S3_EYE} 0)
16+
set(ENV{TFLITE_USE_BSP_KORVO_2} 0)
17+
set(ENV{TFLITE_USE_BSP_KALUGA} 0)
1718

18-
# 2. Set correct var to 'target'
19+
# 2. Set correct var to 1
1920
# This is a workaround idf-component-manager limitation, where only
20-
# target and idf_version can be in the if-clause
21+
# target, idf_version and environment variables can be in the if-clause
2122
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sdkconfig)
2223
file(READ ${CMAKE_CURRENT_LIST_DIR}/sdkconfig SDKCONFIG_RULE)
2324

24-
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_S3_EYE" "esp32s3")
25-
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_KORVO_2" "esp32s3")
26-
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_KALUGA" "esp32s2")
25+
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_S3_EYE") # Check for CONFIG_TFLITE_USE_BSP_S3_EYE option in sdkconfig
26+
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_KORVO_2") # Check for CONFIG_TFLITE_USE_BSP_KORVO_2 option in sdkconfig
27+
add_bsp("${SDKCONFIG_RULE}" "TFLITE_USE_BSP_KALUGA") # Check for CONFIG_TFLITE_USE_BSP_KALUGA option in sdkconfig
2728
endif()
2829

2930
project(person_detection)

examples/person_detection/main/app_camera_esp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ limitations under the License.
1414
==============================================================================*/
1515

1616
#include "app_camera_esp.h"
17+
#include "esp_log.h"
1718
#include "sdkconfig.h"
1819

1920
#if (CONFIG_TFLITE_USE_BSP)

examples/person_detection/main/detection_responder.cc

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,26 @@ static lv_obj_t *camera_canvas = NULL;
3636
static lv_obj_t *person_indicator = NULL;
3737
static lv_obj_t *label = NULL;
3838

39-
static void create_gui(void)
39+
void create_gui(void)
4040
{
41-
bsp_display_start();
42-
bsp_display_backlight_on(); // Set display brightness to 100%
41+
bsp_display_cfg_t cfg = {
42+
.lvgl_port_cfg = {
43+
.task_priority = CONFIG_BSP_DISPLAY_LVGL_TASK_PRIORITY,
44+
.task_stack = 6144,
45+
.task_affinity = 1,
46+
.task_max_sleep_ms = CONFIG_BSP_DISPLAY_LVGL_MAX_SLEEP,
47+
.timer_period_ms = CONFIG_BSP_DISPLAY_LVGL_TICK,
48+
},
49+
.buffer_size = BSP_LCD_DRAW_BUFF_SIZE,
50+
.double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE,
51+
.flags = {
52+
.buff_dma = false,
53+
.buff_spiram = true,
54+
}
55+
};
56+
bsp_display_start_with_config(&cfg);
57+
bsp_display_backlight_on();
58+
4359
bsp_display_lock(0);
4460
camera_canvas = lv_canvas_create(lv_scr_act());
4561
assert(camera_canvas);
@@ -62,20 +78,21 @@ void RespondToDetection(float person_score, float no_person_score) {
6278
int person_score_int = (person_score) * 100 + 0.5;
6379
(void) no_person_score; // unused
6480
#if DISPLAY_SUPPORT
65-
if (!camera_canvas) {
66-
create_gui();
67-
}
81+
if (!camera_canvas) {
82+
create_gui();
83+
}
6884

69-
uint16_t *buf = (uint16_t *) image_provider_get_display_buf();
85+
uint16_t *buf = (uint16_t *) image_provider_get_display_buf();
7086

71-
bsp_display_lock(0);
72-
if (person_score_int < 60) { // treat score less than 60% as no person
73-
lv_led_off(person_indicator);
74-
} else {
75-
lv_led_on(person_indicator);
76-
}
77-
lv_canvas_set_buffer(camera_canvas, buf, IMG_WD, IMG_HT, LV_IMG_CF_TRUE_COLOR);
78-
bsp_display_unlock();
87+
bsp_display_lock(0);
88+
if (person_score_int < 60) { // treat score less than 60% as no person
89+
lv_led_off(person_indicator);
90+
} else {
91+
lv_led_on(person_indicator);
92+
}
93+
94+
lv_canvas_set_buffer(camera_canvas, buf, IMG_WD, IMG_HT, LV_COLOR_FORMAT_RGB565);
95+
bsp_display_unlock();
7996
#endif // DISPLAY_SUPPORT
8097
MicroPrintf("person score:%d%%, no person score %d%%",
8198
person_score_int, 100 - person_score_int);

examples/person_detection/main/detection_responder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,7 @@ limitations under the License.
2929
// particular applications.
3030
void RespondToDetection(float person_score, float no_person_score);
3131

32+
// Initialize GUI components
33+
void create_gui();
34+
3235
#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_DETECTION_RESPONDER_H_

examples/person_detection/main/esp_cli.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "esp_cli.h"
2525
#include "esp_timer.h"
2626

27+
#if CLI_ONLY_INFERENCE
2728
#define IMAGE_COUNT 10
2829
static uint8_t *image_database[IMAGE_COUNT];
2930

@@ -38,6 +39,7 @@ extern const uint8_t image6_start[] asm("_binary_image6_start");
3839
extern const uint8_t image7_start[] asm("_binary_image7_start");
3940
extern const uint8_t image8_start[] asm("_binary_image8_start");
4041
extern const uint8_t image9_start[] asm("_binary_image9_start");
42+
#endif
4143

4244
static const char *TAG = "[esp_cli]";
4345

@@ -96,6 +98,7 @@ static int mem_dump_cli_handler(int argc, char *argv[])
9698
return 0;
9799
}
98100

101+
#if CLI_ONLY_INFERENCE
99102
static int inference_cli_handler(int argc, char *argv[])
100103
{
101104
/* Just to go to the next line */
@@ -121,6 +124,18 @@ static int inference_cli_handler(int argc, char *argv[])
121124
return 0;
122125
}
123126

127+
int esp_cli_register_inference_command() {
128+
esp_console_cmd_t command = {
129+
.command = "detect_image",
130+
.help = "detect_image <image_number>"
131+
"Note: image numbers ranging from 0 - 9 only are valid",
132+
.func = inference_cli_handler,
133+
};
134+
esp_console_cmd_register(&command);
135+
return 0;
136+
}
137+
#endif
138+
124139
static esp_console_cmd_t diag_cmds[] = {
125140
{
126141
.command = "mem-dump",
@@ -137,12 +152,6 @@ static esp_console_cmd_t diag_cmds[] = {
137152
.help = "",
138153
.func = cpu_dump_cli_handler,
139154
},
140-
{
141-
.command = "detect_image",
142-
.help = "detect_image <image_number>"
143-
"Note: image numbers ranging from 0 - 9 only are valid",
144-
.func = inference_cli_handler,
145-
},
146155
};
147156

148157
int esp_cli_register_cmds()
@@ -158,6 +167,7 @@ int esp_cli_register_cmds()
158167

159168
static void image_database_init()
160169
{
170+
#if CLI_ONLY_INFERENCE
161171
image_database[0] = (uint8_t *) image0_start;
162172
image_database[1] = (uint8_t *) image1_start;
163173
image_database[2] = (uint8_t *) image2_start;
@@ -168,7 +178,7 @@ static void image_database_init()
168178
image_database[7] = (uint8_t *) image7_start;
169179
image_database[8] = (uint8_t *) image8_start;
170180
image_database[9] = (uint8_t *) image9_start;
171-
181+
#endif
172182
}
173183

174184
int esp_cli_start()

examples/person_detection/main/esp_cli.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern "C" {
1919
#endif
2020

2121
int esp_cli_start();
22+
int esp_cli_register_inference_command();
2223

2324
#ifdef __cplusplus
2425
}

examples/person_detection/main/idf_component.yml

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,16 @@ dependencies:
22
espressif/esp-tflite-micro:
33
version: "*"
44
override_path: "../../../"
5-
6-
espressif/esp32-camera: "~2.0.5"
7-
5+
espressif/esp32-camera: ~2.0.5
6+
espressif/esp32_s2_kaluga_kit:
7+
rules:
8+
- if: "$TFLITE_USE_BSP_KALUGA == 1"
9+
version: 3.*
810
espressif/esp32_s3_eye:
9-
version: "3.*"
1011
rules:
11-
- if: "target == $TFLITE_USE_BSP_S3_EYE"
12-
12+
- if: "$TFLITE_USE_BSP_S3_EYE == 1"
13+
version: 4.*
1314
espressif/esp32_s3_korvo_2:
14-
version: "2.*"
15-
rules:
16-
- if: "target == $TFLITE_USE_BSP_KORVO_2"
17-
18-
espressif/esp32_s2_kaluga_kit:
19-
version: "3.*"
2015
rules:
21-
- if: "target == $TFLITE_USE_BSP_KALUGA"
16+
- if: "$TFLITE_USE_BSP_KORVO_2 == 1"
17+
version: 2.*

examples/person_detection/main/image_provider.cc

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
32
43
Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,16 +12,17 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1312
See the License for the specific language governing permissions and
1413
limitations under the License.
1514
==============================================================================*/
16-
#include <cstdlib>
17-
#include <cstring>
18-
#include <iostream>
1915

16+
#include "string.h"
2017
#include "freertos/FreeRTOS.h"
2118
#include "freertos/task.h"
19+
20+
#if (CONFIG_TFLITE_USE_BSP)
21+
#include "bsp/esp-bsp.h"
22+
#endif
23+
24+
#include "esp_heap_caps.h"
2225
#include "esp_log.h"
23-
#include "esp_spi_flash.h"
24-
#include "esp_system.h"
25-
#include "esp_timer.h"
2626

2727
#include "app_camera_esp.h"
2828
#include "esp_camera.h"
@@ -31,8 +31,7 @@ limitations under the License.
3131
#include "esp_main.h"
3232

3333
static const char* TAG = "app_camera";
34-
35-
static uint16_t *display_buf; // buffer to hold data to be sent to display
34+
static uint16_t* display_buf;
3635

3736
// Get the camera module ready
3837
TfLiteStatus InitCamera() {
@@ -84,13 +83,19 @@ TfLiteStatus GetImage(int image_width, int image_height, int channels, int8_t* i
8483
// In case if display support is enabled, we initialise camera in rgb mode
8584
// Hence, we need to convert this data to grayscale to send it to tf model
8685
// For display we extra-polate the data to 192X192
86+
87+
// point to the last quarter of buffer
88+
uint16_t* cam_buf = display_buf + (96 * 96 * 3);
89+
memcpy((uint8_t*)cam_buf, fb->buf, fb->len);
90+
esp_camera_fb_return(fb);
91+
8792
for (int i = 0; i < kNumRows; i++) {
8893
for (int j = 0; j < kNumCols; j++) {
89-
uint16_t pixel = ((uint16_t *) (fb->buf))[i * kNumCols + j];
94+
uint16_t inference_pixel = cam_buf[i * kNumCols + j];
9095

9196
// for inference
92-
uint8_t hb = pixel & 0xFF;
93-
uint8_t lb = pixel >> 8;
97+
uint8_t hb = inference_pixel & 0xFF;
98+
uint8_t lb = inference_pixel >> 8;
9499
uint8_t r = (lb & 0x1F) << 3;
95100
uint8_t g = ((hb & 0x07) << 5) | ((lb & 0xE0) >> 3);
96101
uint8_t b = (hb & 0xF8);
@@ -102,8 +107,14 @@ TfLiteStatus GetImage(int image_width, int image_height, int channels, int8_t* i
102107
int8_t grey_pixel = ((305 * r + 600 * g + 119 * b) >> 10) - 128;
103108

104109
image_data[i * kNumCols + j] = grey_pixel;
110+
}
111+
}
105112

106-
// to display
113+
// for display
114+
lv_draw_sw_rgb565_swap(cam_buf, 96 * 96);
115+
for (int i = 0; i < kNumRows; i++) {
116+
for (int j = 0; j < kNumCols; j++) {
117+
uint16_t pixel = cam_buf[i * kNumCols + j];
107118
display_buf[2 * i * kNumCols * 2 + 2 * j] = pixel;
108119
display_buf[2 * i * kNumCols * 2 + 2 * j + 1] = pixel;
109120
display_buf[(2 * i + 1) * kNumCols * 2 + 2 * j] = pixel;
@@ -117,9 +128,9 @@ TfLiteStatus GetImage(int image_width, int image_height, int channels, int8_t* i
117128
for (int i = 0; i < image_width * image_height; i++) {
118129
image_data[i] = ((uint8_t *) fb->buf)[i] ^ 0x80;
119130
}
120-
#endif // DISPLAY_SUPPORT
121131

122132
esp_camera_fb_return(fb);
133+
#endif // DISPLAY_SUPPORT
123134
/* here the esp camera can give you grayscale image directly */
124135
return kTfLiteOk;
125136
#else

examples/person_detection/main/main.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@ limitations under the License.
2020
#include "freertos/task.h"
2121

2222
#include "esp_main.h"
23-
24-
#if CLI_ONLY_INFERENCE
2523
#include "esp_cli.h"
26-
#endif
2724

2825
void tf_main(void) {
2926
setup();
30-
#if CLI_ONLY_INFERENCE
3127
esp_cli_start();
28+
#if CLI_ONLY_INFERENCE
29+
esp_cli_register_inference_command();
3230
vTaskDelay(portMAX_DELAY);
3331
#else
3432
while (true) {

examples/person_detection/main/main_functions.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ limitations under the License.
3232
#include <esp_log.h>
3333
#include "esp_main.h"
3434

35-
// Globals, used for compatibility with Arduino-style sketches.
3635
namespace {
3736
const tflite::Model* model = nullptr;
3837
tflite::MicroInterpreter* interpreter = nullptr;
@@ -56,7 +55,6 @@ constexpr int kTensorArenaSize = 100 * 1024 + scratchBufSize;
5655
static uint8_t *tensor_arena;//[kTensorArenaSize]; // Maybe we should move this to external
5756
} // namespace
5857

59-
// The name of this function is important for Arduino compatibility.
6058
void setup() {
6159
// Map the model into a usable data structure. This doesn't involve any
6260
// copying or parsing, it's a very lightweight operation.
@@ -68,7 +66,7 @@ void setup() {
6866
}
6967

7068
if (tensor_arena == NULL) {
71-
tensor_arena = (uint8_t *) heap_caps_malloc(kTensorArenaSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
69+
tensor_arena = (uint8_t *) heap_caps_malloc(kTensorArenaSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
7270
}
7371
if (tensor_arena == NULL) {
7472
printf("Couldn't allocate memory of %d bytes\n", kTensorArenaSize);
@@ -113,11 +111,14 @@ void setup() {
113111
MicroPrintf("InitCamera failed\n");
114112
return;
115113
}
116-
#endif
114+
115+
#if DISPLAY_SUPPORT
116+
create_gui();
117+
#endif // DISPLAY_SUPPORT
118+
#endif // CLI_ONLY_INFERENCE
117119
}
118120

119121
#ifndef CLI_ONLY_INFERENCE
120-
// The name of this function is important for Arduino compatibility.
121122
void loop() {
122123
// Get image from provider.
123124
if (kTfLiteOk != GetImage(kNumCols, kNumRows, kNumChannels, input->data.int8)) {
@@ -144,7 +145,7 @@ void loop() {
144145
RespondToDetection(person_score_f, no_person_score_f);
145146
vTaskDelay(1); // to avoid watchdog trigger
146147
}
147-
#endif
148+
#endif // CLI_ONLY_INFERENCE
148149

149150
#if defined(COLLECT_CPU_STATS)
150151
long long total_time = 0;

0 commit comments

Comments
 (0)