Contar objetos es contar regiones conectadas
Contar objetos en una imagen es contar los grupos de píxeles que están pegados entre sí, y cada grupo se llama región conectada. Así cuenta un cajero automático las monedas de euro que le metes, y así localiza una pieza una cámara de fábrica.
Hoy cuentas regiones a mano y miras cómo lo hace el laboratorio con nueve monedas.
Al final de esta lección
Nota
Puedo contar los objetos de una imagen y decir dónde está cada uno.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Región conectada | un grupo de píxeles de objeto pegados entre sí |
| Vecindad | qué píxeles cuentan como vecinos: 4 u 8 |
| Etiquetado | dar un número distinto a cada región |
| Área | el número de píxeles de una región |
| Plantilla | un trozo de imagen que se busca en otra |
| Puntuación | cuánto se parece un sitio a la plantilla |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una región conectada es un grupo de vecinos
Primero se hace una máscara con un umbral: los píxeles de objeto valen 1. Después se busca qué unos están pegados entre sí.
Un grupo de unos pegados es una región conectada. Cada región es un objeto, y el número de regiones es el número de objetos.
Ejemplo resuelto: cuatro vecinos u ocho
| Máscara | Con 4 vecinos | Con 8 vecinos |
|---|---|---|
| [[1, 0, 0], [0, 1, 0], [0, 0, 1]] | 3 regiones: las diagonales no se tocan | 1 región: las diagonales sí se tocan |
| [[1, 1], [0, 1]] | 1 región | 1 región |
| [[1, 0], [0, 0]] | 1 región | 1 región |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una lista de pendientes recorre la región
Para medir una región, parte de un píxel de objeto. Apunta sus vecinos de objeto en una lista de pendientes, y saca uno cada vez.
Cada píxel sacado suma 1 al tamaño y añade sus vecinos nuevos a la lista. Cuando no quedan pendientes, la región está completa. Una lista de ya vistos evita volver al mismo píxel.
El tamaño de una región
# Cuántos píxeles tiene la región que contiene un punto (4 vecinos).
picture = [
[1, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 0, 1, 0],
]
pending = [[0, 0]]
seen = [[0, 0]]
size = 0
while len(pending) > 0:
point = pending.pop()
size = size + 1
for step in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
r = point[0] + step[0]
c = point[1] + step[1]
inside = r >= 0 and r < 4 and c >= 0 and c < 5
if inside and picture[r][c] == 1 and [r, c] not in seen:
seen.append([r, c])
pending.append([r, c])
print("píxeles de la región:", size)
# Cambia el punto de partida (pending y seen) a [3, 0]. ¿Cuántos salen?
Un error muy común
Advertencia
Mucha gente cree que contar los píxeles blancos de la máscara cuenta los objetos. Cuenta superficie, no objetos: nueve monedas son 13.569 píxeles blancos. Para contar objetos hay que etiquetar las regiones. Una mota de ruido es una región de 1 píxel: filtra por área si no la quieres.
Qué cuenta el script de objetos del laboratorio
El script count.py etiqueta la máscara de coins.png con scikit-image. Imprime en inglés: objects found son los objetos encontrados y areas in pixels son las áreas ordenadas.
Salen 9 objetos, las nueve monedas dibujadas. Hay tres áreas: 657, 1.313 y 2.553 píxeles, tres monedas de cada. Esta función usa por defecto 8 vecinos.
Cuenta las monedas de la imagen
docker exec jupyter python3 steps/count.pySe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Suma de las nueve áreas
docker exec jupyter python3 -c "print(3 * 657 + 3 * 1313 + 3 * 2553)"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejemplo resuelto: las áreas de las nueve monedas
| Tamaño de moneda | Área de cada una | Cuántas | Píxeles en total |
|---|---|---|---|
| Pequeña | 657 | 3 | 1.971 |
| Mediana | 1.313 | 3 | 3.939 |
| Grande | 2.553 | 3 | 7.659 |
| Las tres juntas | 9 | 13.569 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una plantilla se busca deslizándola por la imagen
Para saber dónde está un objeto, se corta un trozo de la imagen como plantilla y se desliza por toda ella. En cada sitio se mide cuánto se parece.
Esa medida es la puntuación: 1 es idéntico y los valores bajos son distintos. El mejor sitio es donde la puntuación es mayor.
Qué cuenta el script de la plantilla
El script find.py corta un trozo de 40 por 40 píxeles de la esquina 30, 30 de coins.png y lo busca en la imagen entera. Imprime en inglés: best match starts at es dónde empieza el mejor sitio y match score es la puntuación.
Sale 30 30 con puntuación 1,0, porque el trozo sale de ahí mismo. Una plantilla busca un parecido exacto: si cambia el tamaño o el giro, la puntuación baja.
Busca un trozo dentro de la imagen
docker exec jupyter python3 steps/find.pySe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Para ir más lejos: tus propias monedas
Abre start.ipynb en JupyterLab y etiqueta la máscara de coins.png con otro umbral, por ejemplo 160. ¿Cuántos objetos salen ahora?
Después prueba la tarea con 8 vecinos en una cuadrícula de diagonales y compara con la de 4 vecinos.