Une grande image (300 * 300 pixels) divisée en 3 zones. 2 petits (AAA.png et BBB.png) sont des portions de la grande image.
3-areas.png
AAA.png em>
BBB.png
Je veux savoir dans quelles zones ils se trouvent, c'est-à-dire trouver de petites images dans une vue d'ensemble. La sortie idéale serait: "AAA.png est à gauche"; "BBB.png est dans la bonne".
J'ai ces codes en cours d'exécution:
big_pic = cv2.imread("c:\\TEM\\3-areas.png") list_of_areas = { left : [0,300, 0,100], mid : [0,300, 100,200], right : [0,300, 200,300]} small_picture_folder = "C:\\TEM\\" small_pictures = [] root, dirs, files = os.walk(small_picture_folder).next() for path, subdirs, files in os.walk(root): for f in files: if ""AAA"" in f or ""BBB"" in f: small_pictures.append(small_picture_folder + f) for key, value in list_of_areas.iteritems(): for y,y1,x,x1 in value: target_area = big_pic[y:y1, x:x1]
Je veux le simplifier en créant des boucles. Ce que j'ai essayé:
import cv2, os import numpy as np big_pic = cv2.imread("c:\\TEM\\3-areas.png") left_area = big_pic[0:300, 0:100] # [y,y1 : x,x1] mid_area = big_pic[0:300, 100:200] right_area = big_pic[0:300, 200:300] AAA = cv2.imread('C:\\TEM\\AAA.png') AAA_res = cv2.matchTemplate(left_area,AAA,cv2.TM_CCOEFF_NORMED) threshold = 0.99 AAA_loc = np.where(AAA_res >= threshold) a_x_cor = list(AAA_loc[0]) a_y_cor = list(AAA_loc[1]) print a_x_cor, a_y_cor BBB = cv2.imread('C:\\TEM\\BBB.png') BBB_res = cv2.matchTemplate(right_area,BBB,cv2.TM_CCOEFF_NORMED) BBB_loc = np.where(BBB_res >= threshold) b_x_cor = list(BBB_loc[0]) b_y_cor = list(BBB_loc[1]) print b_x_cor, b_y_cor
La ligne "for y, y1, x, x1 in value:" donne une erreur: "TypeError: 'int' object is not iterable."
Quelle serait la meilleure façon d'y parvenir? Merci.
3 Réponses :
Voici comment détecter plusieurs modèles et recadrer le ROI
import cv2 import numpy as np templates = [] templ_shapes = [] threshold = 0.9 # get 1st template temp1 =cv2.imread("YourImagePath1.png",cv2.IMREAD_GRAYSCALE) templates.append(temp1) templ_shapes.append(temp1.shape[:: -1]) # get 2nd template temp2 =cv2.imread("YourImagePath2.png",cv2.IMREAD_GRAYSCALE) templates.append(temp2) templ_shapes.append(temp2.shape[:: -1]) # templ_shapes contains (width and height) dimensions of your templates # so use them to display bounding box # detect and get ROI target =cv2.imread("YourImage_Target_Path.png",cv2.IMREAD_GRAYSCALE) count = 0 for template in templates: result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) loc = np.where(result >= threshold) for pt in zip(*loc[::-1]): # pt is the top left corner of the template location so pt[0] + templ_shapes[count][0] is the X bottom right ... # templ_shapes[count][0] is the width and templ_shapes[count][1] is height cv2.rectangle(target, pt, (pt[0] + templ_shapes[count][0], pt[1] + templ_shapes[count][1]), (0, 0, 255), 2) roi = target[pt[1]:pt[1] + templ_shapes[count][1] ,pt[0] :pt[0] +templ_shapes[count][0]] count+=1
Merci pour l'aide. Mais les images sont de tailles différentes.
Définissez donc la 1ère et la n-ième taille et utilisez-les dans votre boucle dans le même ordre.
Nous vous remercions de votre suivi. mais je ne comprends toujours pas ...
J'ai édité ma réponse. vous pouvez vérifier la modification
ce que vous avez essayé de faire est un algorithme de détection d'objets. jetez un œil à ce tutoriel opencv. https://docs.opencv.org/2.4/doc/ tutoriels / features2d / feature_homography / feature_homography.html pour améliorer la vitesse, essayez de remplacer Surf keypoint par orb keypoint (pour votre cas d'utilisation, ce sera probablement assez bon, (si vous faites cela, n'oubliez pas de modifier la norme de L2 à Hamming)) c'est une généralisation de votre problème. Cordialement
Dans votre boucle externe, en itérant les entrées du dictionnaire
for key, value in list_of_areas.iteritems(): y, y1, x, x1 = value target_area = big_pic[y:y1, x:x1]
la valeur
est une liste de quatre entiers, par exemple [0, 300, 0, 100]
. Ainsi, lorsque vous essayez maintenant d'itérer cette liste en utilisant
for y, y1, x, x1 in value:
, vous obtiendrez quatre itérations, et à chaque itération, exactement un élément de la liste sera "retourné" à la fois . Mais maintenant, vous essayez d'attribuer cette valeur entière unique "retournée" à quatre variables simultanément par
for (...) in value:
d'où l'erreur! Donc, de mon point de vue, la solution la plus simple serait de sauter la boucle interne et d'assigner directement tous les éléments de la valeur
à vos quatre variables, comme ceci:
for key, value in list_of_areas.iteritems():
J'espère que cela vous aidera!
Un autre conseil général: il semble que vous utilisez Python 2 (
print
,iteritems
). Il est utile de le mentionner, par exemple en ajoutant la balisepython-2.x
. Pour que les gens ne soient pas confus, car ils se demandent pourquoi il n'y a pas deiteritems
pour les dictionnaires ...@HansHirse, merci! envisageriez-vous d'en faire une réponse afin que nous puissions clore cette question?