OpenCV Buscar contornos
Este tutorial discutirá cómo encontrar contornos presentes en una imagen usando la función findContours()
de OpenCV en Python.
Utilice la función findContours()
de OpenCV para encontrar contornos en una imagen en Python
Los contornos son curvas formadas al unir los puntos junto con el límite de un objeto. En las imágenes, hay varios objetos presentes y, al encontrar los contornos de la imagen, podemos obtener información sobre la forma de los objetos, ya que los contornos resaltarán los límites de los objetos presentes en la imagen.
Si conocemos las formas de los objetos, podemos adivinar fácilmente qué objetos están presentes en la imagen. Los contornos se utilizan ampliamente para analizar formas y detectar y reconocer objetos.
Podemos usar la función findContours()
de OpenCV para encontrar los contornos presentes en una imagen. Debemos usar una imagen binaria para encontrar los contornos para una mayor precisión.
Si la imagen dada no es binaria, podemos convertirla a binaria. Por ejemplo, en el caso de la imagen a color, debemos convertir la imagen a escala de grises utilizando la función cvtColor()
de OpenCV.
Podemos usar la imagen en escala de grises dentro de la función de umbral () de OpenCV para encontrar la imagen binaria. Después de eso, podemos usar la función findContours()
y la imagen binaria para encontrar los contornos.
Si queremos mostrar los contornos, debemos crear un dibujo y dibujar contornos utilizando la función drawContours()
. El dibujo debe tener el mismo tamaño que la imagen dada para visualizar mejor los contornos.
Podemos crear un dibujo en color negro del mismo tamaño que la imagen dada usando la función zeros() de la biblioteca numpy
.
Por ejemplo, vamos a leer una imagen usando la función imread()
, convertirla a la escala binaria y luego encontrar los contornos y mostrarlos. Vea el código a continuación.
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
cv2.waitKey(0)
Producción:
La función findContours()
devuelve dos argumentos de salida. El primer argumento de salida contiene los puntos de ubicación y las coordenadas del contorno en una lista. El segundo argumento de salida contiene la jerarquía de los contornos.
La primera entrada de la función findContours()
es una imagen binaria o en escala de grises. El segundo argumento de entrada es el modo de recuperación utilizado para definir la jerarquía de contornos.
Podemos pasar diferentes valores dentro del modo de recuperación como cv2.RETR_LIST
para recuperar todos los contornos, cv2.RETR_EXTERNAL
para recuperar solo contadores externos, cv2.RETR_COMP
para recuperar contornos en la jerarquía de 2 niveles y cv2.RETR_TREE
para recuperar contornos en la jerarquía completa. El tercer argumento de entrada de la función findContours()
es el método aproximado utilizado para almacenar los puntos límite.
El método cv2.CHAIN_APPROX_NONE
almacena todos los puntos límite, pero a veces no necesitamos todos los puntos límite. Podemos usar el método cv2.CHAIN_APPROX_SIMPLE
para almacenar los contornos de los puntos inicial y final.
También podemos definir un desplazamiento que desplazará cada contorno según el desplazamiento en la función findContours()
. También podemos mostrar los contornos encima de la imagen dada usando la función drawContours()
de OpenCV.
El primer argumento de la función drawContours()
es la imagen de la que queremos dibujar los contornos. El segundo argumento son los contornos, y el tercero es el índice de contorno.
El tercer argumento es el color de los contornos y se puede definir como un triplete RGB. El cuarto argumento es el grosor de los contornos que se puede definir como un número entero.
Por ejemplo, mostremos el contorno en la parte superior de la imagen dada. Vea el código a continuación.
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
ImgWithCounter = cv2.drawContours(image, contours, -1, (255, 255, 0), 3)
cv2.imshow("Image with counters", ImgWithCounter)
cv2.waitKey(0)
Producción: