Aprende a programar la ESP32-CAM en Micropython. Parte 2

En la primera parte de este tutorial destinado a aprender a utilizar la ESP32-CAM en Micropython te expliqué como grabar un custom firmware en la placa. En esta segunda entrega veremos en detalle los objetos y métodos que agrega este firmware y que nos permiten tener acceso a las funciones de la cámara.

Control de la cámara

Una vez que tenemos el firmware instalado en nuestra ESP32-CAM podemos comenzar a programarla desde Micropython. (La instalación del firmware está explicada en este artículo anterior)

El primer paso es importar el módulo camera que incluye un objeto del mismo nombre que cuenta con 12 métodos para configurar la cámara y capturar imágenes.

Estos métodos son los siguientes:

  • init
  • deinit
  • flip
  • mirror
  • framesize
  • quality
  • contrast
  • saturation
  • brightness
  • speffect
  • whitebalance
  • capture

Veamos a continuación cada uno de ellos en detalle

init

Método: init

Activa e inicializa la cámara

Formato: camera.init (0, parámetro=valor, …)

Los parámetros aceptados en init son los siguientes, con sus valores posibles entre corchetes.

xclk_freq_hz: Frecuencia de reloj de la cámara en Hz. [10000000, 20000000 ]

frame_size: Tamaño de la imagen capturada (ver método framesize mas abajo)

pixel_format: Formato de la imagen capturada [JPEG, YUV422, GRAYSCALE, RGB565]

jpeg_quality: Calidad de la imagen capturada [10..63]. Los valores menores representan mayor calidad

fb_location: Ubicación de la imagen capturada [DRAM, PSRAM]. Es conveniente usar PSRAM.

Ejemplo:

camera.init (0, format=camera.JPEG, fb_location=camera.PSRAM)

deinit

Método: deinit ()

Desactiva la cámara

Parámetros:

No tiene

Ejemplo:

camera.deinit ()

flip

Método: flip (orientación)

Cambia la orientación vertical de la imagen

Parámetros:

Orientación = 0 > Imagen normal

Orientación = 1 > Imagen invertida

Ejemplo:

camera.flip (0) #Sin invertir

mirror

Método: mirror (orientación)

Cambia la orientación horizontal de la imagen

Parámetros:

Orientación = 0 > Imagen normal

Orientación = 1 > Imagen invertida

Ejemplo:

camera.mirror (1) #Invertida

framesize

Método: framesize (tamaño)

Especifica el tamaño y resolución de la imagen capturada

Parámetros:

tamaño debe tener alguno de los siguientes valores:

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

Ejemplo:

camera.framesize (camera.FRAME_CIF)

quality

Método: quality (calidad)

Especifica la calidad de la imagen capturada.

Parámetros:

calidad puede variar entre 10 (calidad alta) y 63 (calidad baja)

Ejemplo:

camera.quality (10)

contrast

Método: contrast (contraste)

Especifica el contraste de la imagen

Parámetros:

contraste puede variar entre -2 (contraste bajo) y 2 (contraste alto). Por omisión vale 0.

Ejemplo:

camera.contrast (1)

saturation

Método: saturation (saturación)

Especifica la saturación (intensidad de los colores) de la imagen

Parámetros:

saturación puede variar entre -2 (baja intensidad) y 2 (alta intensidad). Por omisión vale 0.

Ejemplo:

camera.saturation (-1)

brightness

Método: brightness (brillo)

Especifica el brillo de la imagen

Parámetros:

brillo puede variar entre -2 (mas bajo) y 2 (mas alto). Por omisión vale 0.

Ejemplo:

camera.brightness (1)

speffect

Método: speffect (efecto)

Aplica un efecto a la imagen

Parámetros:

efecto puede ser uno de los siguientes:

EFFECT_NONE (por omisión)

EFFECT_NEG = negativo

EFFECT_BW = ByN (escala de grises)

EFFECT_RED = Rojizo

EFFECT_GREEN = Verdoso

EFFECT_BLUE = Azulado

EFFECT_RETRO = Sepia

Ejemplo:

camera.speffect (camera.EFFECT_NONE)

whitebalance

Método: whitebalance (modo)

Equilibra los niveles de los colores básicos (Rojo, Verde y Azul).

Parámetros:

modo puede ser uno de los siguientes:

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

Ejemplo:

camera.whitebalance (camera.WB_NONE)

capture

Método: capture ()

Captura una imagen

Parámetros:

No tiene.

Ejemplo:

img = camera.capture()

Programa

El siguiente es un ejemplo sencillo que toma imágenes cada 10 segundos y las almacena como archivos en la memoria Flash del ESP32. Es una modificación del programa de ejemplo que se puede encontrar en el repositorio del firmware.

Como se puede ver, en las líneas 1, 2 y 3 se importan los módulos necesarios, empezando por camera.

En la línea 7 se define led en el pin 4, donde está conectado el flash de la cámara.

En la línea 9 se inicializa la variable foto a 1, para contar las imágenes que se van capturando e incluirlo en el nombre del archivo cuando las mismas se graben en la memoria.

A continuación, en la línea 11 se inicia un bucle para capturar las imágenes cada 10 segundos. Lo primero es generar el nombre del archivo que se va a guardar como “Capx.jpg” donde x será reemplazado por el valor de la variable foto.

Luego desde la línea 15, dentro de un bloque try se hace la inicialización y configuración de la cámara y luego la captura de la imagen (línea 50).

import camera
from time import sleep
import machine


#Pin del led de flash
led = machine.Pin(4, machine.Pin.OUT)

foto=1

while (True):
    nombre = "Cap"+str(foto)+".jpg"
    print (nombre)
    
    try:
        camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM)
        
        #Establece el brillo
        camera.brightness(-1)
        
        #Orientacion normal
        camera.flip(0)

        #Orientación normal
        camera.mirror (0)
        
        #Resolución
        camera.framesize(camera.FRAME_XGA)

        #contraste
        camera.contrast(2)
        
        #saturacion
        camera.saturation (-2)
               
        #calidad
        camera.quality(10)
        
        # special effects
        camera.speffect(camera.EFFECT_NONE)
         
        # white balance
        camera.whitebalance(camera.WB_NONE)
        
        #Enciende flash
        #led.value(1)
        sleep (0.5)
        
        #Captura la imagen
        img = camera.capture()
        print ("Tamaño=",len(img))
        
        
        #Apaga flash
        led.value(0)
        
        #desactivar cámara
        camera.deinit ()
       
        #Guardar la imagen en el sistema de archivos
        imgFile = open(nombre, "wb")
        imgFile.write(img)
        imgFile.close()
        
        foto+=1
        
        sleep (10)
        
    except Exception as err:
    
        print ("Error= "+str (err))
        sleep (2)
        
   

En la línea 46 está comentado el encendido del flash. Si lo necesitas debes descomentar esta línea.

El print de la línea 51 muestra el tamaño de la imagen. Este programa está pensado sólo como un ejemplo del uso de los métodos de la cámara y por esta razón las imágenes se graban en la flash del ESP32 y no en la tarjeta SD. La idea es tomar unas pocas imágenes y descargarlas luego a una computadora para verlas, y no que funcione como un time lapse, por ejemplo. Si tomas muchas imágenes (depende de la resolución) puede que obtengas un Error 28 (memoria llena).

Usando Thonny es muy fácil descargar las imágenes a la computadora. Debes activar la visualización de los archivos, hacer click derecho sobre la imagen que quieras descargar y seleccionar Descargar a (carpeta).

Fig. 1: Descarga de una imagen a la computadora

Siguiendo con el análisis del programa de ejemplo, en las líneas 61, 62 y 63 se graba la imagen en la memoria como un archivo binario. Si quieres puedes aprender como trabajar con este tipo de archivos en este artículo anterior.

En la línea 65 se incrementa el contador de imágenes y en la 67 se realiza el retardo de 10 segundos.

Si hubiera algún error dentro del bloque try, desde la línea 69 se captura el error en el bloque exception donde se muestra el mensaje del error producido y se espera 2 segundos.

Ejemplos y observaciones

Las siguientes son algunas imágenes de ejemplo tomadas con distintas configuraciones, calidades y resoluciones.

No es fácil obtener imágenes de buena calidad. Las variaciones de iluminación entre ambientes abiertos y cerrados hace necesario ajustar los distintos parámetros de configuración de la cámara, como brillo, contraste o saturación.

A mayor tamaño de imagen es necesaria una mayor iluminación. En interiores se obtienen mejores resultados con resoluciones bajas.

No se pueden lograr simultáneamente resoluciones altas y calidad de imagen alta. Si se aumenta la resolución, sobre todo en los valores mas elevados, hay que comenzar a disminuir la calidad. Por ejemplo en formato XGA se puede tener la calidad mas alta (el valor de 10) pero en SXGA la calidad debe disminuirse (un valor de 20) y mas aún en UXGA (un valor de 30).

En exteriores es habitual que las imágenes contengan zonas “quemadas” es decir blancas debido a la cantidad de luz. Tal vez esto podria evitarse reduciendo el tiempo de exposición, pero esta función no esta disponible en este firmware.

Si bien el firmware admite valores de resolución muy elevados, con mi ESP32-CAM con una cámara OV2640, siempre obtuve error para valores superiores a UXGA (1600*1200 = 1.8 MPx). Los valores de resolución mayores tal vez estén reservados para otros modelos de cámara.

Conclusión

El firmware de lemariva nos permite programar la ESP32-CAM en Micropython y pone a nuestra disposición una serie de métodos para controlar las funciones mas comunes de la cámara de una forma sumamente sencilla. En este artículo te mostré como utilizar cada uno de ellos y como emplearlos en un ejemplo sencillo que toma imágenes con la cámara a intervalos de tiempo regulares. Esta es una base que puede emplearse para proyectos mucho mas ambiciosos y complejos. En otros artículos iré compartiendo mas ideas y mas aplicaciones de esta interesante placa, siempre programados en Micropython.

Cualquier duda o sugerencia, puedes dejarla en la sección de comentarios. Hasta la próxima!

Más info

Completa información de la ESP32-CAM

4 comentarios en «Aprende a programar la ESP32-CAM en Micropython. Parte 2»

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: