[opencv] contornos: mais propriedades (qualquer desvio no casco convexo: defeito de convexidade, distância mais curta do ponto à linha de contorno, comparar duas formas ou dois contornos e retornar uma medida mostrando semelhança)

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= Falsepara 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**().

Acho que você gosta

Origin blog.csdn.net/dujuancao11/article/details/122429162
Recomendado
Clasificación