2017-09-04 4 views
0

Je suis assez sûr que mes images sont en niveaux de gris qui devrait être monocanal mais je reçois cette erreur et je ne sais pas comment travailler avec ça. Ci-dessous est mon code: Je travaille pour accélérer mon code en créant une pyramide d'images pour chaque image. La mise à l'échelle des images au plus petit format permet d'obtenir une estimation approximative et de l'agrandir.erreur: (-210) warpMatrix doit être matrice à virgule flottante monocanal dans la fonction cv :: findTransformECC

import cv2 
import numpy as np 


path = "R:\\ProcessedPhoto_in_PNG\\" 
path1 = "R:\\AlignedPhoto_in_PNG_EUCLIDEAN\\" 

nol = 3 
warp_mode = cv2.MOTION_EUCLIDEAN 
if warp_mode == cv2.MOTION_HOMOGRAPHY : 
    warp = np.eye(3, 3, dtype=np.float32) 
else : 
    warp = np.eye(2, 3, dtype=np.float32) 


warp = np.dot(warp, np.array([[1, 1, 2], [1, 1, 2], [1/2, 1/2, 1]])**(1-nol)) 


# Specify the number of iterations. 
number_of_iterations = 5000; 

# Specify the threshold of the increment 
# in the correlation coefficient between two iterations 
termination_eps = 1e-10; 

# Define termination criteria 
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, number_of_iterations, termination_eps) 

def alignment(criteria, warp_mode, warp, nol): 

    for i in range(1770,1869): 
     for level in range(nol): 
      im = cv2.imread(path + 'IMG_1770.png') 
      im1 = cv2.imread(path + 'IMG_%d.png'%(i)) 

      sz = im1.shape 


      scale = 1/2**(nol-1-level) 

      im_1 = cv2.resize(im, None, fx= scale, fy = scale, interpolation=cv2.INTER_AREA) 
      im_2 = cv2.resize(im1, None, fx= scale, fy= scale, interpolation=cv2.INTER_AREA) 

      im_gray = cv2.cvtColor(im_1, cv2.COLOR_BGR2GRAY) 
      im1_gray = cv2.cvtColor(im_2, cv2.COLOR_BGR2GRAY) 

      # Run the ECC algorithm. The results are stored in warp_matrix. 
      warp = cv2.findTransformECC(im_gray, im1_gray, warp, warp_mode, criteria) 

      if level != nol-1: 
      # might want some error catching here to reset initial guess 
      # if your algorithm fails at some level of the pyramid 

      # scale up for the next pyramid level 
       warp = warp * np.array([[1, 1, 2], [1, 1, 2], [1/2, 1/2, 1]]) 

      if warp_mode == cv2.MOTION_HOMOGRAPHY : 
       # Use warpPerspective for Homography 
       im1_aligned = cv2.warpPerspective (im1, warp, (sz[1],sz[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP) 
      else : 
       # Use warpAffine for Translation, Euclidean and Affine 
       im1_aligned = cv2.warpAffine(im1, warp, (sz[1],sz[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP); 
      print(i) 
      cv2.imwrite(path1 + "AlignedEU_IMG_%d.png"%i , im1_aligned) 

alignment(criteria, warp_mode, warp, nol) 
+1

convertir la variable 'warp' taper 'np.float32', puis continuez –

Répondre

1

Il semble que votre matrice warp était à l'origine de type np.float32 mais vous faites une nouvelle multiplication matricielle avec np.dot avec une autre matrice non de np.float32 - ne pas spécifier un défaut de type à np.float64 - donc le résultat est promu à taper np.float64. Vous devez vous assurer que la seconde matrice est également de type np.float32. C'est pourquoi findTransformECC se plaint car il s'attend à ce que la matrice warp soit de type np.float32, d'où le message d'erreur. La meilleure façon de résoudre c'est d'abord créer votre deuxième matrice pour assurer la précision est maintenue avec np.float64, puis convertir à np.float32 avant la multiplication lorsque vous passez à np.dot:

# .... 
# .... 
nol = 3 
warp_mode = cv2.MOTION_EUCLIDEAN 
if warp_mode == cv2.MOTION_HOMOGRAPHY : 
    warp = np.eye(3, 3, dtype=np.float32) 
else : 
    warp = np.eye(2, 3, dtype=np.float32) 

# New - Create temporary placeholder for new matrix 
tmp = np.array([[1, 1, 2], [1, 1, 2], [1/2, 1/2, 1]])**(1-nol) 

# Matrix multiply with it but ensuring it's of type np.float32 
warp = np.dot(warp, tmp.astype(np.float32)) 

# .... 
# .... 
# Rest of your code follows 
+0

Puis-je vous poser des questions sur la fonction findtransformECC? J'ai vu en ligne beaucoup de l'exemple mentionné au sujet de cc comme ça « (cc, chaîne) = cv2.findTransformECC (im_gray, im1_gray, chaîne, warp_mode, critères) » Je n'obtiens pas ce qui est cc reportez-vous à fait .... Est-il nécessaire de mettre cela pour transformer la fonction ECC? * Désolé, je sais que c'est une question non liée à la poste * – SacreD

+1

La fonction renvoie un tuple de deux éléments. Vous n'avez pas besoin de faire cela mais vous voudrez accéder au deuxième élément du tuple, qui est la matrice de warp estimée décrivant la relation entre les images. Vous pouvez donc le laisser comme vous l'avez déjà fait, mais assurez-vous de faire 'warp [1]' après pour obtenir la matrice. Le premier élément du tuple est un code de retour déterminant le succès de l'estimation, mais si vos images sont bien définies, vous pouvez ignorer le code. Cependant, l'estimation initiale en entrée de la fonction est également mutée à son retour, vous ne pouvez donc pas la définir comme égale à quoi que ce soit. – rayryeng