3 votes

Souligner les différences de forme entre deux images par un changement de couleur

J'essaie de rendre mon code plus robuste par rapport à ma première révision. Le but est de générer une image unique finale en comparant l'image A et l'image B pour obtenir l'image C. Actuellement, je travaille pour montrer les différences dans les images composées de lignes noires. Dans ce cas, ce serait l'image A et B. J'ai une méthode de travail avec le redimensionnement de l'image et le prétraitement effectué (redimensionnement, réduction du bruit, etc). Le code que j'ai développé pour montrer les différences (image C) est présenté ci-dessous :

np_image_A = np.array(image_A)
np_image_B = np.array(image_B)

# Set the green and red channels respectively to 0. Leaves a blue image
np_image_A[:, :, 1] = 0
np_image_A[:, :, 2] = 0
# Set the blue channels to 0.
np_image_B[:, :, 0] = 0
# Add the np images after color modification
overlay_image = cv2.add(np_image_A, np_image_B)

Pour l'instant, je ne pense pas que cette méthode soit suffisamment robuste et qu'elle puisse entraîner des problèmes. Je veux utiliser une méthode qui montre les différences entre les images A et B dans une seule image. Et l'image A se voit attribuer une couleur pour les différences et l'image B se voit attribuer une autre couleur (comme le bleu et le rouge, et le noir représente les zones qui sont identiques). Ceci est mis en évidence dans l'image ci-dessous : image differences

Pour remédier à cela, j'ai reçu de l'aide de StackOverflow et j'ai maintenant une méthode qui utilise le masquage et la fusion dans OpenCV. Le problème que j'ai trouvé est que seuls les changements additifs sont montrés, et si un élément est supprimé, il n'est pas montré dans l'image de différence.

Le problème avec ce code est qu'il produit ce qui se trouve dans l'image D et non dans l'image C. J'ai essayé d'exécuter ce bloc de code deux fois, en changeant img = imageA et imageB, mais la sortie est mélangée pour une raison quelconque.

    # load image A as color image
    img = cv2.imread('1a.png')
    # load A and B as grayscale
    imgA = cv2.imread('1a.png',0)
    imgB = cv2.imread('1b.png',0)
    # invert grayscale images for subtraction
    imgA_inv = cv2.bitwise_not(imgA)
    imgB_inv = cv2.bitwise_not(imgB)
    # subtract the original (A) for the new version (B)
    diff = cv2.subtract(imgB_inv, imgA_inv)
    # split color image A into blue,green,red color channels
    b,g,r = cv2.split(img)
    # merge channels back into image, subtracting the diff from
    # the blue and green channels, leaving the shape of diff red
    res = cv2.merge((b-diff,g-diff,r))
    # display result
    cv2.imshow('Result',res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Le résultat que je recherche est l'image C, mais actuellement je ne peux obtenir que l'image D avec le code révisé.

Edit : Voici les images de test A et B à utiliser. Test Image A Test Image B

1voto

Jack Points 2525

Vous y êtes presque, mais vous devez créer deux diffs séparés. Un diff représente les pixels noirs qui sont dans A mais pas dans B, et l'autre diff représente les pixels noirs qui sont dans B mais pas dans A.

Résultat : enter image description here

import cv2
import numpy as np

# load A and B as grayscale
imgA = cv2.imread('1a.png',0)
imgB = cv2.imread('1b.png',0)
# invert grayscale images for subtraction
imgA_inv = cv2.bitwise_not(imgA)
imgB_inv = cv2.bitwise_not(imgB)

# create two diffs, A - B and B - A
diff1 = cv2.subtract(imgB_inv, imgA_inv)
diff2 = cv2.subtract(imgA_inv, imgB_inv)
# create a combined image of the two inverted 
combined = cv2.add(imgA_inv, imgB_inv)
combined_inv = cv2.bitwise_not(combined)
# convert the combined image back to rbg, 
# so that we can modify individual color channels
combined_rgb = cv2.cvtColor(combined_inv, cv2.COLOR_GRAY2RGB)
# split combined image into blue,green,red color channels
b,g,r = cv2.split(combined_rgb)
# merge channels back into image, adding the first diff to
# the red channel and the second diff to the blue channel
res = cv2.merge((b+diff2,g,r+diff1))
# display result
cv2.imshow('Result',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X