OpenCV-Détecte les différences d'image similaires en Python

Chose que tu veux faire

Par exemple, vérifier l'apparence des documents OFFICE convertis en PDF avec un moteur de formatage différent. Je veux une image qui puisse être utilisée comme preuve pour que les gens puissent la comprendre. De plus, il est difficile de voir toutes les images, donc je vais donner une valeur numérique au degré de différence, et les gens ne vérifieront que celles qui présentent la grande différence.

Quoi préparer

--Environnement où s'exécute Python3

Ce n'est pas officiel, mais il existe un environnement OpenCV Python, donc je vais le mettre rapidement. pip install opencv-python Le numpy dépendant est également inclus.

https://pypi.org/project/opencv-python/

Code Python

diff_img.py


import pathlib
import cv2
import numpy as np

source_dir = pathlib.Path('source_img')
source_files = source_dir.glob('*.*')
target_dir = pathlib.Path('target_img')
result_dir = pathlib.Path('result_img')
log_file = result_dir / pathlib.Path('result.log')
kernel = np.ones((3, 3), np.uint8)

fs = open(log_file, mode='w')
for source_file in source_files:
    source_img = cv2.imread(str(source_file))
    target_file = target_dir / source_file.name
    target_img = cv2.imread(str(target_file))
    if target_img is None:
        fs.write(target_file + '...skipped.\n')
        continue
    max_hight = max(source_img.shape[0], target_img.shape[0])
    max_width = max(source_img.shape[1], target_img.shape[1])

    temp_img = source_img
    source_img = np.zeros((max_hight, max_width, 3), dtype=np.uint8)
    source_img[0:temp_img.shape[0], 0:temp_img.shape[1]] = temp_img

    temp_img = target_img
    target_img = np.zeros((max_hight, max_width, 3), dtype=np.uint8)
    target_img[0:temp_img.shape[0], 0:temp_img.shape[1]] = temp_img

    result_img = cv2.addWeighted(source_img, 0.5, target_img, 0.5, 0)

    source_img = cv2.cvtColor(source_img, cv2.COLOR_BGR2GRAY)
    target_img = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY)
    img = cv2.absdiff(source_img, target_img)
    rtn, img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
    img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)
    result_img = cv2.drawContours(result_img, contours, -1, (0, 0, 255))
    score = 0
    for contour in contours:
        score += cv2.contourArea(contour)
    score /= max_hight * max_width
    fs.write(target_file.name + ', ' + str(score) + '\n')
    diff_file = result_dir / source_file.name
    cv2.imwrite(str(diff_file), result_img)
fs.close()

Pour la méthode de comparaison, consultez cet article [C'était trop difficile de trouver l'erreur à Saiseriya, donc je l'ai résolue avec l'aide d'un adulte] (http://kawalabo.blogspot.com/2014/11/blog-post.html) http://kawalabo.blogspot.com/2014/11/blog-post.html C'est en rapport avec.

Le score est simplement calculé en prenant la zone de la zone où la différence a été détectée, en la divisant par la zone de l'image entière et en la crachant dans le journal avec le nom du fichier.

result.log


test-1.png, 0.01231201710816777
test-2.png, 0.0084626793598234

Ajouté le 7 janvier 2020

Activé pour comparer même si la taille de l'image à comparer est différente.

Exemple d'exécution

test-1.png Bien qu'il s'agisse d'un tableau similaire, la largeur de la cible de comparaison était un peu plus petite et la marge était plus grande.

Recommended Posts

OpenCV-Détecte les différences d'image similaires en Python
opencv-python Introduction au traitement d'image