Opencv foundation 47 encuentra el contorno de la imagen cv2.findContours() explicación detallada

¿Qué es el contorno de la imagen?

El contorno de la imagen se refiere a la curva continua del borde del objeto en la imagen. En la visión por computadora y el procesamiento de imágenes, los contornos se usan comúnmente para detectar objetos, segmentar imágenes y extraer características de objetos.

El contorno de la imagen se compone de una serie de píxeles consecutivos, que se encuentran en el límite del objeto. Las siluetas se caracterizan por la posición del límite entre el objeto y el fondo y, por lo tanto, se pueden utilizar para representar la forma y la estructura del objeto. Los contornos pueden ser cerrados o abiertos, según la forma del objeto.

¿Cuál es el escenario de aplicación del contorno de la imagen?

Los contornos de la imagen juegan un papel importante en muchos escenarios de aplicación, algunos escenarios de aplicación comunes se enumeran a continuación:

Detección y reconocimiento de objetos : los contornos de la imagen se pueden utilizar para detectar y localizar objetos en una imagen. Al detectar el contorno de un objeto, se pueden identificar y clasificar diferentes objetos en una imagen.

Segmentación de imágenes : los contornos se pueden usar para segmentar diferentes regiones u objetos en una imagen. Al extraer el contorno del objeto, la imagen se puede dividir en múltiples partes diferentes para su posterior análisis y procesamiento.

Análisis de imágenes médicas : en imágenes médicas, los contornos se pueden usar para etiquetar estructuras como órganos, lesiones o células. Esto tiene implicaciones importantes para el diagnóstico y las decisiones de tratamiento.

Automatización industrial : en la automatización industrial, los contornos se pueden utilizar para detectar defectos de productos, medir dimensiones y colocar componentes, lo que permite la producción automatizada y el control de calidad.

Visión robótica : los robots pueden usar contornos de imágenes para percibir el entorno y los objetos, logrando así tareas como la navegación autónoma y el agarre de objetos.

Diseño asistido por computadora (CAD) : en el campo de CAD, los contornos de imágenes se pueden usar para obtener información geométrica de objetos reales para modelar y diseñar en una computadora.

Realidad virtual y aumentada : las siluetas de imágenes se pueden usar para rastrear objetos en tiempo real, lo que permite que los objetos virtuales interactúen con la escena real para crear una experiencia de realidad virtual o aumentada más realista.

Reconstrucción de imágenes y modelado 3D : la reconstrucción de imágenes y el modelado 3D se pueden realizar utilizando el contorno del objeto para generar un modelo de objeto tridimensional.

Aunque la detección de bordes puede detectar bordes, los bordes son discontinuos y los bordes detectados no son un todo. El contorno de la imagen se refiere a un todo formado por bordes de conexión, que se utiliza para cálculos posteriores.
OpenCV proporciona una función para encontrar el contorno de una imagen 函数 cv2.findContours(). Esta función puede encontrar la información del contorno en la imagen, y la función cv2.drawContours() puede dibujar el contorno.
El contorno de la imagen es una información característica muy importante en la imagen.A través de la operación del contorno de la imagen, podemos obtener el tamaño, la posición, la dirección y otra información de la imagen de destino.

Buscar contornos de imagen: función findContours

El formato de sintaxis de la función cv2.findContours() es:

image, contours, hierarchy = cv2.findContours( image, mode, method)

El valor devuelto en la fórmula es:

  • imagen: Consistente con la imagen de imagen original en el parámetro de función.
  • contornos: Los contornos devueltos.
  • jerarquía: Información topológica (jerarquía de contorno) de la imagen.

Los parámetros en la fórmula son:

  • imagen: la imagen original. Imagen de un solo canal de 8 bits, todos los valores distintos de cero se tratan como 1 y todos los valores cero se dejan sin cambios. Es decir, la imagen en escala de grises se procesará automáticamente en una imagen binaria. En la operación real, las funciones tales como el procesamiento de valores umbral se pueden usar de antemano para procesar la imagen del contorno a buscar en una imagen binaria según sea necesario.
  • modo: modo de recuperación de contorno.
  • método: El método de aproximación para el contorno.

El valor devuelto y los parámetros de la función cv2.findContours() tienen significados ricos, y los valores devueltos y los parámetros anteriores se explican uno por uno a continuación.

1. La imagen del valor de retorno
El valor de retorno es consistente con la imagen del parámetro, que es la imagen de entrada original. En OpenCV 4.X, este valor devuelto ha sido cancelado. En OpenCV 4.X, la función cv2.findContours() tiene solo dos valores de retorno y su formato de sintaxis es:

contornos, jerarquía = cv2.findContours(imagen, modo, método)

2. Contornos de valor de retorno
Este valor de retorno devuelve un conjunto de información de contorno, y cada contorno se compone de varios puntos. Por ejemplo, contornos[i] es el contorno i-ésimo (los subíndices comienzan desde 0), y contornos[i][j] es el punto j-ésimo dentro del contorno i-ésimo.

La Figura 12-1 muestra un ejemplo de los contornos extraídos. La función cv2.findContours() extrae los tres contornos en la imagen de la izquierda, y cada contorno está compuesto por varios píxeles.

inserte la descripción de la imagen aquí
A continuación se presentan brevemente las propiedades básicas de los contornos según la Figura 12-1.

(1) atributo de tipo
El atributo de tipo de los contornos de valor de retorno es un tipo de lista, y cada elemento de la lista es un contorno de la imagen, representado por la estructura ndarray en Numpy.
Por ejemplo, use la siguiente declaración para obtener el tipo de contornos:

print (type(contours))

El resultado es <clase 'lista'>.

Use la siguiente declaración para obtener el tipo de cada elemento en los contornos:

print (type(contours[0]))

El resultado es <clase 'numpy.ndarray'>.

(2) Número de contornos
Use la siguiente declaración para obtener el número de contornos:

print (len(contours))

El resultado es "3", lo que significa que en la Figura 12-1 hay 3 contornos.

(3) Número de puntos por contorno

Cada contorno se compone de varios puntos de píxeles, el número de puntos no es fijo y el número específico depende de la forma del contorno.
Por ejemplo, el número de puntos en cada contorno se puede obtener usando la siguiente declaración:

print (len(contours[0])) #打印第 0 个轮廓的长度(点的个数):4
print (len(contours[1])) #打印第 1 个轮廓的长度(点的个数):60
print (len(contours[2])) #打印第 2 个轮廓的长度(点的个数):184

(4) Puntos en el contorno
Usando la siguiente declaración, puede obtener el atributo de posición del punto específico en el contorno 0 en el contorno:

print (contours[0]) #打印第 0 个轮廓中的像素点

contornos[0] corresponde al punto del contorno rectangular en la esquina inferior izquierda de la figura derecha en la Figura 12-1, y los resultados de salida son los siguientes:

[[[ 79 270]]
[[ 79 383]]
[[195 383]]
[[195 270]]]
  1. Los contornos dentro de la imagen de la jerarquía del valor de retorno
    pueden ubicarse en diferentes posiciones. Por ejemplo, un contorno está dentro de otro contorno. En este caso,
    nos referimos al contorno exterior como contorno padre y al contorno interior como contorno hijo . Según la clasificación de relación anterior, se establece una relación padre-hijo entre todos los contornos de una imagen.

A partir de la relación entre los contornos, es posible determinar cómo se conecta un contorno con otros contornos. Por ejemplo, determine si un contorno es un contorno secundario de un contorno determinado o un contorno principal de un contorno determinado. La relación mencionada anteriormente se denomina jerarquía (estructura organizativa) y la jerarquía de valor de retorno contiene la relación jerárquica mencionada anteriormente.
Cada contorno contornos[i] corresponde a 4 elementos para ilustrar la relación jerárquica del contorno actual. Su forma es:

[Next,Previous,First_Child,Parent]

El significado de cada elemento en la fórmula es:

  • Siguiente: El número de índice del siguiente contorno.

  • Anterior: Número de índice del contorno anterior.

  • First_Child: el número de índice del primer contorno secundario.

  • Padre: El número de índice del contorno padre.

Si la relación correspondiente a cada uno de los parámetros anteriores está vacía, es decir, cuando no existe una relación correspondiente, el valor correspondiente al parámetro se establece en "-1".
Utilice la declaración de impresión para ver el valor de la jerarquía:

print(hierarchy)

Cabe señalar que la estructura jerárquica del contorno está determinada por el modo de parámetro. Es decir, utilizando diferentes modos, el número de contornos obtenidos es diferente y la jerarquía obtenida también es diferente.

  1. Imagen de parámetro
    Este parámetro representa la imagen de entrada, que debe ser una imagen binaria de un solo canal de 8 bits. En general, la imagen se procesa en una imagen binaria y luego se usa como parámetro de imagen.

  2. Modo de parámetros
    El modo de parámetros determina el método de extracción del contorno, específicamente de la siguiente manera:

  • cv2.RETR_EXTERNAL: Solo detecta contornos exteriores.
  • cv2.RETR_LIST: No se establece relación jerárquica para los contornos detectados.
  • cv2.RETR_CCOMP: Recupera todos los contornos y los organiza en una jerarquía de dos niveles. La capa superior es el límite exterior y la capa inferior es el límite interior del agujero. Si hay otro objeto conectado dentro del agujero interior, entonces el límite de este objeto todavía está
    en el nivel superior.
  • cv2.RETR_TREE: crea un esquema de una estructura de árbol jerárquico.

Las cuatro situaciones se describen brevemente a continuación.

(1) cv2.RETR_EXTERNAL (solo detecta el contorno exterior)

Por ejemplo, solo se detectan dos contornos exteriores en la Figura 12-2, y los números de serie de los contornos se indican mediante los números de la figura.

inserte la descripción de la imagen aquí
Utilice la declaración de impresión para ver el valor de la jerarquía:

imprimir(jerarquía) [[[ 1 -1 -1 -1] [-1 0 -1 -1]]]

en:

  • El valor de salida "[ 1 -1 -1 -1]" representa el nivel del contorno 0.
  • El contorno siguiente (es decir, el contorno 0) es el contorno 1, por lo que el valor del elemento 1 es "1".
  • Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".
  • No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
  • No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".
  • El valor de salida "[-1 0 -1 -1]" indica el nivel del primer contorno.
  • El siguiente contorno del mismo (es decir, el primer contorno) no existe, por lo que el valor del primer elemento es "-1".
  • Su contorno anterior es el contorno 0, por lo que el valor del segundo elemento es "0".
  • No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
  • No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".
    En este punto, la relación entre los contornos es:

inserte la descripción de la imagen aquí
(2) cv2.RETR_LIST (no se establece relación jerárquica para los contornos detectados)

Por ejemplo, se detectan tres contornos en la figura 12-3 y los números de serie de cada contorno se indican mediante los números de la figura.

inserte la descripción de la imagen aquí
Usando la declaración de impresión, puede ver el valor de la jerarquía:

imprimir(jerarquía) [[[ 1 -1 -1 -1] [ 2 0 -1 -1] [-1 1 -1 -1]]]

en:

  • El valor de salida "[ 1 -1 -1 -1]" representa el nivel del contorno 0.

  • El contorno siguiente (es decir, el contorno 0) es el contorno 1, por lo que el valor del elemento 1 es "1".

  • Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".

  • No tiene subcontornos, por lo que el valor del tercer elemento es "-1".

  • No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

  • El valor de salida "[2 0 -1 -1]" indica el nivel del primer contorno.

  • El siguiente contorno (el primer contorno) es el segundo contorno, por lo que el valor del primer elemento es "2".

  • Su contorno anterior es el contorno 0, por lo que el valor del segundo elemento es "0".

  • No tiene subcontornos, por lo que el valor del tercer elemento es "-1".

  • No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

  • El valor de salida "[-1 1 -1 -1]" indica el nivel del segundo contorno.

  • El contorno siguiente (es decir, el segundo contorno) no existe, por lo que el valor del primer elemento es "-1".

  • Su contorno anterior es el 1er contorno, por lo que el valor del 2do elemento es "1".

  • No tiene subcontornos, por lo que el valor del tercer elemento es "-1".

  • No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".
    Se puede ver en el análisis anterior que cuando el modo de parámetro es cv2.RETR_LIST, no existe una relación padre-hijo entre los contornos.

En este punto, la relación entre los contornos es:

inserte la descripción de la imagen aquí
(3) cv2.RETR_CCOMP (construir dos niveles de contornos)

Cuando el modo del parámetro es cv2.RETR_CCOMP, se establecen dos niveles de contornos. La capa superior es el límite exterior y la capa inferior es el límite interior del agujero.

Por ejemplo, se detectan tres contornos en la figura 12-4 y los números de serie de cada contorno se indican mediante los números de la figura.

inserte la descripción de la imagen aquí
Utilice la declaración de impresión para ver el valor de la jerarquía:

print(hierarchy)
[[[ 1 -1 -1 -1]
 [-1 0 2 -1]
 [-1 -1 -1 1]]]

en:

  • El valor de salida "[ 1 -1 -1 -1]" representa el nivel del contorno 0.
    El contorno siguiente (es decir, el contorno 0) es el contorno 1, por lo que el valor del elemento 1 es "1".
    Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".
    No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
    No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

  • El valor de salida “[-1 0 2 -1]” indica el nivel del primer contorno.
    El siguiente contorno del mismo (es decir, el primer contorno) no existe, por lo que el valor del primer elemento es "-1".
    Su contorno anterior es el contorno 0, por lo que el valor del segundo elemento es "0".
    Su primer contorno hijo es el segundo contorno, por lo que el valor del tercer elemento es "2".
    No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

  • El valor "[-1 -1 -1 1]" indica el nivel del segundo contorno.
    El contorno siguiente (es decir, el segundo contorno) no existe, por lo que el valor del primer elemento es "-1".
    Su contorno anterior tampoco existe, por lo que el valor del segundo elemento es "-1".
    No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
    Su contorno principal es el primer contorno, por lo que el valor del cuarto elemento es "1".
    En este punto, la relación de contorno es:

inserte la descripción de la imagen aquí

(4) cv2.RETR_TREE (construir el esquema de una estructura de árbol jerárquica)

Por ejemplo, se detectan tres contornos en la figura 12-5 y los números de serie de cada contorno se indican mediante los números de la figura.

inserte la descripción de la imagen aquí
Utilice la declaración de impresión para ver el valor de la jerarquía:

print(hierarchy)
[[[ 1 -1 -1 -1]
 [-1 0 2 -1]
 [-1 -1 -1 1]]]

en:

  • El valor de salida "[ 1 -1 -1 -1]" representa el nivel del contorno 0.
    El contorno siguiente (es decir, el contorno 0) es el contorno 1, por lo que el valor del elemento 1 es "1".
    Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".
    No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
    No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

  • El valor de salida “[-1 0 2 -1]” indica el nivel del primer contorno.
    El siguiente contorno del mismo (es decir, el primer contorno) no existe, por lo que el valor del primer elemento es "-1".
    Su contorno anterior es el contorno 0, por lo que el valor del segundo elemento es "0".
    Su primer contorno hijo es el segundo contorno, por lo que el valor del tercer elemento es "2".
    Su perfil principal no existe, por lo que el valor del cuarto elemento es "-1".

  • El valor de salida "[-1 -1 -1 1]" indica el nivel del segundo contorno.
    El contorno siguiente (es decir, el segundo contorno) no existe, por lo que el valor del primer elemento es "-1".
    Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".
    Su subcontorno no existe, por lo que el valor del tercer elemento es "-1".
    Su contorno principal es el primer contorno, por lo que el valor del primer elemento es "1

En este punto, la relación entre los contornos es:

inserte la descripción de la imagen aquí
Cabe señalar que solo hay dos capas de contornos en este ejemplo , por lo que las estructuras jerárquicas obtenidas al usar los parámetros cv2.RETR_CCOMP y cv2.RETR_TREE son consistentes . Cuando hay múltiples capas de contornos, al usar el parámetro cv2.RETR_CCOMP también obtendrá una jerarquía con solo dos capas, y al usar el parámetro cv2.RETR_TREE obtendrá una estructura con múltiples capas.

6. Método de parámetros
El método de parámetros determina cómo expresar el contorno, que puede ser los siguientes valores:

  • cv2.CHAIN_APPROX_NONE: almacena todos los puntos de contorno y la diferencia de posición de píxeles entre dos puntos adyacentes no supera 1, es decir, max(abs(x1-x2), abs(y2-y1))=1.
  • cv2.CHAIN_APPROX_SIMPLE: Comprime elementos en dirección horizontal, dirección vertical y dirección diagonal, y solo retiene las coordenadas del punto final de esta dirección. Por ejemplo, en casos extremos, un rectángulo solo necesita 4 puntos para contener la información del contorno.
  • cv2.CHAIN_APPROX_TC89_L1: use una versión del algoritmo de aproximación de cadena teh-Chinl.
  • cv2.CHAIN_APPROX_TC89_KCOS: utiliza una versión del algoritmo de aproximación de cadena teh-Chinl.

Por ejemplo, en la Figura 12-6, la imagen de la izquierda es el contorno almacenado con el valor del parámetro cv2.CHAIN_APPROX_NONE, que guarda todos los puntos del contorno, la imagen de la derecha es el contorno almacenado con el valor del parámetro cv2.CHAIN_APPROX_SIMPLE, y solo el Se guardan los puntos en el límite. Cuatro puntos.

inserte la descripción de la imagen aquí
Cuando utilice la función cv2.findContours() para encontrar contornos de imágenes, debe prestar atención a los siguientes problemas:

  • La imagen de origen que se va a procesar debe ser una imagen binaria en escala de grises. Por lo tanto, en circunstancias normales, es necesario realizar una segmentación de umbral
    o un procesamiento de detección de bordes en la imagen por adelantado, y luego usarlo como parámetro después de obtener una imagen binaria satisfactoria.
  • En OpenCV, se trata de encontrar objetos blancos de fondos negros. Por lo tanto, el objeto debe ser blanco y el fondo debe
    ser negro.
  • En OpenCV 4.x, la función cv2.findContours() tiene solo dos valores de retorno.

Ejemplo de código:

import cv2
o = cv2.imread('lena.png')
cv2.imshow("original",o)
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

print("contours=\n",contours)
print("hierarchy=\n",hierarchy)

Después de ejecutar este código, encontrará un error, porque estoy usando la versión opencv4.5.

El error
inserte la descripción de la imagen aquí
indica que en OpenCV 4.x, la función cv2.findContours() solo tiene dos valores de retorno

El nuevo código es el siguiente:

import cv2
o = cv2.imread('contours.bmp')

gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

print("hierarchy=\n",hierarchy)

El resultado de la operación es el siguiente:

hierarchy=
 [[[ 1 -1 -1 -1]
  [ 2  0 -1 -1]
  [-1  1 -1 -1]]]

Imagen original:

Puede aplicar las explicaciones anteriores para analizar el significado del valor, como:

El valor de salida " [ 1 -1 -1 -1] " indica el nivel del contorno 0.
El contorno siguiente (es decir, el contorno 0) es el contorno 1, por lo que el valor del elemento 1 es "1".
Su contorno anterior no existe, por lo que el valor del 2º elemento es "-1".
No tiene subcontornos, por lo que el valor del tercer elemento es "-1".
No tiene contorno principal, por lo que el valor del cuarto elemento es "-1".

Trate de entender
[ 2 0 -1 -1]
[-1 1 -1 -1]
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/hai411741962/article/details/132165910
Recomendado
Clasificación