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)