Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > fr.comp.lang.python > #3056

Re: problème de copie ? shallow - deep

From marc.marc@marc.org
Newsgroups fr.comp.lang.python
Subject Re: problème de copie ? shallow - deep
Date 2018-02-01 21:19 +0100
Organization Aioe.org NNTP Server
Message-ID <p4vsod$cm3$1@gioia.aioe.org> (permalink)
References <5a732113$0$3313$426a74cc@news.free.fr> <871si4zk9f.fsf@universite-de-strasbourg.fr.invalid>

Show all headers | View raw


Bonsoir,
en effet comme le dit Alain l'objet retourné par mpl.imread est un array 
numpy. Si vous faites:
print(originale.__class__) la réponse est <type 'numpy.ndarray'>.
print(originale.shape) la réponse est par exemple (800,800,3), un 
tableau tri dimensionnel, en fait 3 images de 800x800 pixels (ici) qui 
correspondent aux valeurs rouge, vert, bleu (RGB en anglais) de l'image 
originale - bon ça peut dépendre de l'image originale.
Même si l'utilisation du premier indice seul marche dans votre cas, il 
vaut mieux de mon point de vue utiliser les 3 indices, par exemple :

for ligne in range(hauteur//2):
     tmp = copy.copy(image[ligne,:,:])
     image[ligne,:,:] = image[hauteur-ligne-1,:,:]
     image[hauteur-ligne-1,:,:] = tmp

Vous pouvez vous amuser à remplacer le dernier : de chaque tableau par 
l'entier 2 et vous verrez que l'effet miroir ne s'est fait que sur la 
composante bleue de l'image.

Quand on écrit : tmp = image[ligne] travailler sur tmp ou sur 
image[ligne] c'est pareil je suis d'accord avec Alain.
Pour créer une nouvelle instance d'array numpy on peut utiliser 
copy.copy ou bien np.copy ( peut-être y-a-t-il une différence je ne sais 
pas. J'utilise le second ).
Mais écrire :
tmp = image[ligne]*1
produit aussi un nouvel array ( mais personnellement je préfère la copie 
explicite avec np.copy )

Quand on écrit : image[ligne,:,:] = image[hauteur-ligne-1,:,:] on 
remplace le contenu de la ligne numéro "ligne" de l'image par celui de 
la ligne numéro  "hauteur-ligne-1", et ce pour chacune des 3 images RGB.
Il ne s'agit pas de pointeurs.
De la même manière que pour un tableau 1D en C si on écrit a[3] = a[4], 
même si a est un pointeur, sauf que là c'est à 3 ( généralement à N ) 
dimensions. En C sauf erreur il faudrait un tableau de tableaux de 
tableaux qu'il faudrait allouer dynamiquement par une triple boucle et 
il faudrait une double boucle pour remplacer le contenu d'une ligne par 
une autre pour chacune des 3 images. Par contre en Fortran moderne (>= 
90 ou 2003 je ne sais plus) on peut utiliser le même genre d'expressions 
qu'en python/numpy et l'allocation des tableaux à N dimensions se fait 
en une ligne. Mais je m'égare ...

Amicalement.
Marc




Le 01/02/2018 à 18:34, Alain Ketterlin a écrit :
> Fabrice <professeur.leclercq@gmail.com> writes:
> 
>> je n'ai toujours pas compris on dirait ;-)
>> Voici le code qui marche et qui simule le reflet d'une image dans l'eau:
>>
>> import matplotlib.pyplot as mpl    # mpl sera notre repère
>> import numpy as np                 # np manipule des tableaux
>> import copy
>>
>> originale = mpl.imread("damier.jpeg") # un image est lue
>> image = copy.copy(originale)       # image est une copie modifiable
>> hauteur = len(image)               # hauteur contient le nombre de ligne
>> largeur = len(image[0])            # largeur contient le nombre de pixel
>>
>> for ligne in range(hauteur//2):
>>      tmp = copy.copy(image[ligne])
>>      image[ligne] = image[hauteur-ligne-1]
>>      image[hauteur-ligne-1] = tmp
>>
>> print("L'originale")
>> mpl.imshow(originale,cmap='gray')  # On affiche l'image dans le repère
>> mpl.show()                         # On affiche le repère à l'écran
>> print("et son reflet dans l'eau")
>> mpl.imshow(image,cmap='gray')      # On affiche l'image dans le repère
>> mpl.show()
>>
>>
>> mais si je ne fais pas copy.copy, je perds la liste dans tmp.
> 
> En fait, il ne faut pas considérer les np.array (ou image) comme des
> listes Python. Ce sont des structures différents, même si la syntaxe est
> similaire.
> 
> Si j'ai bien compris (mais marc.marc pourra confirmer -- ou pas), quand
> tu écris :
> 
>      tmp = image[ligne]
> 
> tu récupères une "view" sur l'image originale. Ce n'est pas une simple
> référence, et de toute façon image[ligne] n'existe pas indépendamment du
> reste l'image (les np.array sont "denses", alors que les listes de
> listes sont "creuses", ou éclatées).
> 
> Donc : 1) les lignes n'existent pas individuellement, 2) tmp et
> image[ligne] sont effectivement la même chose, et donc 3)
> image[ligne]=... modifie effectivement aussi bien l'image que tmp.
> 
> (Je m'arrête là, parce que je ne peux pas essayer en ce moment...)
> 
>> Pourtant, tmp et image[ligne] sont des étiquettes qui pointent sur la
>> même liste.
>> Quand je fais image[ligne] = image[hauteur-ligne-1], je détache
>> l'étiquette image[ligne] de la liste dans tmp pour la coller sur la
>> liste image[hauteur-ligne-1]. l'étiquette tmp devrait pointer sur la
>> liste en mémoire qui ne doit ^pas être effacée puisque référencée.
>> Puis je détache l'étiquette image[hauteur-ligne-1] de la liste dans
>> image[ligne] maintenant pour l'attacher à la liste dans tmp.
>>
>> En C++, j'aurai dit que j'ai échangé les pointeurs. Un objet mutable,
>> c'est bien un pointeur ?
> 
> Ton analyse s'applique bien aux listes python d'origine.
> 
> Mais numpy c'est une tout autre bestiole... C'est fait pour faire du
> calcul scientifique, donc dans des matrices denses, comme on fait dans
> les langages raisonnablement efficaces pour ça (Fortran, C and co).
> 
> Numpy, c'est le renard (C/Fortran/...) qui entre dans le poulailler
> (celui qui est plein de canards).
> 
> -- Alain.
> 

Back to fr.comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

problème de copie ? shallow - deep Fabrice <professeur.leclercq@gmail.com> - 2018-02-01 15:15 +0100
  Re: problème de copie ? shallow - deep Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2018-02-01 18:34 +0100
    Re: problème de copie ? shallow - deep marc.marc@marc.org - 2018-02-01 21:19 +0100
      Re: problème de copie ? shallow - deep Fabrice <professeur.leclercq@gmail.com> - 2018-02-02 18:09 +0100
        Re: problème de copie ? shallow - deep Nicolas <nicolasp@aaton.com> - 2018-02-05 09:43 +0100
          Re: problème de copie ? shallow - deep marc.marc@marc.org - 2018-02-05 15:02 +0100

csiph-web