removed blbo size limit

main
Jake 2026-07-21 15:33:23 +08:00
parent c2f4e52e80
commit f92185d575
22 changed files with 19098 additions and 19019 deletions

View File

@ -6,7 +6,7 @@ ESP32-S3 camera board that finds a coloured blob and reports its position over I
The ESP runs HSV blob detection on the camera. A MicroPython master can turn the camera on, set colour, and poll for a target. Optionally it can join WiFi so you can open a browser page to tune the colour live.
Target position from `read_target()` is relative to the image centre (320x240). Positive x is right, positive y is up. No target returns `None`.
Target position from `read_target()` is relative to the image centre (320x240). Positive x is right, positive y is up. Diameter is the blob size in pixels (2 × detector radius). No target returns `None`.
## Hardware
@ -57,8 +57,8 @@ while True:
if target is None:
print("no target")
else:
x, y = target
print("target at ({}, {})".format(x, y))
x, y, diameter = target
print("target at ({}, {}) diameter={}".format(x, y, diameter))
time.sleep(0.07)
```
@ -67,8 +67,9 @@ Useful calls:
- `eye.start()` — camera on and local detection
- `eye.set_hsv(h, s, v)` / `eye.set_tolerance(...)` — colour (or tune in the browser)
- `eye.set_wifi(ssid, password)` / `eye.wifi_off()` / `eye.wifi_ip()`
- `eye.read_target()``(x, y)` or `None`
- `eye.read_target()``(x, y, diameter)` or `None`
- `eye.set_rgb(r, g, b)`
- `eye.set_size_limits(max_diameter=..., max_area=...)` — optional; default is no max size
## Web UI

View File

@ -1 +1 @@
11b3b61e9480df528d6e66dea27b9eac C:/Users/jake/Documents/linefollower_eye/build/linefollower_eye.bin
6a6455df3be9ce6cb464eb7b6094afba C:/Users/jake/Documents/linefollower_eye/build/linefollower_eye.bin

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
bb2f376d32d2591cdbc413fa638a4b8548cd1938
c2f4e52e8097cb0b87bd60aec09a67246b1e8d25

View File

@ -143,3 +143,9 @@
13 137 8062192591250737 C:/Users/jake/Documents/linefollower_eye/build/bootloader/esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
15 138 8062192926361752 esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
15 138 8062192926361752 C:/Users/jake/Documents/linefollower_eye/build/bootloader/esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
12 139 8063066162703124 esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
12 139 8063066162703124 C:/Users/jake/Documents/linefollower_eye/build/bootloader/esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
14 127 8063067509934642 esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
14 127 8063067509934642 C:/Users/jake/Documents/linefollower_eye/build/bootloader/esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
14 132 8063067684964067 esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501
14 132 8063067684964067 C:/Users/jake/Documents/linefollower_eye/build/bootloader/esp-idf/esptool_py/CMakeFiles/bootloader_check_size 72d5b948b0e48501

View File

@ -3262,7 +3262,7 @@ build esp-idf/partition_table/CMakeFiles/partition_table-flash | ${cmake_ninja_w
build cmake_object_order_depends_target___idf_esp_app_format: phony || cmake_object_order_depends_target___idf_esp_bootloader_format
build esp-idf/esp_app_format/CMakeFiles/__idf_esp_app_format.dir/esp_app_desc.c.obj: C_COMPILER____idf_esp_app_format_unscanned_ D$:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_app_format/esp_app_desc.c || cmake_object_order_depends_target___idf_esp_app_format
DEFINES = -DESP_PLATFORM -DIDF_VER=\"v5.5.2\" -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ -D_GLIBCXX_HAVE_POSIX_SEMAPHORE -D_GLIBCXX_USE_POSIX_SEMAPHORE -D_GNU_SOURCE -D_POSIX_READER_WRITER_LOCKS -D PROJECT_NAME=\"linefollower_eye\" -DPROJECT_VER=\"bb2f376-dirty\"
DEFINES = -DESP_PLATFORM -DIDF_VER=\"v5.5.2\" -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ -D_GLIBCXX_HAVE_POSIX_SEMAPHORE -D_GLIBCXX_USE_POSIX_SEMAPHORE -D_GNU_SOURCE -D_POSIX_READER_WRITER_LOCKS -D PROJECT_NAME=\"linefollower_eye\" -DPROJECT_VER=\"c2f4e52-dirty\"
DEP_FILE = esp-idf\esp_app_format\CMakeFiles\__idf_esp_app_format.dir\esp_app_desc.c.obj.d
FLAGS = -mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -fdiagnostics-color=always -ffunction-sections -fdata-sections -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wextra -Wno-error=extra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -mdisable-hardware-atomics -Og -fno-shrink-wrap -fmacro-prefix-map=C:/Users/jake/Documents/linefollower_eye=. -fmacro-prefix-map=D:/Espressif/frameworks/esp-idf-v5.5.2=/IDF -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu17 -Wno-old-style-declaration
INCLUDES = -IC:/Users/jake/Documents/linefollower_eye/build/config -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_app_format/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/newlib/platform_include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/config/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/config/include/freertos -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/config/xtensa/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/FreeRTOS-Kernel/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/FreeRTOS-Kernel/portable/xtensa/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/freertos/esp_additions/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/include/soc -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/include/soc/esp32s3 -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/dma/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/ldo/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/debug_probe/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/mspi_timing_tuning/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/power_supply/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/port/esp32s3/. -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/port/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/. -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/heap/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/heap/tlsf -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/log/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/soc/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/soc/esp32s3 -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/soc/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/soc/esp32s3/register -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/hal/platform_port/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/hal/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/hal/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_rom/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_rom/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_rom/esp32s3/include/esp32s3 -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_rom/esp32s3 -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_common/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_system/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_system/port/soc -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/esp_system/port/include/private -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/xtensa/esp32s3/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/xtensa/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/xtensa/deprecated_include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/include/apps -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/include/apps/sntp -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/lwip/src/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/port/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/port/freertos/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/port/esp32xx/include -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/port/esp32xx/include/arch -ID:/Espressif/frameworks/esp-idf-v5.5.2/components/lwip/port/esp32xx/include/sys

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Command: ninja all

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
{
"version": "1.2",
"project_name": "linefollower_eye",
"project_version": "bb2f376-dirty",
"project_version": "c2f4e52-dirty",
"project_path": "C:/Users/jake/Documents/linefollower_eye",
"idf_path": "D:/Espressif/frameworks/esp-idf-v5.5.2",
"build_dir": "C:/Users/jake/Documents/linefollower_eye/build",

View File

@ -86,8 +86,6 @@ static const char *TAG = "eye_i2c";
#define CMD_WIFI_ON 7
#define CMD_WIFI_OFF 8
#define MAX_BLOB_AREA 20000
#define MAX_BLOB_RADIUS 100
#define EYE_I2C_RX_MAX 128
#if !CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2
@ -226,9 +224,6 @@ static void refresh_regs(void)
vision_stats_t stt;
vision_get_stats(&stt);
bool found = stt.found;
if (found && (stt.area > MAX_BLOB_AREA || stt.radius > MAX_BLOB_RADIUS)) {
found = false;
}
tmp[REG_FOUND] = found ? 1 : 0;
if (found) {
put_u16(&tmp[REG_CX_L], (uint16_t)(int16_t)(stt.cx + (stt.cx >= 0 ? 0.5f : -0.5f)));

View File

@ -27,6 +27,6 @@ else:
if target is None:
print("no target")
else:
x, y = target
print("target at ({}, {})".format(x, y))
x, y, diameter = target
print("target at ({}, {}) diameter={}".format(x, y, diameter))
time.sleep(0.2)

View File

@ -21,8 +21,8 @@ Example:
if target is None:
print("no target")
else:
x, y = target # offset from image centre (0,0)
print("target at", x, y)
x, y, diameter = target # offset from image centre (0,0)
print("target at", x, y, "diameter", diameter)
time.sleep(0.1)
"""
@ -82,6 +82,9 @@ class Vision:
self.i2c = I2C(0, sda=Pin(sda), scl=Pin(scl), freq=freq)
else:
self.i2c = i2c
# Optional size filters for read_target(); None = no limit
self._max_diameter = None
self._max_area = None
time.sleep(1)
@staticmethod
@ -257,6 +260,18 @@ class Vision:
self._write(_REG_RGB, int(r) & 0xFF, int(g) & 0xFF, int(b) & 0xFF)
time.sleep_ms(10)
def set_size_limits(self, max_diameter=None, max_area=None):
"""
Optionally reject oversized blobs in read_target().
max_diameter: max blob diameter in pixels, or None for no limit
max_area: max blob area in pixels, or None for no limit
Example (old defaults): eye.set_size_limits(max_diameter=200, max_area=20000)
"""
self._max_diameter = max_diameter
self._max_area = max_area
# --- tracking ---
def read_target(self):
@ -266,10 +281,11 @@ class Vision:
Image is 320x240, so centre is (0, 0):
+x = right of centre, -x = left
+y = above centre, -y = below
diameter = blob diameter in pixels (2 * detector radius)
Returns:
(x, y) if a target was found
None if no target (or a bad I2C read)
(x, y, diameter) if a target was found
None if no target (or a bad I2C read)
"""
try:
raw = self._read(_REG_FOUND, 13)
@ -290,6 +306,9 @@ class Vision:
return None
if cx < 0 or cy < 0 or cx >= _FRAME_W or cy >= _FRAME_H:
return None
if area >= 20000 or radius >= 100 or area == 65535:
diameter = int(radius) * 2
if self._max_diameter is not None and diameter > self._max_diameter:
return None
return (int(cx) - _CENTER_X, _CENTER_Y - int(cy))
if self._max_area is not None and area > self._max_area:
return None
return (int(cx) - _CENTER_X, _CENTER_Y - int(cy), diameter)