Trouver la similitude d'image avec Python + OpenCV

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.

Choses à faire

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 05 Chien Shiba (mignon)

Comparaison

nom de fichier image La description
01.png 01 Daxfund (mignon)
02.png 02 Corgi (mignon)
03.png 03 Golden retriever (mignon)
04.png 04 Chien Shiba (mignon)
06.png 06 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.

environnement

Structure du répertoire

hist_matching.py
feature_detection.py
images
 ├─ 01.png
 ├─ 02.png
 ├─ 03.png
 ├─ 04.png
 ├─ 05.png
 └─ 06.png

Validation 1: Comparez l'histogramme

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é.

Vérification 2: correspondance des points caractéristiques

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.

Résumé

Recommended Posts

Trouver la similitude d'image avec Python + OpenCV
Édition d'image avec python OpenCV
[Python] Utilisation d'OpenCV avec Python (filtrage d'image)
[Python] Utilisation d'OpenCV avec Python (transformation d'image)
Traitement d'image avec Python et OpenCV [Tone Curve]
Acquisition d'images depuis une caméra avec Python + OpenCV
Traitement d'image léger avec Python x OpenCV
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de "lisser" l'image avec Python + OpenCV
J'ai essayé de "différencier" l'image avec Python + OpenCV
Comment recadrer une image avec Python + OpenCV
[Petite histoire] Tester la génération d'images avec Python / OpenCV
Traitement d'image avec Python (partie 2)
"Traitement Apple" avec OpenCV3 + Python3
Capture de caméra avec Python + OpenCV
[Python] Utilisation d'OpenCV avec Python (basique)
Tri des fichiers image avec Python (2)
Tri des fichiers image avec Python (3)
Traitement d'image avec Python (partie 1)
Tweet avec image en Python
Tri des fichiers image avec Python
Traitement d'image avec Python (3)
Détection de visage avec Python + OpenCV
Obtenez des fonctionnalités d'image avec OpenCV
Utiliser OpenCV avec Python @Mac
Reconnaissance d'image avec Keras + OpenCV
[Python] Traitement d'image avec scicit-image
[OpenCV / Python] J'ai essayé l'analyse d'image de cellules avec OpenCV
Génération d'images JPEG en spécifiant la qualité avec Python + OpenCV
Créez diverses vidéos Photoshop avec Python + OpenCV ② Créez une image fixe Photoshop
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
Découpez une image avec python
Principes de base du traitement d'image en temps réel avec opencv
Réseau neuronal avec OpenCV 3 et Python 3
[Python] Utilisation d'OpenCV avec Python (détection des bords)
Trouvez la distance d'édition (distance de Levenshtein) avec python
Traitement d'image avec la binarisation Python 100 knocks # 3
Programmation facile Python + OpenCV avec Canopy
Coller le png avec le canal alpha comme une image transparente avec Python / OpenCV
Essayez la reconnaissance faciale avec python + OpenCV
Découpez le visage avec Python + OpenCV
Reconnaissance faciale avec caméra avec opencv3 + python2.7
Charger une image gif avec Python + OpenCV
Essayez de brouiller l'image avec opencv2
Utiliser OpenCV avec Python 3 dans Window
100 traitement d'image par Python Knock # 2 Échelle de gris
Dessinez une illustration avec Python + OpenCV
Introduction à l'analyse d'image opencv python
Suivre les balles de baseball avec Python + OpenCV
Segmentation basée sur un graphique avec Python + OpenCV
Envoyer l'image avec python et enregistrer avec php
[Python] Lecture facile des fichiers image du numéro de série avec OpenCV
Dessinez une flèche (vecteur) avec opencv / python
Etude de base d'OpenCV avec Python
Génération d'images dégradées avec Python [1] | np.linspace
Interpolation automatique des images avec OpenCV et Python (méthode de marche rapide, Navier-Stokes)
Traitement d'image par Python 100 knock # 10 filtre médian
Détection de visage avec Python + OpenCV (rotation invariante)
mail html avec image à envoyer avec python
Créez une image factice avec Python + PIL.
Enregistrer la vidéo image par image avec Python OpenCV