Blog
Contornos: más funciones
- Publicado por: Alberto Sosa-Costa
- Categoría: Blog OpenCV Procesamiento de Imagenes
Aprender cómo encontrar defectos de convexidad.
Encontrar la distancia más corta entre un punto y un polígono.
Hacer coincidir diferentes formas.
Defectos de convexidad
En entradas anteriores hemos visto el concepto de envoltura convexa. Cualquier desviación del objeto de esta envoltura puede considerarse como defecto de convexidad.
OpenCV viene con una función ya hecha para encontrar esto, cv2.convexityDefects(). A continuación un ejemplo de cómo llamar a esta función:
#Carga la imagen img = cv2.imread('test.jpg',0) #Determina los contornos ret,thresh = cv2.threshold(img,120,255,0) image,contours, hierarchy = cv2.findContours(thresh,1,2) cnt = contours[0] #Halla los defectos de convexidad envoltura = cv2.convexHull(cnt,returnPoints = False) defectos = cv2.convexityDefects(cnt,envoltura)
Recuerde que debe pasar returnPoints = False, cuando determine la envoltura convexa, a fin de encontrar defectos de convexidad.
import cv2 #Carga la imagen img = cv2.imread('estrella.png') #Convierte la imagen a escala de grises imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray,127,255,0) #Determina los contornos image,contours, hierarchy = cv2.findContours(thresh,1,2) cnt = contours[0] #Determina los defectos de convexidad envoltura = cv2.convexHull(cnt,returnPoints = False) defectos = cv2.convexityDefects(cnt,envoltura) #Dibuja la envoltura convexa y los defectos de convexidad for k in range(defectos.shape[0]): i,f,l,d = defectos[k,0] inicio= tuple(cnt[i][0]) fin= tuple(cnt[f][0]) lejos = tuple(cnt[l][0]) cv2.line(img,inicio,fin,[0,255,255],2) cv2.circle(img,lejos,5,[0,0,255],-1) #Muestra la imagen final cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows() #Guarda la imagen cv2.imwrite('def_convexidad.png',img)
Prueba de polígono de puntos
Esta función encuentra la distancia más corta entre un punto de la imagen y su contorno. Esta distancia es negativa si el punto está fuera del contorno, positiva si está dentro y cero si está sobre el contorno.
Por ejemplo, podemos comprobar el punto (30,30) de la siguiente manera:
dist = cv2.pointPolygonTest(cnt,(30,30),True)
Aquí, el tercer argumento de la función es measureDist. Si es True, encuentra la distancia mínima explicada anteriormente. Si es Falso, entonces la función devuelve +1, -1 ó 0, indicando que el punto está dentro, fuera o sobre el contorno, respectivamente.
Si no desea encontrar la distancia, asegúrese de que el tercer argumento es False, porque este es un proceso que consume mucho tiempo. De hecho, fijando el tercer argumento como False, la función corre de dos a tres veces más rápido.
Haciendo coincidir formas
Otra interesante función de OpenCV es cv2.matchShapes() que nos permite comparar dos formas, o dos contornos y devuelve una métrica que muestra la similitud. Cuanto menor sea el resultado, más similares serán las imágenes comparadas. Se calcula sobre la base de los valores de los momentos invariantes de Hu.
import cv2 #Carga ambas imágenes que se desean comparar img1 = cv2.imread('estrella.png',0) img2 = cv2.imread('estrella2.png',0) #Determina los contornos de ambas imágenes ret, thresh = cv2.threshold(img1, 127, 255,0) images,contours,hierarchy = cv2.findContours(thresh,2,1) cnt1 = contours[0] ret, thresh2 = cv2.threshold(img2, 127, 255,0) images,contours,hierarchy = cv2.findContours(thresh2,2,1) cnt2 = contours[0] #Calcula la similitud entre ambas imágenes y muestra el resultado ret = cv2.matchShapes(cnt1,cnt2,1,0.0) print(ret)
Más bajo se muestran los resultados obtenidos al comparar las siguientes imágenes:
Imagen A con la imagen B = 0,001946
Imagen A con imagen C = 0.326911Note que incluso la rotación de la imagen no afecta mucho a esta comparación.
Los Momentos de Hu son siete momentos invariantes a la traslación, la rotación y la escala. Estos valores se pueden encontrar utilizando la función cv2.HuMoments().
a
¡Enhorabuena por llegar hasta aquí! Sigue aprendiendo de contornos en
nuestro curso Python de OpenCV:
[…] ➡ Mas funciones de los contornos […]