Saltar a contenido

Detección

Detección de bordes

# Detección de bordes con Canny:
#
# Este ejemplo muestra el detector de bordes Canny

import sensor, image, time

sensor.reset() # Inicializar el sensor
sensor.set_pixformat(sensor.GRAYSCALE) # o sensor.RGB565
sensor.set_framesize(sensor.QQVGA) # o sensor.QVGA (u otros)
sensor.skip_frames(time = 2000) # Confirma los nuevos ajustes

clock = time.clock() # Controla los FPS
while(True):
    clock.tick() # Seguimiento de los milisegundos transcurridos entre instantáneas
    img = sensor.snapshot() # Toma una foto y devuelve la imagen
    # Uso del detector de bordes Canny
    # img.find_edges(image.EDGE_CANNY, threshold=(50, 80))
    # Detección de bordes más rápida y sencilla
    img.find_edges(image.EDGE_SIMPLE, threshold=(100, 255))
    print(clock.fps()) # CanMV Cam funciona aproximadamente a la mitad de velocidad mientras tanto

Descargar el programa detec_bordes.py

Búsqueda de círculos

# Búsqueda de círculos
#
# Este ejemplo muestra cómo buscar círculos en la imagen utilizando la transformada de Hough
# https://en.wikipedia.org/wiki/Circle_Hough_Transform
#
# Ten en cuenta que el método find_circles() solo encontrará círculos que estén completamente
# dentro de la imagen. Los círculos que se salen de la imagen se ignoran...
import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # La escala de grises es más rápida.
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot().lens_corr(1.8)

    # Los objetos circulares tienen cuatro valores: x, y, r (radio) y magnitud. La
    # magnitud es la magnitud de la detección del círculo. Cuanto mayor sea,
    # mejor...

    # `threshold` controla cuántos círculos se encuentran. Aumenta su valor
    # para disminuir el número de círculos detectados...

    # `x_margin`, `y_margin` y `r_margin` controlan la fusión de círculos similares
    # en las direcciones x, y y r (radio).

    # r_min, r_max y r_step controlan qué radios de círculos se prueban.
    # Reducir el número de radios de círculos probados produce un gran aumento del rendimiento.

    for c in img.find_circles(threshold = 2000, x_margin = 10, y_margin = 10, r_margin = 10,
            r_min = 2, r_max = 100, r_step = 2):
        img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))

        print(c)

    print("FPS %f" % clock.fps())

Descargar el programa Busqueda_círculos.py

Ecua

Buscar líneas
#
# Este ejemplo muestra cómo buscar líneas en la imagen. Por cada objeto de línea
# encontrado en la imagen, se devuelve un objeto de línea que incluye la rotación de la línea.

# Nota: La detección de líneas se realiza mediante la transformada de Hough:
# http://en.wikipedia.org/wiki/Hough_transform

# find_lines() encuentra líneas de longitud infinita. Utiliza find_line_segments() para
# encontrar líneas no infinitas.

enable_lens_corr = False # Activar para líneas más rectas...

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # La escala de grises es más rápida
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

# Todas las línea tienen un método `theta()` para obtener su ángulo de rotación en grados.
# Puedes filtrar las líneas según su ángulo de rotación.

min_degree = 0
max_degree = 179

# Todas las líneas también tienen métodos `x1()`, `y1()`, `x2()` y `y2()` para obtener sus
# puntos finales, y un método `line()` para obtener todos los valores anteriores como una
# tupla de 4 valores para `draw_line()`

while(True):
    clock.tick()
    img = sensor.snapshot()
    if enable_lens_corr: img.lens_corr(1.8) # para lentes de 2,8 mm...

    # El `umbral` controla cuántas líneas se encuentran en la imagen. Solo se detectan las
    # líneas con sumas de magnitud de diferencia de bordes superiores al `umbral`...

    # Más información sobre el `umbral`: cada píxel de la imagen aporta un valor de magnitud
    # a una línea. La suma de todas las contribuciones es la magnitud de esa línea. Luego,
    # cuando se fusionan las líneas, sus magnitudes se suman. Tenga en cuenta que `threshold`
    # filtra las líneas con magnitudes bajas antes de fusionarlas. Para ver la magnitud de
    # las líneas no fusionadas, establezca `theta_margin` y `rho_margin` en 0...

    # `theta_margin` y `rho_margin` controlan la fusión de líneas similares. Si las diferencias
    # entre los valores theta y rho de dos líneas son menores que los márgenes, entonces se fusionan.

    for l in img.find_lines(threshold = 1000, theta_margin = 25, rho_margin = 25):
        if (min_degree <= l.theta()) and (l.theta() <= max_degree):
            img.draw_line(l.line(), color = (255, 0, 0))
            # print(l)

    print("FPS %f" % clock.fps())

# Acerca de los valores rho negativos:
#
# Una tupla [theta+0:-rho] es igual que [theta+180:+rho].

Descargar el programa Buscar_lineas.py

Buscar rectángulos

# Buscar rectángulos
#
# Este ejemplo muestra cómo encontrar rectángulos en la imagen utilizando el código de detección
# de umbral cuádruple del código de etiquetas de April. El algoritmo de detección de umbral
# cuádruple detecta rectángulos de una manera extremadamente robusta y es mucho mejor que los
# métodos basados en la transformada de Hough. Por ejemplo, puede detectar rectángulos incluso
# cuando la distorsión de la lente hace que esos rectángulos parezcan curvados.
# ¡Los rectángulos redondeados no son ningún problema! (Pero, dado el caso, el código también
# detectará círculos de radio pequeño)...

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # La escala de grises es más rápida (160 x 120 como máximo en CanMV-M7)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()

    # El `umbral` siguiente debe establecerse en un valor lo suficientemente alto como para
    # filtrar el ruido.
    # Rectángulos detectados en la imagen que tienen magnitudes de borde bajas. Los rectángulos
    # tienen magnitudes de borde mayores cuanto más grandes y contrastados son...

    for r in img.find_rects(threshold = 10000):
        img.draw_rectangle(r.rect(), color = (255, 0, 0))
        for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
        print(r)

    print("FPS %f" % clock.fps())

Descargar el programa Buscar_rectangulos.py

Regresión lineal rápida

# Regresión lineal rápida
#
# Este ejemplo muestra cómo utilizar el método get_regression() en la cámara conectada a CanMV
# para obtener la regresión lineal de una región de interés (ROI). Con este método, puedes
# construir fácilmente  un robot capaz de seguir líneas que apuntan en la misma dirección
# pero que en realidad no están conectadas. Utilza find_blobs() en líneas que estén conectadas
# para obtener mejores opciones de filtrado y control.
#
# Se denomina regresión lineal rápida porque utilizamos el método de mínimos cuadrados para ajustar
# la línea. Sin embargo, este método NO ES ADECUADO PARA IMÁGENES que tengan muchos puntos atípicos
# (o realmente ninguno) que distorsionen el ajuste de la línea...

THRESHOLD = (0, 100) # Umbral de escala de grises para objetos oscuros...
BINARY_VISIBLE = True # Primero hazlo binario para que puedas ver en qué se está ejecutando la
                      # regresión lineal... aunque puede que baje los FPS.

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot().binary([THRESHOLD]) if BINARY_VISIBLE else sensor.snapshot()

    # Devuelve un objeto de línea similar a los objetos de línea devueltos por find_lines() y
    # find_line_segments(). Dispone de x1(), y1(), x2(), y2(), length(), theta() (rotación en grados),
    # rho() y magnitude().
    #
    # magnitude() representa lo bien que ha funcionado la regresión lineal. Va de (0, INF],
    # donde 0 se devuelve para un círculo. Cuanto más lineal sea la escena, mayor será la magnitud.

    line = img.get_regression([(255,255) if BINARY_VISIBLE else THRESHOLD])

    if (line): img.draw_line(line.line(), color = 127)
    print("FPS %f, mag = %s" % (clock.fps(), str(line.magnitude()) if (line) else "N/A"))

# Acerca de los valores rho negativos:
#
# Una tupla [theta+0:-rho] es igual que [theta+180:+rho].

Descargar el programa Regres_lineal_rapida.py

Regresión lineal robusta

# Regresión lineal robusta
#
# Este ejemplo muestra cómo utilizar el método get_regression() en su cámara CanMV para obtener
# la regresión lineal de una región de interés (ROI). Con este método, puedes
# construir fácilmente  un robot capaz de seguir líneas que apuntan en la misma dirección
# pero que en realidad no están conectadas. Utilza find_blobs() en líneas que estén conectadas
# para obtener mejores opciones de filtrado y control.
#
# En este script utilizamos el argumento robust=True para get_regression(), que calcula la
# regresión lineal utilizando un algoritmo mucho más robusto, pero potencialmente mucho más
# lento. El algoritmo robusto se ejecuta en tiempo O(N^2) en la imagen. Por lo tanto, DEBES
# LIMITAR EL NÚMERO DE PÍXELES sobre los que trabaja el algoritmo robusto o, de lo contrario,
# el algoritmo puede tardar segundos en dar un resultado... ¡ESTABLECE EL UMBRAL CON MUCHO CUIDADO!

THRESHOLD = (0, 100) # Umbral de escala de grises para objetos oscuros...
BINARY_VISIBLE = True # Primero hazlo binario para que puedas ver en qué se está ejecutando la
                      # regresión lineal... aunque puede que baje los FPS.

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQQVGA) # 80 x 60 (4800 píxeles) - O(N^2) máx. = 2304000.
sensor.skip_frames(time = 2000)     # ADVERTENCIA: Si utiliza QQVGA, en ocasiones el
clock = time.clock()                # procesamiento de un fotograma puede tardar unos segundos.

while(True):
    clock.tick()
    img = sensor.snapshot().binary([THRESHOLD]) if BINARY_VISIBLE else sensor.snapshot()

    # Devuelve un objeto de línea similar a los objetos de línea devueltos por find_lines() y
    # find_line_segments(). Dispone de x1(), y1(), x2(), y2(), length(), theta() (rotación en
    # grados), rho() y magnitude().
    #
    # magnitude() representa lo bien que ha funcionado la regresión lineal. Significa algo
    # diferente para la regresión lineal robusta. En general, cuanto mayor sea el valor, mejor...
    line = img.get_regression([(255,255) if BINARY_VISIBLE else THRESHOLD], robust = True)

    if (line): img.draw_line(line.line(), color = 127)
    print("FPS %f, mag = %s" % (clock.fps(), str(line.magnitude()) if (line) else "N/A"))

# Acerca de los valores rho negativos:
#
# Una tupla [theta+0:-rho] es igual que [theta+180:+rho].

Descargar el programa Regres_lineal_robusta.py