Ir al contenido

P17 — Encontrar el centro de la línea en una fila de la imagen

Un programa encuentra una cinta negra en una fila de la imagen en escala de grises (0 = negro, 255 = blanco) con estas líneas:

umbral = fila.mean() * 0.7
pesos = np.maximum(0, umbral - fila)
centro_x = center_of_mass(pesos)[0]
centro_x = centro_x if not np.isnan(centro_x) else width // 2
error_x = width // 2 - centro_x

center_of_mass(pesos) calcula ∑ii wi∑iwi\dfrac{\sum_i i\,w_i}{\sum_i w_i}, donde ii es el número de la columna (desde 0) y wiw_i el peso; si todos los pesos son 0, da nan. Para simplificar, la imagen tiene solo 16 columnas (width = 16) y la fila es:

ii0123456789101112131415
valor180182178181179120403538110177183180179181178

Intensidad de cada columna de la fila

  1. Calcule el promedio de la fila y el umbral. ¿Qué columnas tienen peso distinto de cero y cuánto vale cada peso?
  2. Calcule centro_x y error_x. ¿La cinta está a la izquierda o a la derecha del centro de la imagen?
  3. Se apaga parte de la luz y todos los valores bajan a la mitad. Calcule de nuevo el umbral y centro_x. ¿Qué concluye sobre calcular el umbral con el promedio?
  4. Un compañero cambia la primera línea por umbral = 100, un número fijo. Con la luz a la mitad, ¿cuántas columnas quedan con peso distinto de cero? ¿Sigue distinguiendo la cinta del fondo?
  5. Se quita la cinta y todos los valores quedan entre 175 y 183. ¿Qué devuelve center_of_mass y qué error_x entrega el programa? ¿Qué hace el robot y qué riesgo tiene ese comportamiento?
Mostrar solución
  1. La suma es 2321 y el promedio 2321/16=145.062321/16 = 145.06. Umbral =0.7×145.06=101.54= 0.7 \times 145.06 = 101.54. Solo las columnas 6, 7 y 8 están por debajo: w6=101.54−40=61.54w_6 = 101.54 - 40 = 61.54, w7=66.54w_7 = 66.54, w8=63.54w_8 = 63.54. Las columnas 5 (120) y 9 (110) son borde de la cinta, pero quedan por encima del umbral.
  2. centro_x=6(61.54)+7(66.54)+8(63.54)61.54+66.54+63.54=1343.4191.6=7.01\text{centro\_x} = \dfrac{6(61.54) + 7(66.54) + 8(63.54)}{61.54 + 66.54 + 63.54} = \dfrac{1343.4}{191.6} = 7.01. error_x =8−7.01=0.99= 8 - 7.01 = 0.99 px. La cinta está un poco a la izquierda del centro de la imagen.
  3. Promedio 72.5372.53, umbral 50.7750.77. Siguen pasando solo las columnas 6, 7 y 8, con pesos 30.7730.77, 33.2733.27 y 31.7731.77, exactamente la mitad de antes, y centro_x=7.01\text{centro\_x} = 7.01: no cambia. Como el umbral es proporcional al promedio, si toda la fila se oscurece en la misma proporción, el umbral baja igual y el resultado no depende de la iluminación.
  4. Con la luz a la mitad, el fondo vale unos 90, que es menos que 100: las 16 columnas tienen peso. Los pesos del fondo son unos 10 y los de la cinta unos 80, así que el centro todavía da 7.22, pero el programa ya no está separando la cinta del fondo; si se quitara la cinta, reportaría una “línea” en la mitad de la imagen.
  5. El promedio es unos 179 y el umbral unos 125: ningún valor está por debajo, todos los pesos son 0, center_of_mass da nan y el programa usa width // 2 = 8. Entonces error_x = 0: el robot sigue derecho como si estuviera centrado sobre la línea. Es razonable para un hueco corto en la cinta, pero si la perdió de verdad (por ejemplo, en una curva cerrada) seguirá derecho sin buscarla. Convendría detectar ese caso y detenerse o girar a buscar la línea.