[PYTHON] Comparons les deux images et recherchons les erreurs

Essayez de trouver des erreurs en utilisant OpenCV et Python.

Préparation

Tout d'abord, créez une image pour trouver des erreurs. C'est difficile à faire, donc cette fois je vais emprunter l'image de la page web Illustration de recherche d'erreur d'entraînement cérébral 01 (débutant) ..

Et comme cette image est connectée verticalement à l'image A et à l'image B, elle est divisée en parties supérieure et inférieure. En plus de le diviser en deux, convertissez-le au format PNG pour le gérer avec OpenCV.

convert -crop 100%x50% image02.gif image02.png

Cela créera les fichiers divisés supérieur et inférieur iamge02-0.png et image02-1.png, et vous êtes prêt à partir.

Puisque les étiquettes sont écrites dans l'image comme "A" dans l'image supérieure et "B" dans l'image inférieure, les noms de fichier seront changés en image02A.png et image02B.png.

convert image02.gif image02.Vous pouvez le png et le diviser avec python.



```python
import cv2

img = cv2.imread('img/image02.png')
height, width, _ = img.shape
imageA = img[0:round(height/2), :]
imageB = img[round(height/2):, :]
cv2.imwrite('img/image02A.png', imageA)
cv2.imwrite('img/image02B.png', imageB)

Trouvez la différence 1

Chargez une image A et une image B et essayez la détection de fonction.

def matchAB(fileA, fileB):
    #Chargement des images
    imgA = cv2.imread(fileA)
    imgB = cv2.imread(fileB)

    #Conversion de gris
    grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)

    #Extraction de la quantité de fonction AKAZE
    akaze = cv2.AKAZE_create()
    kpA, desA = akaze.detectAndCompute(grayA, None)
    kpB, desB = akaze.detectAndCompute(grayB, None)

    #Définition et imagerie BFMatcher
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = bf.match(desB, desB)
    matches = sorted(matches, key=lambda x: x.distance)
    matched_image = cv2.drawMatches(imgA, kpA, imgB, kpB, matches, None, flags=2)
    
    #afficher
    plt.imshow(cv2.cvtColor(matched_image, cv2.COLOR_BGR2RGB))
    plt.show()

Figure_001.png

Évidemment, la méthode ci-dessus marquerait les «endroits correspondants», mais ce n'est pas bon car il n'y a que 5 mauvais endroits.

Trouvez la différence 2

Quelle est la recherche d'erreurs en premier lieu? En d'autres termes, lorsque les deux images sont superposées, les contours des images dessinées sur chacune peuvent être légèrement différents.

Considérant la possibilité que l'image A et l'image B soient légèrement désalignées, nous avons décidé de trouver la position où la fenêtre créée en divisant l'image A correspond le mieux à l'image B et de créer une image différente. fait.

def matchAB(fileA, fileB):
    #Chargement des images
    imgA = cv2.imread(fileA)
    imgB = cv2.imread(fileB)

    #Conversion de gris
    grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)

    #Obtenir la taille de l'image
    height, width = grayA.shape
    #Faire une image partielle et faire correspondre
    result_window = np.zeros((height, width), dtype=imgA.dtype)
    for start_y in range(0, height-100, 50):
        for start_x in range(0, width-100, 50):
            window = grayA[start_y:start_y+100, start_x:start_x+100]
            match = cv2.matchTemplate(grayB, window, cv2.TM_CCOEFF_NORMED)
            _, _, _, max_loc = cv2.minMaxLoc(match)
            matched_window = grayB[max_loc[1]:max_loc[1]+100, max_loc[0]:max_loc[0]+100]
            result = cv2.absdiff(window, matched_window)
            result_window[start_y:start_y+100, start_x:start_x+100] = result

	plt.imshow(result_window)

Avec cela, il s'est avéré qu'il y avait une position avec une grande différence.

Figure_002.png

Poursuite de la recherche des différences 2

Donc, cette fois, je vais prendre les coordonnées de la «position où il y a une différence» dans l'image de différence et essayer de la superposer sur l'image d'origine. Spécifiquement, les valeurs de coordonnées sont captées en extrayant le contour de la "position avec une différence", et un carré est dessiné sur l'image d'origine sur la base des valeurs de coordonnées.

def matchAB(fileA, fileB):
    #Chargement des images
    imgA = cv2.imread(fileA)
    imgB = cv2.imread(fileB)

    #Conversion de gris
    grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)

    #Obtenir la taille de l'image
    height, width = grayA.shape
    #Faire une image partielle et faire correspondre
    result_window = np.zeros((height, width), dtype=imgA.dtype)
    for start_y in range(0, height-100, 50):
        for start_x in range(0, width-100, 50):
            window = grayA[start_y:start_y+100, start_x:start_x+100]
            match = cv2.matchTemplate(grayB, window, cv2.TM_CCOEFF_NORMED)
            _, _, _, max_loc = cv2.minMaxLoc(match)
            matched_window = grayB[max_loc[1]:max_loc[1]+100, max_loc[0]:max_loc[0]+100]
            result = cv2.absdiff(window, matched_window)
            result_window[start_y:start_y+100, start_x:start_x+100] = result

    #Extrayez le contour de l'image de différence créée à la suite de la mise en correspondance et placez-la dans un carré
    _, result_window_bin = cv2.threshold(result_window, 127, 255, cv2.THRESH_BINARY)
    _, contours, _ = cv2.findContours(result_window_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    imgC = imgA.copy()
    for contour in contours:
        min = np.nanmin(contour, 0)
        max = np.nanmax(contour, 0)
        loc1 = (min[0][0], min[0][1])
        loc2 = (max[0][0], max[0][1])
        cv2.rectangle(imgC, loc1, loc2, 255, 2)

    #Afficher l'image
    plt.subplot(1, 3, 1), plt.imshow(cv2.cvtColor(imgA, cv2.COLOR_BGR2RGB)), plt.title('A'), plt.xticks([]), plt.yticks([])
    plt.subplot(1, 3, 2), plt.imshow(cv2.cvtColor(imgB, cv2.COLOR_BGR2RGB)), plt.title('B'), plt.xticks([]), plt.yticks([])
    plt.subplot(1, 3, 3), plt.imshow(cv2.cvtColor(imgC, cv2.COLOR_BGR2RGB)), plt.title('Answer'), plt.xticks([]), plt.yticks([])
    plt.show()

Figure_003.png

L'image est petite et difficile à voir, mais il semble que 5 erreurs peuvent être suggérées sauf pour la partie de l'étiquette avec A ou B en haut à gauche.

Résumé

Il s'est avéré qu'il était possible de résoudre le quiz de recherche d'erreur en créant une image de différence à l'aide d'OpenCV.

Code du jour

Recommended Posts

Comparons les deux images et recherchons les erreurs
Comparons la transformée de Fourier de la source sonore synthétisée et le composite de la transformée de Fourier
Essayons Linux pour la première fois
Comparez la vitesse d'ajout et de carte Python