Saltar a contenido

Comparación de imágenenes

Diferenciación básica de fotogramas

# Ejemplo de diferenciación basica de fotogramas
#
# Este ejemplo muestra cómo utilizar la diferenciación de fotogramas con la cámara CanMV.
# Se denomina diferencia de fotogramas básica porque no hay actualización de la imagen de fondo.
# Por lo tanto, con el paso del tiempo, la imagen de fondo puede cambiar y provocar problemas.

import sensor, image, os, time

TRIGGER_THRESHOLD = 5

sensor.reset() # Inicializa el sensor
sensor.set_pixformat(sensor.RGB565) # o sensor.RGB565
sensor.set_framesize(sensor.QVGA) # o sensor.QQVGA (u otros)
sensor.skip_frames(time = 2000) # Hace que los nuevos ajustes surtan efecto
sensor.set_auto_whitebal(False) # Desactiva el balance de blancos
clock = time.clock() # Rastrea los FPS

# Toma del bufer de la RAM un fotograma para asignar un segundo búfer de fotogramas.
# Hay mucha más RAM en el búfer de fotogramas que en la pila de MicroPython.
# Sin embargo, después de hacer esto, tendrás mucha menos RAM para algunos algoritmos...
# Por lo tanto, ten en cuenta que ahora es mucho más fácil evitar problemas de RAM.
# Sin embargo, la diferenciación de fotogramas no utiliza mucho del espacio adicional en
# el búfer de fotogramas.
# Pero cosas como AprilTags sí lo hacen y no funcionarán si haces esto...
# extra_fb = sensor.alloc_extra_fb(sensor.width(), sensor.height(), sensor.RGB565)

extra_fb = image.Image(size=(sensor.width(), sensor.height()))

print("A sólo unos segundos de guardar la imagen de fondo...")
sensor.skip_frames(time = 2000) # Dale tiempo al usuario para prepararse
# extra_fb.replace(sensor.snapshot())
extra_fb.draw_image(sensor.snapshot(), 0, 0)
print("Imagen de fondo guardada: ¡ahora se calcula la diferencia entre fotogramas!")

while(True):
    clock.tick() # Sigue los milisegundos transcurridos entre instantáneas (snapshots)
    img = sensor.snapshot() # Toma una foto y devuelve la imagen

    # Reemplaza la imagen con la diferencia de fotogramas "abs(NEW-OLD)"
    img.difference(extra_fb)

    hist = img.get_histogram()
    # El siguiente código funciona comparando el valor del percentil 99 (por ejemplo, el valor máximo
    # no atípico) con el valor del percentil 90 (por ejemplo, un valor no máximo). La diferencia entre
    # los dos valores aumentará a medida que la imagen de diferencia parezca cambiar más píxeles.

    diff = hist.get_percentile(0.99).l_value() - hist.get_percentile(0.90).l_value()
    triggered = diff > TRIGGER_THRESHOLD

    print(clock.fps(), triggered)

Descargar el programa dif_basica_fotogramas.py

Diferenciación avanzada de fotogramas

# Ejemplo de diferenciación avanzada de fotogramas
#
# Este ejemplo muestra cómo utilizar la diferenciación de fotogramas con la cámara CanMV.
# Realiza una actualización del fondo para gestionar los cambios que se producen en la imagen
# de fondo con el paso del tiempo.


import sensor, image, os, time

TRIGGER_THRESHOLD = 5

BG_UPDATE_FRAMES = 50 # Cuántos fotogramas antes de la mezcla
BG_UPDATE_BLEND = 128 # Cuánto mezclar

sensor.reset() # Inicializa el sensor
sensor.set_pixformat(sensor.RGB565) # o sensor.RGB565
sensor.set_framesize(sensor.QVGA) # o sensor.QQVGA (u otros)
sensor.skip_frames(time = 2000) # Hace que los nuevos ajustes surtan efecto
sensor.set_auto_whitebal(False) # Desactiva el balance de blancos
clock = time.clock() # Rastrea los FPS

# Toma del bufer de la RAM un fotograma para asignar un segundo búfer de fotogramas.
# Hay mucha más RAM en el búfer de fotogramas que en la pila de MicroPython.
# Sin embargo, después de hacer esto, tendrás mucha menos RAM para algunos algoritmos...
# Por lo tanto, ten en cuenta que ahora es mucho más fácil evitar problemas de RAM.
# Sin embargo, la diferenciación de fotogramas no utiliza mucho del espacio adicional en
# el búfer de fotogramas.
# Pero cosas como AprilTags sí lo hacen y no funcionarán si haces esto...
# extra_fb = sensor.alloc_extra_fb(sensor.width(), sensor.height(), sensor.RGB565)

extra_fb = image.Image(size=(sensor.width(), sensor.height()))

print("A sólo unos segundos de guardar la imagen de fondo...")
sensor.skip_frames(time = 2000) # Dale tiempo al usuario para prepararse
#extra_fb.replace(sensor.snapshot())
extra_fb.draw_image(sensor.snapshot(), 0, 0)
print("Imagen de fondo guardada: ¡ahora se calcula la diferencia entre fotogramas!")

triggered = False

frame_count = 0
while(True):
    clock.tick() # Sigue los milisegundos transcurridos entre instantáneas (snapshots)
    img = sensor.snapshot() # Toma una foto y devuelve la imagen

    frame_count += 1
    if (frame_count > BG_UPDATE_FRAMES):
        frame_count = 0
        # Mezclar en el nuevo fotograma. Aquí estamos utilizando 256-alfa porque queremos mezclar
        # el nuevo fotograma con el fondo. No el fondo con el nuevo fotograma, que sería solo alfa.
        # La mezcla sustituye cada píxel por ((NUEVO*(alfa))+(ANTIGUO*(256-alfa)))/256. Por lo tanto,
        # un alfa bajo da como resultado una mezcla baja de la nueva imagen, mientras que un alfa alto
        # da como resultado una mezcla alta de la nueva imagen. Necesitamos invertir eso para esta
        # actualización.
        img.blend(extra_fb, alpha=(256-BG_UPDATE_BLEND))
        extra_fb.replace(img)

    # Reemplaza la imagen con la diferencia de fotogramas "abs(NEW-OLD)"
    img.difference(extra_fb)

    hist = img.get_histogram()
    # El siguiente código funciona comparando el valor del percentil 99 (por ejemplo, el valor máximo
    # no atípico) con el valor del percentil 90 (por ejemplo, un valor no máximo). La diferencia entre
    # los dos valores aumentará a medida que la imagen de diferencia parezca cambiar más píxeles.

    diff = hist.get_percentile(0.99).l_value() - hist.get_percentile(0.90).l_value()
    triggered = diff > TRIGGER_THRESHOLD

    print(clock.fps(), triggered)

Descargar el programa dif_avanzada_fotogramas.py

Similitud estructural (SSIM)

# Similitud estructural (SSIM)
#
# Este ejemplo muestra cómo utilizar el algoritmo SSIM para detectar diferencias entre dos imágenes.
# El algoritmo SSIM compara bloques de píxeles de 8x8 entre dos imágenes para determinar un
# grado de similitud entre ambas.

import sensor, image, os, time

# Es probable que la imagen haya cambiado si sim.min() es inferior a este valor
MIN_TRIGGER_THRESHOLD = -0.4

sensor.reset() # Inicializa el sensor
sensor.set_pixformat(sensor.RGB565) # o sensor.GRAYSCALE
sensor.set_framesize(sensor.QVGA) # o sensor.QQVGA (u otros)
sensor.skip_frames(time = 2000) # Hace que los nuevos ajustes surtan efecto
sensor.set_auto_whitebal(False) # Desactiva el balance de blancos
clock = time.clock() # Rastrea los FPS

# Toma del bufer de la RAM un fotograma para asignar un segundo búfer de fotogramas.
# Hay mucha más RAM en el búfer de fotogramas que en la pila de MicroPython.
# Sin embargo, después de hacer esto, tendrás mucha menos RAM para algunos algoritmos...
# Por lo tanto, ten en cuenta que ahora es mucho más fácil evitar problemas de RAM.
# Sin embargo, la diferenciación de fotogramas no utiliza mucho del espacio adicional en
# el búfer de fotogramas.
# Pero cosas como AprilTags sí lo hacen y no funcionarán si haces esto...
# extra_fb = sensor.alloc_extra_fb(sensor.width(), sensor.height(), sensor.RGB565)

extra_fb = image.Image(size=(sensor.width(), sensor.height()))

print("A sólo unos segundos de guardar la imagen de fondo...")
sensor.skip_frames(time = 2000) # Dale tiempo al usuario para prepararse
# extra_fb.replace(sensor.snapshot())
extra_fb.draw_image(sensor.snapshot(), 0, 0)
print("¡Imagen de fondo guardada!")

while(True):
    clock.tick() # Sigue los milisegundos transcurridos entre instantáneas (snapshots)
    img = sensor.snapshot() # Toma una foto y devuelve la imagen
    sim = img.get_similarity(extra_fb)
    change = "- Cambio -" if sim.min() < MIN_TRIGGER_THRESHOLD else "- Sin cambio -"

    print(clock.fps(), change, sim)

Descargar el programa Similitud_estructural.py