A correspondência de modelo é uma técnica para localizar áreas de uma imagem que são semelhantes a um patch (modelo).
Um patch é uma pequena imagem com certos recursos. O objetivo da correspondência de modelos é encontrar o patch / modelo em uma imagem.
Para encontrá-lo, o usuário deve fornecer duas imagens de entrada:  Imagem de origem (S)  - A imagem na qual encontrar o modelo e  Imagem de modelo (T) - A imagem que deve ser encontrada na imagem de origem.

  • É basicamente um método para pesquisar e encontrar a localização de uma imagem de modelo em uma imagem maior.
  • A ideia aqui é encontrar regiões idênticas de uma imagem que correspondam a um modelo que fornecemos, fornecendo um limite
    • O limite depende da precisão com a qual queremos detectar o modelo na imagem de origem.
    • Por exemplo, se estamos aplicando o reconhecimento de rosto e queremos detectar os olhos de uma pessoa, podemos fornecer uma imagem aleatória de um olho como modelo e pesquisar a fonte (o rosto de uma pessoa).
    • Nesse caso, como os “olhos” mostram uma grande quantidade de variações de pessoa para pessoa, mesmo se definirmos o limite como 50% (0,5), o olho será detectado.
    • Nos casos em que modelos quase idênticos devem ser pesquisados, o limite deve ser definido como alto. (T> = 0,8)

Como funciona a correspondência de modelos?

  • A imagem do modelo simplesmente desliza sobre a imagem de entrada (como na convolução 2D)
  • O modelo e o patch da imagem de entrada sob a imagem do modelo são comparados.
  • O resultado obtido é comparado com o limite.
  • Se o resultado for maior que o limite, a parte será marcada como detectada.
  • Na função cv2.matchTemplate (img_gray, template, cv2.TM_CCOEFF_NORMED) o primeiro parâmetro é a imagem principal, o segundo parâmetro é o modelo a ser correspondido e o terceiro parâmetro é o método usado para correspondência.
import cv2 
import numpy as np 
img_rgb = cv2.imread('mainimage.jpg'). 
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) 
template = cv2.imread('template',0) 
w, h = template.shape[::-1] 
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) 
threshold = 0.8
loc = np.where( res >= threshold)  
for pt in zip(*loc[::-1]): 
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2) 
cv2.imshow('Detected',img_rgb) 

Limitações da correspondência de modelo:

  1. As ocorrências de padrão devem preservar a orientação da imagem do padrão de referência (modelo)
  2. Como resultado, ele não funciona para versões giradas ou dimensionadas do modelo, pois uma mudança na forma / tamanho / cisalhamento etc. do modelo de objeto Wrt resultará em uma correspondência falsa.
  3. O método é ineficiente ao calcular a imagem de correlação de padrões para imagens médias a grandes, pois o processo é demorado.

Para evitar o problema causado pelos diferentes tamanhos do modelo e da imagem original, podemos usar a multiescala . No caso de onde, só porque as dimensões do seu modelo não correspondem às dimensões da região na imagem que você deseja corresponder, não significa que você não pode aplicar a correspondência de modelo.

Mecanismo de multiescala na correspondência de modelo



O processo de Multi scaling é o seguinte:

  1. Faça um loop sobre a imagem de entrada em várias escalas (ou seja, torne a imagem de entrada progressivamente menor e menor).
  2. Aplique a correspondência de modelo usando cv2.matchTemplate e acompanhe a correspondência com o maior coeficiente de correlação (junto com as coordenadas x, y da região com o maior coeficiente de correlação).
  3. Depois de percorrer todas as escalas, pegue a região com o maior coeficiente de correlação e use-a como sua região "correspondente".
import cv2 
import numpy as np 
   
img_rgb = cv2.imread('mainimage.jpg') 
   
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) 
   
template = cv2.imread('template',0) 
   
w, h = template.shape[::-1] 
found = None
  
for scale in np.linspace(0.2, 1.0, 20)[::-1]: 
  
    
    
    resized = imutils.resize(img_gray, width = int(img_gray.shape[1] * scale)) 
    r = img_gray.shape[1] / float(resized.shape[1]) 
   
    
    
    
    
    
    
    
    
    if resized.shape[0] < h or resized.shape[1] < w: 
            break
    found = (maxVal, maxLoc, r) 
   
(_, maxLoc, r) = found 
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r)) 
(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r)) 
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2) 
cv2.imshow("Image", image) 
cv2.waitKey(0) 

Explicação passo a passo do código acima:

  • Depois de armazenar a largura e a altura do modelo em w e r, inicializamos uma variável encontrada para manter o controle da região e escala da imagem com a melhor correspondência. A partir daí, começamos o loop pelas múltiplas escalas da imagem usando a função np.linspace. Esta função aceita três argumentos, o valor inicial, o valor final e o número de fatias iguais entre eles. Neste exemplo, começaremos com 100% do tamanho original da imagem e trabalharemos para baixo até 20% do tamanho original em pedaços de 20 por cento de tamanhos iguais.
  • Em seguida, redimensionamos a imagem de acordo com a escala atual e calculamos a proporção da largura antiga em relação à nova largura - como você verá mais tarde, é importante manter o controle dessa proporção. Fazemos uma verificação para garantir que a imagem de entrada seja maior do que a correspondência do nosso modelo. Se o modelo for maior, nossa chamada cv2.matchTemplate gerará um erro, portanto, apenas interrompemos o loop se for esse o caso.
  • Neste ponto, podemos aplicar a correspondência de modelo à nossa imagem redimensionada:
    • A função cv2.minMaxLoc pega nosso resultado de correlação e retorna uma 4-tupla que inclui o valor de correlação mínimo, o valor de correlação máximo, a (x, y) -coordenada do valor mínimo e a (x, y) -coordenada de o valor máximo, respectivamente. Estamos interessados ​​apenas no valor máximo e coordenar (x, y), portanto, mantemos os máximos e descartamos os mínimos.
  • Depois disso, inspecionamos as regiões da imagem que estão sendo correspondidas a cada iteração da escala. A partir daí, atualizamos nossa variável encontrada para acompanhar o valor máximo de correlação encontrado até agora, a (x, y) -coordenada do valor máximo, junto com a proporção da largura da imagem original para a largura da imagem redimensionada atual .
  • Depois de percorrer todas as escalas da imagem, desempacotamos nossa variável encontrada e, em seguida, calculamos nossas coordenadas inicial e final (x, y) de nossa caixa delimitadora. Cuidado especial é tomado para multiplicar as coordenadas da caixa delimitadora pela proporção para garantir que as coordenadas correspondam às dimensões originais da imagem de entrada.
  • Por fim, desenhamos nossa caixa delimitadora e a exibimos em nossa tela.

Este artigo foi contribuído por Pratima Upadhyay . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando contribute.geeksforgeeks.org ou enviar o seu artigo para contribute@geeksforgeeks.org. Veja o seu artigo que aparece na página principal do GeeksforGeeks e ajude outros Geeks.

Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.