Les deux images recadrées sont ** automatiquement ** combinées pour que les coutures soient naturelles.
En partant des bords des images supérieure et inférieure, la zone est progressivement rétrécie et comparée. La zone avec le degré de correspondance le plus élevé est combinée en tant que zone commune.
--Lire au format oreiller
Cette fois, j'ai utilisé ʻImage.crop () `pour couper le format de l'oreiller.
Image.crop((Coordonnée X de l'extrémité gauche du découpage,Coordonnée y supérieure,Coordonnée x la plus à droite,Coordonnée y inférieure))
Notez que l'argument doit être spécifié sous forme de taple et que les ** parenthèses "(" ")" sont dupliquées **. Afin de réduire autant que possible la quantité de calcul, le plus petit du côté supérieur et du côté inférieur est défini comme zone de départ de la comparaison, et il est réduit de 1px. (Dans l'exemple de code, si l'image du haut est grande, la différence de hauteur est stockée dans la variable dif_h et utilisée pour spécifier les coordonnées supérieures de rognage.)
L'image recadrée est convertie au format opencv et les images sont comparées en utilisant cv2.matchTemplate ()
.
cv2.matchTemplate(Image à comparer 1,Image 2 à comparer,Mode de correspondance)
Il semble y avoir différents modes de correspondance, mais je pense que tout est OK (à quelques exceptions près) pour cette application, j'ai donc utilisé le standard de type cv2.TM_CCOEFF_NORMED
.
Puisque la sortie de matchTemplate est une image en échelle de gris (probablement) qui montre le degré de correspondance dans la lumière et l'obscurité, la valeur maximale = le résultat de l'évaluation correspondante de cette image est obtenue en utilisant cv2.minMaxLoc ()
.
cv2.minMaxLoc(Image en échelle de gris à évaluer)[1]
Comme pour la valeur de retour de minmaxLoc, la valeur maximale est stockée dans la seconde, donc la valeur maximale est retirée avec [1]. (Vous trouverez des détails sur la correspondance des modèles d'image sur cette page Est expliqué dans)
Répétez ce qui précède avec une instruction for tout en modifiant la zone pour trouver l'endroit où le résultat d'évaluation correspondant est maximisé.
J'ai cité cette page. https://note.nkmk.me/python-pillow-concat-images/
def get_concat_v(im1, im2):
dst = Image.new('RGB', (im1.width, im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
Dans l'image au format oreiller, créez une zone avec ʻImage.new () et collez l'image à connecter avec ʻImage.paste ()
.
Comme vous pouvez le voir en l'essayant, ** Plus la taille de l'image est grande, plus cela prend du temps **. Cette fois, elle est en niveaux de gris, et la plus petite de l'image supérieure et de l'image inférieure est définie comme taille de la zone de départ de comparaison. Bien que non adopté cette fois, je pense que la quantité de calcul peut être réduite en redimensionnant et en comparant les images, en limitant la zone à comparer et en mettant fin à la comparaison lorsqu'une certaine valeur d'évaluation est dépassée.
import numpy as np
from PIL import Image
import cv2
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def auto_img_concat_v(upper_img, under_img):
max_res_num = 0 #Enregistrer la valeur maximale du résultat d'évaluation correspondant
over_pixel = 0 #Enregistrez le nombre de pixels qui se chevauchent à l'évaluation de correspondance maximale
img_w = upper_img.width
upper_h = upper_img.height
under_h = under_img.height
compare_height = min(upper_h, under_h) #Nombre de pixels à comparer (hauteur)
#Si la hauteur de l'image ci-dessus est élevée, obtenez la différence (sinon 0)
dif_h = (upper_h - under_h) if upper_h > under_h else 0
for i in range(1, compare_height):
search_img = upper_img.crop((0, i + dif_h, img_w, upper_h)) #Découper l'image ci-dessus
target_img = under_img.crop((0, 0, img_w, compare_height - i)) #Découper l'image ci-dessous
search_np = np.array(search_img, dtype=np.uint8) #Convertir l'image en tableau (image du haut)
cv_search_img = cv2.cvtColor(search_np, cv2.COLOR_RGB2GRAY) #Échelle de gris (image du haut)
target_np = np.array(target_img, dtype=np.uint8) #〃 (ci-dessous l'image)
cv_target_img = cv2.cvtColor(target_np, cv2.COLOR_RGB2GRAY) #〃 (ci-dessous l'image)
res = cv2.matchTemplate(
cv_search_img, cv_target_img, cv2.TM_CCOEFF_NORMED) #Évaluation de correspondance (la sortie est une image en échelle de gris montrant une similitude)
res_num = cv2.minMaxLoc(res)[1] #Obtenez une évaluation correspondante numériquement
print(res_num, "\n", i)
if max_res_num < res_num: #Obtenez la valeur maximale du résultat d'évaluation correspondant
max_res_num = res_num
over_pixel = target_img.height #Obtenez le nombre de pixels qui se chevauchent à la valeur d'évaluation correspondante maximale
print("\n", max_res_num, "\n", over_pixel)
if max_res_num > 0.98: #Si la valeur d'évaluation est supérieure à un certain niveau, joindre le traitement
result_img = get_concat_v(upper_img.crop(
(0, 0, img_w, upper_h - over_pixel)), under_img) #Combinaison d'images
return result_img
else:
print("La combinaison d'images a échoué")
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#Fonction de concaténation d'images (direction verticale)
def get_concat_v(im1, im2):
dst = Image.new('RGB', (im1.width, im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if __name__ == "__main__":
upper = Image.open(r"C:\Users\aaa\Desktop\Danbo_upper.jpg ")
under = Image.open(r"C:\Users\aaa\Desktop\Danbo_under.jpg ")
concat_img = auto_img_concat_v(upper, under)
if concat_img:
concat_img.show()
J'ai pu bien combiner.
Il existe des problèmes tels qu'une grande quantité de calculs et une incompatibilité avec des images qui ne correspondent pas dans le sens horizontal. J'ai pu faire ce que je voulais faire pour le moment. À l'avenir, j'aimerais créer un outil qui connecte automatiquement les écrans défilés en combinaison avec pyautog.
Recommended Posts