2011-09-29 3 views
2

Je travaille sur une tâche concernant la conversion d'une image en niveaux de gris en image binaire à 1 bit par le tramage. J'essaie une matrice 4x4 simple qui rendra l'image 16 fois plus grande que l'original.Comment améliorer l'efficacité de cette itération numpy?

dithering_matrix = array([[ 0, 8, 2, 10], 
          [12, 4, 14, 6], 
          [ 3, 11, 1, 9], 
          [15, 7, 13, 5]], dtype=uint8) 
split_num = dithering_matrix.size + 1 

Je lis à im ndarray et a fait les choses suivantes: une image 512x512

output = list() 
for row in im: 
    row_output = list() 
    for pixel in row: 
     pixel_matrix = ((pixel/(256/split_num)) > dithering_matrix) * 255 
     row_output.append(pixel_matrix) 
    output.append(hstack(tuple(row_output))) 
output_matrix = vstack(tuple(output)) 

je trouve qu'il a fallu 8-10s à la sortie et je pense que la boucle de im ci-dessus passé beaucoup de temps. Dans certains logiciels, la même opération était généralement effectuée en un éclair. Alors est-il possible d'améliorer l'efficacité?


MISE À JOUR: @Ignacio Vazquez-Abrams Je ne suis pas vert fimiliar avec profileur :(J'ai essayé cprofile et le résultat est étrange

  1852971 function calls (1852778 primitive calls) in 9.127 seconds 

    Ordered by: internal time 
    List reduced from 561 to 20 due to restriction <20> 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 6.404 6.404 9.128 9.128 a1.1.py:10(<module>) 
     513 0.778 0.002 0.778 0.002 {numpy.core.multiarray.concatenate 
} 
    262144 0.616 0.000 1.243 0.000 D:\Python27\lib\site-packages\nump 
y\core\shape_base.py:6(atleast_1d) 
    262696 0.260 0.000 0.261 0.000 {numpy.core.multiarray.array} 
    262656 0.228 0.000 0.487 0.000 D:\Python27\lib\site-packages\nump 
y\core\numeric.py:237(asanyarray) 
     515 0.174 0.000 1.419 0.003 {map} 
    527019 0.145 0.000 0.145 0.000 {method 'append' of 'list' objects 
} 

La ligne 10 de A1.1.. . py est la première ligne from numpy import * (tous les commentaires avant que) qui me déconcerte vraiment

+0

Que dit votre profileur? –

Répondre

7

Si vous utilisez le Kronecker product pour transformer chaque pixel dans une sous-matrice 4x4, qui va vous permettre de se débarrasser des boucles Python:

im2 = np.kron(im, np.ones((4,4))) 
dm2 = np.tile(dithering_matrix,(512,512)) 
out2 = ((im2/(256/split_num)) > dm2) * 255 

Sur mon ordinateur, c'est environ 20 fois plus rapide que votre version.

+0

im2 n'est pas utilisé dans les calculs ultérieurs. faute de frappe? – unutbu

+0

@unutbu: Bonne prise. Fixé. – NPE

Questions connexes