From 1f6634349e4148b26d6de18bb51aeece7f8031fd Mon Sep 17 00:00:00 2001 From: lmtreser Date: Fri, 7 Jun 2024 20:05:50 -0300 Subject: [PATCH] update esp32cam --- dispositivos/esp32-cam/IMG1.jpg | Bin 0 -> 31988 bytes dispositivos/esp32-cam/README.md | 184 +++++++++++++++++++++++++++--- dispositivos/esp32-cam/capture.py | 51 ++++++--- dispositivos/esp32-cam/process.py | 4 +- 4 files changed, 203 insertions(+), 36 deletions(-) create mode 100644 dispositivos/esp32-cam/IMG1.jpg diff --git a/dispositivos/esp32-cam/IMG1.jpg b/dispositivos/esp32-cam/IMG1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3e4c4ed094a09db1564284b9c5ca5f51535a93a8 GIT binary patch literal 31988 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 literal 0 HcmV?d00001 diff --git a/dispositivos/esp32-cam/README.md b/dispositivos/esp32-cam/README.md index 07a6f6d..dbf35ac 100644 --- a/dispositivos/esp32-cam/README.md +++ b/dispositivos/esp32-cam/README.md @@ -9,24 +9,6 @@ Dispositivo base para trabajar con ESP32-CAM. - `capture.py` Script para capturar una fotografía - `process.py` Script para detectar colores -## Firmware - -La placa ESP32-CAM se puede utilizar con MicroPython. Utilizaremos el driver `micropython-camera-driver` de [Mauro Riva](https://github.com/lemariva). Se puede descargar desde el repositorio en [GitHub](https://github.com/lemariva/micropython-camera-driver). - -Como la placa no posee conexión USB, hay que utilizar un adaptador USB-TTL. Las conexiones son las que muestra la imagen. - -![Conexiones FTDI <> ESP32-CAM](./FTDI.png) - -Para instalarlo: - -```bash -esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash -``` - -```bash -esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 micropython_camera_feeeb5ea3_esp32_idf4_4.bin -``` - ## Pinout ![Pinout ESP32-CAM](./ESP32-CAM%20Pinout.jpg) @@ -66,9 +48,173 @@ esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 micropython_ca | GPIO 27 | SCL SIOC_GPIO_NUM | OV2640 | | GPIO 32 | POWER PIN PWDN_GPIO_NUM | OV2640 | +## Firmware + +La placa ESP32-CAM se puede utilizar con MicroPython. Utilizaremos el driver `micropython-camera-driver` de [Mauro Riva](https://github.com/lemariva). Se puede descargar desde el repositorio en [GitHub](https://github.com/lemariva/micropython-camera-driver). + +Como la placa no posee conexión USB, hay que utilizar un adaptador USB-TTL. Las conexiones son las que muestra la imagen. + +![Conexiones FTDI <> ESP32-CAM](./FTDI.png) + +Para instalarlo: + +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash +``` + +```bash +esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 micropython_camera_feeeb5ea3_esp32_idf4_4.bin +``` + +## Métodos + +**init**, activa e inicializa la cámara. + +```python +# Formato +camera.init(0, parámetro=valor, …) +``` + +- `xclk_freq_hz` = `[10000000, 20000000 ]`: Frecuencia de reloj de la cámara en Hz +- `frame_size`: Tamaño de la imagen capturada +- `pixel_format` = `[JPEG, YUV422, GRAYSCALE, RGB565]`: Formato de la imagen capturada +- `jpeg_quality` = `[10..63]`: Calidad de la imagen capturada, los valores menores representan mayor calidad +- `fb_location` = `[DRAM, PSRAM]`: Ubicación de la imagen capturada, es conveniente usar PSRAM. + +```python +# Ejemplo +camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM) +``` + +**deinit**, desactiva la cámara. + +```python +# Ejemplo +camera.deinit() +``` + +**flip**, cambia la orientación vertical de la imagen. + +- `0`: Imagen normal +- `1`: Imagen invertida + +```python +# Ejemplo +camera.flip(0) +``` + +**mirror**, cambia la orientación horizontal de la imagen. + +- `0`: Imagen normal +- `1`: Imagen invertida + +```python +# Ejemplo +camera.mirror(1) +``` + +**framesize**, especifica el tamaño y resolución de la imagen capturada. + +- `FRAME_96X96` = 96*96 +- `FRAME_QQVGA` = 160*120 +- `FRAME_QCIF` = 176*144 +- `FRAME_HQVGA` = 240*160 +- `FRAME_240X240` = 240*240 +- `FRAME_QVGA` = 320*240 +- `FRAME_CIF` = 352*288 +- `FRAME_HVGA` = 480*320 +- `FRAME_VGA` = 640*480 +- `FRAME_SVGA` = 800*600 +- `FRAME_XGA` = 1024*768 +- `FRAME_HD` = 1280*720 +- `FRAME_SXGA` = 1280*1024 +- `FRAME_UXGA` = 1600*1200 +- `FRAME_FHD` = 1920*1080 +- `FRAME_P_HD` = 2048*1152 +- `FRAME_P_3MP` = 2048*1536 +- `FRAME_QXGA` = 2048*1536 +- `FRAME_QHD` = 2560*1440 +- `FRAME_WQXGA` = 2560*1600 +- `FRAME_P_FHD` +- `FRAME_QSXGA` = 2560*2048 + +```python +# Ejemplo +camera.framesize(camera.FRAME_CIF) +``` + +**quality**, especifica la calidad de la imagen capturada. Varia entre 10 (calidad alta) y 63 (calidad baja). + +```python +# Ejemplo +camera.quality(10) +``` + +**contrast**, especifica el contraste de la imagen. Varia entre -2 (contraste bajo) y 2 (contraste alto). Por omisión vale 0. + +```python +# Ejemplo +camera.contrast(1) +``` + +**saturation**, especifica la saturación (intensidad de los colores) de la imagen. Varia entre -2 (baja intensidad) y 2 (alta intensidad). Por omisión vale 0. + +```python +# Ejemplo +camera.saturation(-1) +``` + +**brightness**, especifica el brillo de la imagen. Varia entre -2 (mas bajo) y 2 (mas alto). Por omisión vale 0. + +```python +# Ejemplo +camera.brightness(1) +``` + +**speffect**, aplica un efecto a la imagen. + +- `EFFECT_NONE`: sin efecto, valor por omisión +- `EFFECT_NEG`: negativo +- `EFFECT_BW`: escala de grises +- `EFFECT_RED`: rojizo +- `EFFECT_GREEN`: verdoso +- `EFFECT_BLUE`: azulado +- `EFFECT_RETRO`: sepia + +```python +# Ejemplo +camera.speffect(camera.EFFECT_NONE) +``` + +**whitebalance**, equilibra los niveles de los colores básicos (Rojo, Verde y Azul). + +- `WB_NONE`: sin compensación +- `WB_SUNNY`: compensa días soleados +- `WB_CLOUDY`: compensa días nublados +- `WB_OFFICE`: compensa iluminación fría +- `WB_HOME`: compensa iluminación cálida + +```python +# Ejemplo +camera.whitebalance(camera.WB_NONE) +``` + +**capture**, captura una imagen. + +```python +# Ejemplo +img = camera.capture() +``` + +## Ejemplo de captura + +`capture.py` permite capturar una foto 640*480 y almacenarla en PSRAM. + +![Captura](./IMG1.jpg) + ## Recursos - [Aprende a programar la ESP32-CAM en Micropython. Parte 1](https://www.profetolocka.com.ar/2022/04/18/aprende-a-programar-la-esp32-cam-en-micropython-parte-1/) - [Aprende a programar la ESP32-CAM en Micropython. Parte 2](https://www.profetolocka.com.ar/2022/04/25/aprende-a-programar-la-esp32-cam-en-micropython-parte-2/) - [ESP32 CAM introducción y primeros pasos](https://programarfacil.com/esp32/esp32-cam/) -- [ESP32-CAM: Machine Vision Tips, Camera Guides and Projects](https://www.arducam.com/esp32-machine-vision-learning-guide/) +- [ESP32-CAM: Machine Vision Tips, Camera Guides and Projects](https://www.arducam.com/esp32-machine-vision-learning-guide/) \ No newline at end of file diff --git a/dispositivos/esp32-cam/capture.py b/dispositivos/esp32-cam/capture.py index c5bb625..b17e3d3 100644 --- a/dispositivos/esp32-cam/capture.py +++ b/dispositivos/esp32-cam/capture.py @@ -1,22 +1,43 @@ -# Código para Capturar una Imagen -# https://lemariva.com/blog/2020/06/micropython-support-cameras-m5camera-esp32-cam-etc +# Captura de fotos con ESP32CAM +# Creado el 7 de junio de 2024 -import esp -import machine -import time import camera +import machine +from time import sleep -# Inicializar la cámara -camera.init(0, format=camera.JPEG) +flash = machine.Pin(4, machine.Pin.OUT) -# Capturar una imagen -buf = camera.capture() +foto_count = 1 -# Guardar la imagen en un archivo -#with open("captura.jpg", "wb") as f: -# f.write(buf) +while (True): + + nombre = "IMG"+str(foto_count)+".jpg" + print(nombre) + + try: + camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM) + camera.framesize(camera.FRAME_VGA) -print("Imagen guardada como captura.jpg") + flash.value(1) + sleep (0.5) -# Finalizar la cámara -camera.deinit() + # Captura la imagen + img = camera.capture() + print("Tamaño=",len(img)) + + flash.value(0) + camera.deinit () + + # Guardar la imagen en el sistema de archivos + imgFile = open(nombre, "wb") + imgFile.write(img) + imgFile.close() + + foto_count += 1 + + sleep (10) + + except Exception as err: + + print("Error= "+str (err)) + sleep(2) \ No newline at end of file diff --git a/dispositivos/esp32-cam/process.py b/dispositivos/esp32-cam/process.py index 4c0470f..97ca407 100644 --- a/dispositivos/esp32-cam/process.py +++ b/dispositivos/esp32-cam/process.py @@ -1,7 +1,7 @@ # Detección de Colores con MicroPython # -# Para realizar la detección de colores, puedes usar técnicas básicas de procesamiento -# de imágenes. Aquí hay un ejemplo simple para detectar un color específico en la imagen. +# Para realizar la detección de colores, podes usar técnicas básicas de procesamiento +# de imágenes. Este ejemplo permite detectar un color específico en la imagen. # Capturar y Procesar la Imagen: import esp