Módulo detector

Módulo detector Hough

Este módulo se ocupa del procesamiento de la imagen para la detección de segmentos, su anotación y su representación en el espacio de Hough.

Contiene 3 clases:

  • Segments: representa un conjunto de segmentos, con sus deltas, longitudes, distancias y ángulos.

  • SegmentsAnnotator: clase para dibujar segmentos sobre una imagen.

  • HoughSpace: clase para calcular el espacio de Hough y sus histogramas.

Status: - modificado para carril 7.py, que busca orientación y líneas de carril - adopta histograma 2D par par

class detector.HoughSpace(howManyAngleBins: int = 10, maxLanes: int = 4, howManyBinsInALane: int = 5, laneWidthInPixels: int = 210)

Clase para calcular el histograma denominado espacio de Hough.

shape(howManyAngleBins, howManyDistanceBins), par par

Ángulos: 0..pi (dos cuadrantes), 0 y pi son horizontales, pi/2 es vertical. Líneas longitudinates se encuentran en pi/4..3pi/4 (octantes 2 y 3).

Distancias: en píxeles, a la izquierda negativas, a la derecha positivas. Discontinuidad en ángulo 0 y pi (horizontal). Distancias positivas en ángulo 0 son negativas en ángulo pi.

__init__(howManyAngleBins: int = 10, maxLanes: int = 4, howManyBinsInALane: int = 5, laneWidthInPixels: int = 210)

Constructor Define la cantidad de bins, el factor de distancias y ángulos a los bins correspondientes. howManyAngleBins debe ser par si se quiere tener bins de ángulos perpendiculares. Los ángulos van de 0 a pi, 0 y pi son horizontales, pi/2 es vertical, giran en sentido horario. distanceBins: a la izquierda van las distancias negativas, a la derecha las positivas.

Arguments: - howManyAngleBins: número de bins para ángulos de 0 a pi, p/2 es vertical, se recomienda número par. - maxLanes: excursión (-maxLanes:+maxLanes) . - howManyBinsInALane: número de bins en un carril. - laneWidthInPixels: ancho de un carril en píxeles.

angle2index: float
angleHistogram: ndarray
angleIndices: ndarray
assign2Bins(segments: Segments)

Dos arrays paralelos de índices se crean a partir de los ángulos y distancias de los segmentos, apuntando a los bins correspondientes en el espacio de Hough. Se recortan, por lo que los valores fuera de rango se establecen en el valor válido más cercano. Esto afecta a distanceIndices, los últimos bins en ambos extremos agregarán todas las distancias mayores que maxDistanceInPixels.

centralAngleBin: int
centralDistanceBin: int
computeAngleHistogram() ndarray

Para cada ángulo, suma los bins de todos los lanes (las distancias). El resultado devuelto también se registra en self.angleHistogram. Requiere que self.houghSpace esté calculado.

Returns: - el histograma 1D de ángulos.

computeLaneHistogram(referenceAngleBin: int | None = None) ndarray

Computa y devuelve el histograma 1D de distancia, solo en el vecindario de referenceAngleBin. Lo registra en self.laneHistogram. El referenceAngleBin dado se registra en self.referenceAngleBin.

Arguments: - referenceAngleBin: el rango de ángulos de referencia.

Returns: - el histograma 1D de carriles.

El histograma resultante se le da la forma de vector columna, con [np.newaxis,:].

computeVotes(votes: ndarray) ndarray

Puebla el espacio de Hough. Votes es un array paralelo (del mismo tamaño que segments) con los votos para cada segmento. Si no quieres votos ponderados sino solo votos contados, puedes usar votes=1. También calcula el histograma 1D para ángulos y el histograma 1D para distancias cerca del bin de ángulo central.

Arguments: - votes: array de votos para cada segmento.

Returns: - el espacio de Hough.

distance2index: float
distanceIndices: ndarray
getIndicesFromBin(angleIndex: int, distanceIndex: int) ndarray

Devuelve los índices de los elementos en el bin que coinciden con los bins de ángulo y distancia dados.

Arguments: - angleIndex: el índice en rangos de ángulo. - distanceIndex: el índice en rangos de distancia.

Returns: - indices: array de índices de elementos en el bin.

getVisualization(scale: float = 0.0, showMax: bool = False) ndarray

Produce y devuelve una imagen de color mapeado del histograma 2D producido en computeVotes(), opcionalmente resaltando el pico si showMax es True.

Arguments: - scale: factor de escala para la imagen. - showMax: si se debe resaltar el pico.

Returns: - la visualización del espacio de Hough.

houghSpace: ndarray
howManyAngleBins: int = 10
howManyBinsInALane: int = 5
howManyDistanceBins: int
laneHistogram: ndarray
laneWidthInPixels: int = 210
maxLanes: int = 4
maxLoc: tuple
maxVal: float
pasteVisualization(image: ndarray, houghSpaceColor: ndarray | None = None, borderColor: tuple = (0, 128, 255), scale: float = 0.0, showMax: bool = False) ndarray

Pega la visualización del espacio de Hough sobre una imagen, en la esquina inferior derecha. Muestra histogramas 1D de ángulos y distancias. Decora con ejes y bordes si borderColor no es None. Se anota sobre la imagen provista.

Arguments: - image: la imagen para pegar la visualización. - borderColor: color para el borde. - scale: factor de escala para los histogramas. - showMax: si se debe resaltar el pico en la visualización. - houghSpaceColor: si se proporciona, se usa esta visualización en lugar de crear una nueva.

Returns: - houghSpaceColor: la visualización del espacio de Hough

Si se proporciona houghSpaceColor, se debe indicar la escala. Para más anotaciones, las coordenadas del espacio de Hough son -houghSpaceColor.shape[:2]

referenceAngleBin: int
class detector.LaneSensor(houghSpace: HoughSpace, fld: cv2.ximgproc.FastLineDetector, imSize: tuple, hui=None)

Esta clase produce y analiza HoughSpace y segmentos cenitales y en perspectiva, para determinar carriles, orientación y otros. La clase se puede interpretar como un sensor que extrae información del espacio de Hough.

El constructor inicializa objetos durables, y se actualiza (update) en cada bucle con la nueva imagen.

FLDT: float
H: ndarray
__init__(houghSpace: HoughSpace, fld: cv2.ximgproc.FastLineDetector, imSize: tuple, hui=None) None

Registra los objetos durables ya inicializados HoughSpace y FastLineDetector. Cuelga el listener afterRoi si se proporciona el objeto hui. Este constructor no define H, que se actualiza con afterRoi o se establece manualmente:

self.H = someHomographyMatrix

Arguments: houghSpace: objeto HoughSpace ya inicializado fld: objeto FastLineDetector ya inicializado hui: (opcional) objeto Hui para consultar limit y colgar el listener afterRoi que actualiza H

afterRoi(hui) None

Listener para colgar en Hui.afterRoi, para actualizar la homografía H cada vez que el usuario dispara su recómputo. Ejemplo de uso:

hui.afterRoi = laneSensor.afterRoi

Arguments: hui: objeto Hui con la propiedad Hview

No hace falta importar HUI

compass(lastVersor: ndarray | None = None) ndarray

Devuelve el versor de orientación alineado con el segmento más largo.

Arguments: lastVersor: versor de orientación anterior para observar cambios abruptos. No implementado.

Returns: np.ndarray: versor de orientación actual.

Guarda el versor en self.compassVersor.

compassVersor: ndarray
endOfLane() tuple

Detecta la línea de fin de carril en cada esquina, y mide la distancia. Es una línea perpendicular a las líneas de carril. Se buscan en el bin perpendicular al principal, más menos uno. Sólo si el carril fue detectado, de otro modo imprime una advertencia y retorna con datos nulos.

self.mainAngleBin es la dirección del carril.

Returns: tuple: (endOfLaneDetected:bool, endOfLaneDistance:float, endOfLaneIndex:int)

fld: cv2.ximgproc.FastLineDetector
hs: HoughSpace
hui: object
im: ndarray
imGray: ndarray
imSize: tuple
lane() tuple

Analiza el espacio de Hough buscando líneas de carril izquierda y derecha.

Returns: - leftLaneDetected: bool indicando si se detectó la línea de carril izquierda. - rightLaneDetected: bool indicando si se detectó la línea de carril derecha. - centralLaneAngle: ángulo promedio de la línea de carril central, en radianes, con respecto a la horizontal, positivo en sentido horario. - centralLaneDistance: distancia promedio de la línea de carril central, en píxeles, con signo (negativa a la izquierda, positiva a la derecha).

maxAngleHistogramIndex: int
perspectives: Segments
update(im: ndarray) bool

Recibe la imagen y extrae segmentos. Produce: - self.perspectives: segmentos detectados en perspectiva, con sus propiedades calculadas. - self.zenithals: segmentos proyectados a cenital, con sus propiedades calculadas. - self.hs: espacio de Hough actualizado con los segmentos proyectados a cenital

Arguments: im: imagen en perspectiva para procesar

Returns: bool: True si se detectaron segmentos, False en caso contrario.

zenithals: Segments
class detector.Segments(segs: Segments | ndarray | None = None, referencePoint: tuple | ndarray | None = None)

El objeto Segments representa un conjunto de líneas (segmentos rectos), almacenados en la propiedad coords, como un array de segmentos. Cada segmento es un par de puntos 2D. Todos los arrays son ndarray con dimensión principal de n.

Propiedades de Segments:

n: número de segmentos referencePoint: punto 2D, origen para el cálculo de la distancia de Hough;

es un ndarray de 2 elementos float.

ndarray de n filas: coords: ndarray de segmentos detectados [n,2,2], indefinido en un objeto vacío, se define una vez y no debería cambiar deltas: (dx,dy) lengths: longitudes de los segmentos distances: distancias de Hough al punto de referencia angles: ángulos de los segmentos normalUnityVectors: vectores unitarios normales a los segmentos

__init__(segs: Segments | ndarray | None = None, referencePoint: tuple | ndarray | None = None)

Constructor

Parámetros:
  • segs (np.ndarray or Segments or None) – Los segmentos para poblar el objeto. - Si segs es un ndarray de numpy, es una lista de segmentos de FLD con forma (n, 1, 4) donde n es el número de segmentos. - Si segs es una instancia de Segments, copiará los segmentos del objeto Segments dado. - Si segs es None, se creará un objeto Segments vacío, si quieres rellenarlo tú mismo.

  • referencePoint (tuple) – El punto de referencia para el cálculo de la distancia de Hough. referencePoint no afecta las coordenadas de los segmentos, que por una cuestión de eficiencia se almacenan sin cambios. Se usa en computeDistances().

angles: ndarray
computeAngles()

Calcula los ángulos a partir de los deltas, con arctan2, por lo que el ángulo está en [-pi, pi]. Los resultados se almacenan en la propiedad angles. Si los deltas están normalizados (dy>=0), los ángulos están en [0, pi]. No toma argumentos ni devuelve ningún valor.

computeAnglesAndDistances()

Ejecuta todo: Calcula ángulos, distancias, longitudes, deltas y luego ordena los deltas.

computeDeltas()

Deltas son (dx,dy), segundo punto menos primer punto.

computeDistances()

Computa distancias desde referencePoint a los segmentos, con signo. No establecer referencePoint generará una excepción. Si los deltas no están ordenados, los signos de las distancias dependerán de los deltas.

computeLengths()

Calcula las longitudes a partir de los deltas.

coords: ndarray
deltas: ndarray
distances: ndarray
getPointAsIntTuple(point: ndarray) tuple

Devuelve un punto como una tupla de enteros. Así lo requiere drawMarker de OpenCV.

Devuelve:

El punto de referencia como un array 2D.

Tipo del valor devuelto:

np.ndarray

lengths: ndarray
n: int
normalUnityVectors: ndarray
referencePoint: ndarray = array([nan, nan])
tidyupDeltas()

Rota 180º si es necesario para tener dy >= 0, de modo que los vectores normales apunten hacia abajo (y positivo apunta hacia abajo). Útil para calcular distancias.

class detector.SegmentsAnnotator(color: tuple[int, int, int] = (0, 0, 255), thickness: int = 1, withPoints: bool = False, offset: tuple = (0, 0), scale: float = 1.0, colorMap: ~typing.Callable[[float], tuple[int, int, int]] = <staticmethod(<function SegmentsAnnotator.colorMapBGR>)>)

Clase para dibujar segmentos sobre una imagen.

__init__(color: tuple[int, int, int] = (0, 0, 255), thickness: int = 1, withPoints: bool = False, offset: tuple = (0, 0), scale: float = 1.0, colorMap: ~typing.Callable[[float], tuple[int, int, int]] = <staticmethod(<function SegmentsAnnotator.colorMapBGR>)>)

Constructor Establece valores predeterminados para dibujar segmentos sobre una imagen.

Arguments: - color: color para la anotación. - thickness: grosor de las líneas. - withPoints: si se deben dibujar los puntos finales de los segmentos. - offset: desplazamiento para aplicar a los segmentos. - scale: factor de escala para aplicar a los segmentos. - colorMap: función para mapear intensidades a colores.

static colorMapBGR(intensity: float) tuple[int, int, int]

Devuelve un color BGR a partir de una intensidad en el rango [0.0,1.0), con colores primarios y secundarios brillantes 255. Mapea los colores en un patrón cíclico: el color para 0,999 es vecino al color para 0.0. Adopta una paleta de 765 colores.

Arguments: - intensity: intensidad en el rango [0.0,1.0).

Returns: - tupla con color BGR.

static colorMapGray(intensity)

Gray scale color mapping

static colorMapYMC(intensity: float) tuple[int, int, int]

Devuelve un color BGR a partir de una intensidad en el rango [0.0,1.0), con colores brillantes 255. Mapea los colores en un patrón cíclico: el color para 0,999 es vecino al color para 0.0. Adopta una paleta de 765 colores.

Arguments: - intensity: intensidad en el rango [0.0,1.0).

Returns: - tupla con color BGR.

drawSegments(image: np.ndarray, segments: Segments | np.ndarray, intensities: np.ndarray | None = None, message: str | None = None, color: tuple | np.ndarray | None = None, thickness: int | None = None, colorMap: function | None = None, withPoints: bool | None = None, offset: tuple | np.ndarray | None = None, scale: float | None = None) np.ndarray

Dibuja los segmentos sobre una imagen. Si se proporcionan intensidades, el color se ignora y se utiliza colorMap. Si se proporciona un mensaje, se escribe en la esquina inferior izquierda. Si se omiten, estos argumentos tienen valores por defecto en el objeto:

  • color

  • thickness

  • withPoints

  • offset

  • scale

Parámetros:
  • image – Imagen para anotar.

  • segments – Segmentos a dibujar.

  • intensities – Intensidades para mapear a colores, en el rango [0..1). Mismo tamaño que segments.

  • message (str) – Mensaje para escribir en la imagen.

  • color – Color para la anotación, utilizado si no se proporcionan intensidades. Un ndarray de forma (n,3) proporciona un color para cada segmento. Por defecto usa self.color.

  • thickness (int) – Grosor de las líneas.

  • colorMap (function) – Función para mapear intensidades a colores.

  • withPoints (bool) – Si se deben dibujar los puntos finales de los segmentos.

  • offset (tuple) – Desplazamiento para aplicar a los segmentos.

  • scale (float) – Factor de escala para aplicar a los segmentos.

detector.projectSegments(segments: Segments | ndarray | tuple, H: ndarray, inverse: bool = False, segmentsShape: bool = True, printFlag: bool = False) ndarray

Proyecta los segmentos dados con la homografía H de forma (3,3).

P” = H * P

Los segmentos son pares de puntos. Para proyectar puntos en lugar de segmentos (un número impar de puntos, como solo uno) use segmentsShape=False.

Arguments: - segments: conjunto de segmentos. - H: matriz de homografía. - inverse: si es True, H se considera la inversa de la proyección. - segmentsShape: si es True, el resultado se remodela a la forma original de los segmentos. - printFlag: si es True, imprime resultados intermedios.

Returns: - ndarray de segmentos proyectados.