Skip to content

Commit 621f762

Browse files
committed
feat(opencv): add color tracker example
1 parent 5c6aa20 commit 621f762

23 files changed

+1413
-0
lines changed

.gitlab/ci/build.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,16 @@ build_example_utilities_xz_decompress_file:
944944
variables:
945945
EXAMPLE_DIR: examples/utilities/xz_decompress_file
946946

947+
build_example_vision_opencv_color_tracker:
948+
extends:
949+
- .build_examples_template
950+
- .rules:build:example_vision_opencv_color_tracker
951+
parallel:
952+
matrix:
953+
- IMAGE: espressif/idf:release-v5.4
954+
variables:
955+
EXAMPLE_DIR: examples/vision/opencv/color_tracker
956+
947957
build_components_audio_adc_mic_test_apps:
948958
extends:
949959
- .build_examples_template

.gitlab/ci/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ pack-upload_files:
132132
- job: "build_example_usb_host_usb_cdc_4g_module: [espressif/idf:release-v5.1]"
133133
- job: "build_example_usb_host_usb_cdc_basic: [espressif/idf:release-v5.1]"
134134
- job: "build_example_usb_host_usb_msc_ota: [espressif/idf:release-v5.1]"
135+
- job: "build_example_vision_opencv_color_tracker: [espressif/idf:release-v5.4]"
135136

136137
artifacts:
137138
when: always

.gitlab/ci/rules.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,9 @@
617617
.patterns-example_utilities_xz_decompress_file: &patterns-example_utilities_xz_decompress_file
618618
- "examples/utilities/xz_decompress_file/**/*"
619619

620+
.patterns-example_vision_opencv_color_tracker: &patterns-example_vision_opencv_color_tracker
621+
- "examples/vision/opencv/color_tracker/**/*"
622+
620623
.patterns-example_gprof_gprof_simple: &patterns-example_gprof_gprof_simple
621624
- "examples/gprof/gprof_simple/**/*"
622625

@@ -1571,6 +1574,16 @@
15711574
- <<: *if-dev-push
15721575
changes: *patterns-example_utilities_xz_decompress_file
15731576

1577+
.rules:build:example_vision_opencv_color_tracker:
1578+
rules:
1579+
- <<: *if-protected
1580+
- <<: *if-label-build
1581+
- <<: *if-trigger-job
1582+
- <<: *if-dev-push
1583+
changes: *patterns-build_system
1584+
- <<: *if-dev-push
1585+
changes: *patterns-example_vision_opencv_color_tracker
1586+
15741587
.rules:build:example_elf_loader_elf_loader_example:
15751588
rules:
15761589
- <<: *if-protected

examples/.build-rules.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@ examples/utilities/xz_decompress_file:
418418
enable:
419419
- if: INCLUDE_DEFAULT == 1
420420

421+
examples/vision/opencv/color_tracker:
422+
enable:
423+
- if: IDF_TARGET in ["esp32p4"] and (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 4)
424+
421425
examples/gprof/gprof_simple:
422426
enable:
423427
- if: IDF_TARGET in ["esp32","esp32s2","esp32s3","esp32c3"]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
project(color_tracker)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
| Supported Targets | ESP32-P4 |
2+
| ----------------- | -------- |
3+
4+
# OpenCV Color Tracker
5+
6+
This example is based on the [esp_video](https://components.espressif.com/components/espressif/esp_video/) and [opencv](https://components.espressif.com/components/espressif/opencv/) components, and demonstrates how to display the detect results on an LCD screen.
7+
8+
## How to use the example
9+
10+
## ESP-IDF Required
11+
12+
- This example supports ESP-IDF release/v5.4 and later branches. By default, it runs on ESP-IDF release/v5.4.
13+
- Please follow the [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/get-started/index.html) to set up the development environment. **We highly recommend** you [Build Your First Project](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/get-started/index.html#build-your-first-project) to get familiar with ESP-IDF and make sure the environment is set up correctly.
14+
15+
16+
### Prerequisites
17+
18+
* An ESP32-P4-Function-EV-Board.
19+
* A 7-inch 1024 x 600 LCD screen powered by the [EK79007](https://dl.espressif.com/dl/schematics/display_driver_chip_EK79007AD_datasheet.pdf) IC, accompanied by a 32-pin FPC connection [adapter board](https://dl.espressif.com/dl/schematics/esp32-p4-function-ev-board-lcd-subboard-schematics.pdf) ([LCD Specifications](https://github.com/espressif/esp-dev-kits/blob/master/docs/_static/esp32-p4-function-ev-board/camera_display_datasheet/display_datasheet.pdf)).
20+
* A MIPI-CSI camera powered by the SC2336 IC, accompanied by a 32-pin FPC connection [adapter board](https://dl.espressif.com/dl/schematics/esp32-p4-function-ev-board-camera-subboard-schematics.pdf) ([Camera Specifications](https://dl.espressif.com/dl/schematics/camera_datasheet.pdf)).
21+
* A USB-C cable for power supply and programming.
22+
* Please refer to the following steps for the connection:
23+
* **Step 1**. According to the table below, connect the pins on the back of the screen adapter board to the corresponding pins on the development board.
24+
25+
| Screen Adapter Board | ESP32-P4-Function-EV-Board |
26+
| -------------------- | -------------------------- |
27+
| 5V (any one) | 5V (any one) |
28+
| GND (any one) | GND (any one) |
29+
| PWM | GPIO26 |
30+
| LCD_RST | GPIO27 |
31+
32+
* **Step 2**. Connect the FPC of LCD through the `MIPI_DSI` interface.
33+
* **Step 3**. Connect the FPC of Camera through the `MIPI_CSI` interface.
34+
* **Step 4**. Use a USB-C cable to connect the `USB-UART` port to a PC (Used for power supply and viewing serial output).
35+
* **Step 5**. Turn on the power switch of the board.
36+
37+
### Configure the Project
38+
39+
Run `idf.py menuconfig` and navigate to the `Example Configuration` menu, where you can configure the relevant pins and example-related options.
40+
41+
This example supports configuring two HSV ranges, and you can adjust the Primary Color Range and the Secondary Color Range separately to identify the colors you want. By default, the intervals are set for recognizing red.
42+
43+
```
44+
Example Configuration --->
45+
Primary Color Range --->
46+
(0) Primary Lower H (Hue)
47+
(120) Primary Lower S (Saturation)
48+
(70) Primary Lower V (Value)
49+
(10) Primary Upper H (Hue)
50+
(255) Primary Upper S (Saturation)
51+
(255) Primary Upper V (Value)
52+
Secondary Color Range --->
53+
(170) Secondary Lower H (Hue)
54+
(120) Secondary Lower S (Saturation)
55+
(70) Secondary Lower V (Value)
56+
(180) Secondary Upper H (Hue)
57+
(255) Secondary Upper S (Saturation)
58+
(255) Secondary Upper V (Value)
59+
```
60+
61+
As well, in the `Espressif Camera Sensors` Configurations, the camera sensor can be selected.
62+
63+
```
64+
Component config --->
65+
Espressif Camera Sensors Configurations --->
66+
[*] SC2336 ---->
67+
Default format select for MIPI (RAW8 1280x720 30fps, MIPI 2lane 24M input) --->
68+
(X) RAW8 1280x720 30fps, MIPI 2lane 24M input
69+
```
70+
71+
### Build and Flash
72+
73+
Build the project and flash it to the board, then run monitor tool to view serial output (replace `PORT` with your board's serial port name):
74+
75+
```c
76+
idf.py -p PORT flash monitor
77+
```
78+
79+
To exit the serial monitor, type ``Ctrl-]``.
80+
81+
See the [ESP-IDF Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
82+
83+
![color_tracker](https://dl.espressif.com/AE/esp-iot-solution/cv_color_tracker.gif)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
idf_component_register(SRC_DIRS "."
2+
INCLUDE_DIRS "." "include/"
3+
REQUIRES "esp_mm" "esp_timer")
4+
5+
set_source_files_properties(
6+
"cv_detect.cpp"
7+
PROPERTIES
8+
COMPILE_OPTIONS
9+
"-Wno-deprecated-enum-enum-conversion"
10+
)
11+
12+
set(MODIFY_EXE ${PROJECT_DIR}/modify_opencv.py)
13+
set(OPENCV_CMAKE_TARGET "${PROJECT_DIR}/managed_components/espressif__opencv/CMakeLists.txt")
14+
set(OPENCV_CMAKE_SOURCE "CMakeLists.txt.opencv")
15+
16+
add_custom_command(
17+
OUTPUT ${OPENCV_CMAKE_TARGET}
18+
COMMENT "Updating OpenCV CMakeLists.txt using modify_opencv.py"
19+
COMMAND python ${MODIFY_EXE}
20+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
21+
DEPENDS ${OPENCV_CMAKE_SOURCE}
22+
VERBATIM)
23+
24+
add_custom_target(update_opencv ALL DEPENDS ${OPENCV_CMAKE_TARGET})
25+
add_dependencies(app update_opencv)
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
set(deps esp_rom vfs lwip pthread newlib)
2+
3+
idf_component_register(
4+
# We need the dummy source file so that the component
5+
# library is not an interface library. This allows to
6+
# get the list of include directories from other components
7+
# via INCLUDE_DIRECTORIES property later on.
8+
SRCS dummy.c
9+
# OpenCV librarires depend on some of the IDF libraries,
10+
# add them here:
11+
PRIV_REQUIRES ${deps})
12+
13+
# Determine compilation flags used for building OpenCV
14+
# Flags inherited from IDF build system and other IDF components:
15+
set(idf_include_directories $<TARGET_PROPERTY:idf::${COMPONENT_NAME},INCLUDE_DIRECTORIES>)
16+
set(includes "-I$<JOIN:${idf_include_directories}, -I>")
17+
# IDF is built with -D_GNU_SOURCE, but we don't actually implement all _GNU_SOURCE
18+
# features. Defining _GNU_SOURCE causes OpenCV to try to use them, which fails.
19+
# Use _DEFAULT_SOURCE instead, it provides enough features to build OpenCV.
20+
set(extra_defines -D_DEFAULT_SOURCE)
21+
# Final flags for C and C++:
22+
set(c_flags "${includes} ${extra_defines}")
23+
set(cxx_flags "${includes} ${extra_defines}")
24+
set(cxx_flags "${includes} ${extra_defines} -DCV_INT32_T_IS_LONG_INT=ON -Dalloca=__builtin_alloca")
25+
26+
set(common_flags "-ggdb -ffunction-sections -fdata-sections")
27+
28+
# Calculate flags for optimizations, assertions, debug info:
29+
if(COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE)
30+
set(assert_flags "-DNDEBUG")
31+
else()
32+
set(assert_flags "-DDEBUG -D_DEBUG")
33+
endif()
34+
35+
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
36+
set(assert_flags "${assert_flags} -mlongcalls -mauto-litpools")
37+
endif()
38+
39+
if(CONFIG_COMPILER_OPTIMIZATION_DEFAULT)
40+
set(opt_c_flags "-Og ${common_flags} ${assert_flags} -Wno-format -Wno-format-security -Wno-undef -Wno-calloc-transposed-args")
41+
set(opt_cxx_flags "-Og ${common_flags} ${assert_flags} -Wno-undef -Wno-cast-user-defined -Wno-format -Wno-format-security -Wno-cast-function-type -Wno-deprecated-enum-enum-conversion")
42+
set(opt_args -DCMAKE_BUILD_TYPE=Debug
43+
-DCMAKE_C_FLAGS_DEBUG=${opt_c_flags}
44+
-DCMAKE_CXX_FLAGS_DEBUG=${opt_cxx_flags})
45+
elseif(CONFIG_COMPILER_OPTIMIZATION_SIZE)
46+
# Normally we should use MinSizeRel build type for this,
47+
# however OpenCV CMake files only handle Debug and Release
48+
# (see e.g. opencv/cmake/OpenCVCompilerOptions.cmake).
49+
# So we redefine the flags for Release instead.
50+
set(opt_c_flags "-Os ${common_flags} ${assert_flags} -Wno-format -Wno-format-security -Wno-undef -Wno-calloc-transposed-args")
51+
set(opt_cxx_flags "-Os ${common_flags} ${assert_flags} -Wno-undef -Wno-cast-user-defined -Wno-format -Wno-format-security -Wno-cast-function-type -Wno-deprecated-enum-enum-conversion")
52+
set(opt_args -DCMAKE_BUILD_TYPE=Release
53+
-DCMAKE_C_FLAGS_RELEASE=${opt_c_flags}
54+
-DCMAKE_CXX_FLAGS_RELEASE=${opt_cxx_flags})
55+
elseif(COMPILER_OPTIMIZATION_PERF)
56+
# Currently OpenCV fails to compile at -O2 level on Xtensa due to a compiler issue,
57+
# details in https://github.com/jcmvbkbc/gcc-xtensa/issues/14.
58+
# Compiling at -O3 happens to be okay.
59+
set(opt_c_flags "-O3 ${common_flags} ${assert_flags} -Wno-format -Wno-format-security -Wno-undef -Wno-calloc-transposed-args")
60+
set(opt_cxx_flags "-O3 ${common_flags} ${assert_flags} -Wno-undef -Wno-cast-user-defined -Wno-format -Wno-format-security -Wno-cast-function-type -Wno-deprecated-enum-enum-conversion")
61+
set(opt_args -DCMAKE_BUILD_TYPE=Release
62+
-DCMAKE_C_FLAGS_RELEASE=${opt_c_flags}
63+
-DCMAKE_CXX_FLAGS_RELEASE=${opt_cxx_flags})
64+
elseif(COMPILER_OPTIMIZATION_NONE)
65+
set(opt_c_flags "-O0 ${common_flags} ${assert_flags} -Wno-format -Wno-format-security -Wno-undef -Wno-calloc-transposed-args")
66+
set(opt_cxx_flags "-O0 ${common_flags} ${assert_flags} -Wno-undef -Wno-cast-user-defined -Wno-format -Wno-format-security -Wno-cast-function-type -Wno-deprecated-enum-enum-conversion")
67+
set(opt_args -DCMAKE_BUILD_TYPE=Debug
68+
-DCMAKE_C_FLAGS_DEBUG=${opt_c_flags}
69+
-DCMAKE_CXX_FLAGS_DEBUG=${opt_cxx_flags})
70+
else()
71+
message(FATAL_ERROR "Unsupported optimization level")
72+
endif()
73+
74+
# Python to use for OpenCV build
75+
idf_build_get_property(python PYTHON)
76+
77+
include(ExternalProject)
78+
79+
# Build OpenCV in this directory:
80+
set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/opencv-build)
81+
82+
# List of OpenCV static libraries we expect to see after the build.
83+
# Obtained manually by looking at ${BINARY_DIR}/install/lib directory.
84+
# In some cases it's important to have right order of libraries here.
85+
set(opencv_libraries
86+
calib3d flann fuzzy
87+
objdetect tracking video videostab features2d
88+
surface_matching
89+
shape stereo stitching structured_light
90+
line_descriptor ml phase_unwrapping photo plot quality rapid
91+
imgcodecs imgproc core
92+
)
93+
94+
set(3rdparty_libraries
95+
zlib
96+
libopenjp2
97+
libjpeg-turbo
98+
libpng
99+
libtiff
100+
libwebp
101+
)
102+
103+
# List of all static libraries to be produced
104+
set(all_libraries)
105+
set(all_targets)
106+
foreach(libname ${opencv_libraries})
107+
set(lib_path ${BINARY_DIR}/install/lib/libopencv_${libname}.a)
108+
list(APPEND all_libraries ${lib_path})
109+
list(APPEND all_targets opencv_${libname})
110+
add_prebuilt_library(opencv_${libname} ${lib_path})
111+
endforeach()
112+
foreach(libname ${3rdparty_libraries})
113+
set(lib_path ${BINARY_DIR}/install/lib/opencv4/3rdparty/lib${libname}.a)
114+
list(APPEND all_libraries ${lib_path})
115+
list(APPEND all_targets opencv_${libname})
116+
add_prebuilt_library(opencv_${libname} ${lib_path})
117+
endforeach()
118+
119+
# Add OpenCV as a subproject.
120+
ExternalProject_Add(opencv_proj
121+
SOURCE_DIR ${COMPONENT_DIR}/opencv
122+
BINARY_DIR ${BINARY_DIR}
123+
BUILD_BYPRODUCTS ${all_libraries}
124+
# These two options are set so that Ninja immediately outputs
125+
# the subproject build to the terminal. Otherwise it looks like the
126+
# build process "hangs" for too long until OpenCV build is complete.
127+
USES_TERMINAL_CONFIGURE TRUE
128+
USES_TERMINAL_BUILD TRUE
129+
# Arguments to pass to OpenCV CMake invocation:
130+
CMAKE_ARGS
131+
-DCMAKE_C_FLAGS=${c_flags}
132+
-DCMAKE_CXX_FLAGS=${cxx_flags}
133+
${opt_args}
134+
-DCMAKE_INSTALL_PREFIX=${BINARY_DIR}/install
135+
-DENABLE_CCACHE=${CCACHE_ENABLE}
136+
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
137+
-DPYTHON_DEFAULT_EXECUTABLE=${python}
138+
-DCV_CPU_BASELINE_MODE=${CONFIG_IDF_TARGET}
139+
-DCV_DISABLE_OPTIMIZATION=0
140+
-DOPENCV_EXTRA_MODULES_PATH=${CMAKE_CURRENT_LIST_DIR}/opencv_contrib/modules
141+
-DOPENCV_FORCE_3RDPARTY_BUILD=1
142+
-DCMAKE_SYSTEM_PROCESSOR=${CONFIG_IDF_TARGET_ARCH}
143+
-DENABLE_PIC=0
144+
-DTARGET=${CONFIG_IDF_TARGET}
145+
-DWITH_ADE=0
146+
-DWITH_JPEG=1
147+
-DWITH_OPENCL=0
148+
-DWITH_OPENEXR=0
149+
-DWITH_OPENGL=0
150+
-DWITH_OPENMP=0
151+
-DWITH_PNG=1
152+
-DWITH_PROTOBUF=0
153+
-DWITH_TIFF=1
154+
-DWITH_WEBP=1
155+
-DBUILD_EXAMPLES=0
156+
-DBUILD_PACKAGE=1
157+
-DBUILD_PERF_TESTS=0
158+
-DBUILD_PNG=1
159+
-DBUILD_SHARED_LIBS=0
160+
-DBUILD_TESTS=0
161+
-DBUILD_ZLIB=1
162+
-DBUILD_opencv_apps=0
163+
-DBUILD_opencv_bgsegm=0
164+
-DBUILD_opencv_datasets=0
165+
-DBUILD_opencv_imgcodecs=1
166+
-DBUILD_opencv_objdetect=1
167+
-DBUILD_opencv_imgproc=1
168+
-DBUILD_opencv_tracking=1
169+
-DBUILD_opencv_video=1
170+
-DBUILD_opencv_videoio=0
171+
)
172+
173+
# Attach header files to the component library:
174+
set_target_properties(${COMPONENT_LIB} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${BINARY_DIR}/install/include/opencv4)
175+
176+
# Make sure the subproject is built before the component library:
177+
add_dependencies(${COMPONENT_LIB} opencv_proj)
178+
179+
180+
foreach(opencv_target ${all_targets})
181+
# Attach IDF compoenent dependencies to OpenCV libraries
182+
foreach(dep ${deps})
183+
target_link_libraries(${opencv_target} INTERFACE idf::${dep})
184+
endforeach()
185+
# Attach OpenCV libraries to the component library
186+
target_link_libraries(${COMPONENT_LIB} INTERFACE ${opencv_target})
187+
endforeach()

0 commit comments

Comments
 (0)