4_9_4_Contour: mais atributos - Documentação oficial chinesa OpenCV
Vai aprender - Defeitos de convexidade e como encontrá-los - Encontrar a distância mais curta de um ponto a um polígono - Combinar formas diferentes
teoria e código
1. Defeitos de convexidade
Vimos o casco convexo no Capítulo 2 sobre Contornos. Qualquer desvio deste casco convexo pode ser considerado um defeito de convexidade. O OpenCV tem uma função para encontrar isso, cv.convexityDefects (). Uma chamada de função básica é a seguinte:
hull = cv.convexHull(cnt,returnPoints = False) defects = cv.convexityDefects(cnt,hull)
Nota Lembre-se que temos que passar ao encontrar o casco convexo
returnPoints= False
para encontrar o defeito de convexidade.Ele retorna um array onde cada linha contém esses valores - [start, end, farthest point, distância aproximada ao ponto mais distante] . Podemos visualizá-lo com imagens. Desenhamos uma linha conectando os pontos inicial e final e, em seguida, desenhamos um círculo no ponto mais distante. Lembre-se, os três primeiros valores retornados são os índices de cnt. Então temos que pegar esses valores do cnt.
import cv2 as cv import numpy as np img = cv.imread('star.jpg') img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) ret,thresh = cv.threshold(img_gray, 127, 255,0) contours,hierarchy = cv.findContours(thresh,2,1) cnt = contours[0] hull = cv.convexHull(cnt,returnPoints = False) defects = cv.convexityDefects(cnt,hull) for i in range(defects.shape[0]): s,e,f,d = defects[i,0] start = tuple(cnt[s][0]) end = tuple(cnt[e][0]) far = tuple(cnt[f][0]) cv.line(img,start,end,[0,255,0],2) cv.circle(img,far,5,[0,0,255],-1) cv.imshow('img',img) cv.waitKey(0) cv.destroyAllWindows()
Ver resultados:
2. Teste de Polígono de Pontos
Esta função encontra a distância mais curta de um ponto até o contorno . Ele retorna a distância, que é negativa quando o ponto está fora do contorno, positivo quando o ponto está dentro do contorno e zero quando o ponto está no contorno .
Por exemplo, podemos verificar
(50,50)
o seguinte:dist = cv.pointPolygonTest(cnt,(50,50),True)
Na função, o terceiro parâmetro é MeasureDist. Se for verdade, ele encontrará a distância sinalizada. Se false, descobre se o ponto está dentro ou fora da linha de contorno (retorna +1, -1 e 0 respectivamente).
Observação Se você não quiser encontrar a distância, certifique-se de que o terceiro parâmetro seja False, pois esse é um processo demorado. Portanto, configurá-lo para False o torna 2-3 vezes mais rápido.
3. Correspondência de formas
OpenCV vem com uma função **cv.matchShapes**() que nos permite comparar duas formas ou dois contornos e retorna uma medida mostrando a similaridade .
Quanto menor o resultado, melhor a partida. É calculado a partir dos valores de momento.
Os diferentes métodos de medição são explicados na documentação.
import cv2 as cv import numpy as np img1 = cv.imread('star.jpg',0) img2 = cv.imread('star2.jpg',0) ret, thresh = cv.threshold(img1, 127, 255,0) ret, thresh2 = cv.threshold(img2, 127, 255,0) contours,hierarchy = cv.findContours(thresh,2,1) cnt1 = contours[0] contours,hierarchy = cv.findContours(thresh2,2,1) cnt2 = contours[0] ret = cv.matchShapes(cnt1,cnt2,1,0.0) print( ret )
Eu tentei formas que combinam com as diferentes formas dadas abaixo:
Obtenho os seguintes resultados: - combinando a imagem A consigo mesma = 0,0 - combinando a imagem A com a imagem B = 0,001946 - combinando a imagem A com a imagem C = 0,326911
Veja, mesmo a rotação da imagem não faz grande diferença nesta comparação.
Os momentos Hu de referência são os sete momentos que são invariantes à translação, rotação e escala. A sétima é a quantidade não distorcida. Esses valores podem ser encontrados usando a função **cpu.HuMoments**().