web-dev-qa-db-fra.com

Comment trouver une image contenue dans une image?

Je construis actuellement ce qui équivaut essentiellement à un croisement entre un moteur de recherche et une galerie de bandes dessinées Web qui se concentre sur la citation de sources et sur le mérite des auteurs.

J'essaie de trouver un moyen de rechercher une image pour y trouver des personnages.

Par exemple:

cyanide and happiness

En supposant que le caractère rouge et le caractère vert soient enregistrés en tant que Red Man et Green Man, comment puis-je déterminer si une image contient l'un ou l'autre?.

Cela n'a pas besoin d'avoir une reconnaissance à 100% ou quoi que ce soit, c'est plus une fonctionnalité supplémentaire que je voudrais créer, je ne sais pas par où commencer. J'ai fait beaucoup de recherches sur Google pour la reconnaissance d'image, mais je n'ai pas trouvé grand-chose.

Pour ce que ça vaut, je préfère le faire en utilisant Python.

28
Adam

Pour tous ceux qui tomberont dessus à l'avenir.

Cela peut être fait avec correspondance de modèle . Pour résumer (à ma connaissance), la correspondance de modèles recherche une correspondance exacte d'une image dans une autre image.

Voici un exemple de la façon de le faire dans Python:

import cv2

method = cv2.TM_SQDIFF_NORMED

# Read the images from the file
small_image = cv2.imread('small_image.png')
large_image = cv2.imread('large_image.jpeg')

result = cv2.matchTemplate(small_image, large_image, method)

# We want the minimum squared difference
mn,_,mnLoc,_ = cv2.minMaxLoc(result)

# Draw the rectangle:
# Extract the coordinates of our best match
MPx,MPy = mnLoc

# Step 2: Get the size of the template. This is the same size as the match.
trows,tcols = small_image.shape[:2]

# Step 3: Draw the rectangle on large_image
cv2.rectangle(large_image, (MPx,MPy),(MPx+tcols,MPy+trows),(0,0,255),2)

# Display the original image with the rectangle around the match.
cv2.imshow('output',large_image)

# The image is only displayed if we call this
cv2.waitKey(0)
31
Moshe

Comme réponse de Moshe ne couvre que la correspondance avec un modèle qui n'est contenu qu'une seule fois dans l'image donnée. Voici comment faire correspondre plusieurs à la fois:

import cv2
import numpy as np

img_rgb = cv2.imread('mario.png')
template = cv2.imread('mario_coin.png')
w, h = template.shape[:-1]

res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)
threshold = .8
loc = np.where(res >= threshold)
for pt in Zip(*loc[::-1]):  # Switch collumns and rows
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)

cv2.imwrite('result.png', img_rgb)

(Remarque: j'ai changé et corrigé quelques "erreurs" qui étaient dans le code d'origine)

Résultat:

detect mario coins (before/after)

Source: https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_template_matching/py_template_matching. html

23
JeromeJ

OpenCV a une interface Python que vous pouvez regarder. Si les caractères ne changent pas trop, vous pouvez essayer d'utiliser la fonction matchTemplate .

Ici est leur tutoriel officiel (le tutoriel est écrit en utilisant l'interface C++, mais vous devriez pouvoir avoir une bonne idée de la façon d'utiliser la fonction dans Python = de lui).

1
mevatron