Bonjour à tous. @best_not_best. Mon travail actuel consiste à implémenter la fonction de recommandation d'emploi du site de recrutement et à analyser le site à l'aide de Google Analytics et Adobe Analytics. (Le reste ne fait que publier des images d'animaux sur le Slack interne.)
Dans Last Advent Calendar, un jugement de similarité d'image a été effectué à l'aide du Deep Learning. La précision était bonne, mais la collecte des données d'entraînement est toujours un goulot d'étranglement ... Cette fois, je voudrais simplement comparer les deux images pour trouver la similitude des images.
Comparez les similitudes des images ci-dessous. L'image est récupérée auprès de l'enseignant Google. J'ai choisi une image de face pour une meilleure précision.
Image de comparaison
nom de fichier | image | La description |
---|---|---|
05.png | Chien Shiba (mignon) |
Comparaison
nom de fichier | image | La description |
---|---|---|
01.png | Daxfund (mignon) | |
02.png | Corgi (mignon) | |
03.png | Golden retriever (mignon) | |
04.png | Chien Shiba (mignon) | |
06.png | Labrador retriever (mignon) |
Si la similitude entre 05.png et 04.png, qui sont de la même race de chien, est élevée, c'est une réussite.
hist_matching.py
feature_detection.py
images
├─ 01.png
├─ 02.png
├─ 03.png
├─ 04.png
├─ 05.png
└─ 06.png
En gros, c'est une méthode de comparaison par teinte. Voir ci-dessous pour plus de détails.
La conversion de l'échelle de gris n'est pas effectuée car la comparaison est basée sur la teinte. De plus, la taille de l'image est uniformément convertie en 200 px x 200 px à des fins de comparaison.
hist_matching.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""hist matching."""
import cv2
import os
TARGET_FILE = '05.png'
IMG_DIR = os.path.abspath(os.path.dirname(__file__)) + '/images/'
IMG_SIZE = (200, 200)
target_img_path = IMG_DIR + TARGET_FILE
target_img = cv2.imread(target_img_path)
target_img = cv2.resize(target_img, IMG_SIZE)
target_hist = cv2.calcHist([target_img], [0], None, [256], [0, 256])
print('TARGET_FILE: %s' % (TARGET_FILE))
files = os.listdir(IMG_DIR)
for file in files:
if file == '.DS_Store' or file == TARGET_FILE:
continue
comparing_img_path = IMG_DIR + file
comparing_img = cv2.imread(comparing_img_path)
comparing_img = cv2.resize(comparing_img, IMG_SIZE)
comparing_hist = cv2.calcHist([comparing_img], [0], None, [256], [0, 256])
ret = cv2.compareHist(target_hist, comparing_hist, 0)
print(file, ret)
Est-ce qu'il consomme de la mémoire? Erreur de segmentation: 11
ou python (18114,0x7fff7a45b000) malloc: *** erreur pour l'objet 0x102000e00: somme de contrôle incorrecte pour l'objet libéré - l'objet a probablement été modifié après avoir été libéré.
Il est rarement affiché. Je n'ai pas trouvé de solution (désolé), mais lorsqu'il s'agit d'un grand nombre d'images, il semble préférable de réduire le nombre d'images de comparaison et d'effectuer plusieurs traitements.
Résultat d'exécution
TARGET_FILE: 05.png
01.png 0.3064316801821619
02.png -0.09702013809004943
03.png 0.5273343981076624
04.png 0.5453261576844468
06.png 0.1256772923432995
Pour exactement la même image, la similitude est de 1. Vous pouvez voir que la similitude entre 05.png et 04.png est élevée. Il était surprenant que le degré de similitude avec 01.png soit élevé.
2 Extrayez les points caractéristiques de l'image et comparez leurs distances. J'ai évoqué ce qui suit.
La conversion de l'échelle de gris est effectuée pour améliorer la précision d'extraction. Comme dans la section précédente, la taille de l'image est uniformément convertie en 200 px x 200 px à des fins de comparaison.
feature_detection.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""feature detection."""
import cv2
import os
TARGET_FILE = '05.png'
IMG_DIR = os.path.abspath(os.path.dirname(__file__)) + '/images/'
IMG_SIZE = (200, 200)
target_img_path = IMG_DIR + TARGET_FILE
target_img = cv2.imread(target_img_path, cv2.IMREAD_GRAYSCALE)
target_img = cv2.resize(target_img, IMG_SIZE)
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
# detector = cv2.ORB_create()
detector = cv2.AKAZE_create()
(target_kp, target_des) = detector.detectAndCompute(target_img, None)
print('TARGET_FILE: %s' % (TARGET_FILE))
files = os.listdir(IMG_DIR)
for file in files:
if file == '.DS_Store' or file == TARGET_FILE:
continue
comparing_img_path = IMG_DIR + file
try:
comparing_img = cv2.imread(comparing_img_path, cv2.IMREAD_GRAYSCALE)
comparing_img = cv2.resize(comparing_img, IMG_SIZE)
(comparing_kp, comparing_des) = detector.detectAndCompute(comparing_img, None)
matches = bf.match(target_des, comparing_des)
dist = [m.distance for m in matches]
ret = sum(dist) / len(dist)
except cv2.error:
ret = 100000
print(file, ret)
Dans de rares cas, j'utilise "essayer sauf" pour cracher "cv2.error". J'ai essayé la méthode d'extraction avec AKAZE et ORB.
Résultat d'exécution (AKAZE)
TARGET_FILE: 05.png
01.png 143.925
02.png 134.05
03.png 140.775
04.png 127.8
06.png 148.725
Résultat d'exécution (ORB)
TARGET_FILE: 05.png
01.png 67.59139784946237
02.png 58.60931899641577
03.png 59.354838709677416
04.png 53.59498207885304
06.png 63.55913978494624
Puisque la distance est calculée, la valeur de la même image exacte est 0, et plus la valeur est petite, plus la similitude est élevée. Dans les deux méthodes implémentées, la similitude entre 05.png et 04.png est élevée comme dans la section précédente.