Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > fr.comp.lang.python > #3306 > unrolled thread
| Started by | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| First post | 2020-03-27 00:50 +0100 |
| Last post | 2020-04-09 13:27 +0200 |
| Articles | 15 — 4 participants |
Back to article view | Back to fr.comp.lang.python
vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-27 00:50 +0100
Re: vitesse manipulation liste (generateur ?) Nicolas <nicolasp@aaton.com> - 2020-03-27 13:12 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-27 15:29 +0100
Re: vitesse manipulation liste (generateur ?) Nicolas <nicolasp@aaton.com> - 2020-03-28 12:27 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-28 18:08 +0100
Re: vitesse manipulation liste (generateur ?) Nicolas <nicolasp@aaton.com> - 2020-03-28 21:38 +0100
Re: vitesse manipulation liste (generateur ?) Pierre Maurette <maurette.pierre@free.fr> - 2020-03-27 17:36 +0100
Re: vitesse manipulation liste (generateur ?) Pierre Maurette <maurette.pierre@free.fr> - 2020-03-27 17:38 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-28 01:00 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-28 00:57 +0100
Re: vitesse manipulation liste (generateur ?) Nicolas <nicolasp@aaton.com> - 2020-03-28 12:12 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-28 19:15 +0100
Re: vitesse manipulation liste (generateur ?) Nicolas <nicolasp@aaton.com> - 2020-03-28 21:26 +0100
Re: vitesse manipulation liste (generateur ?) Lulu <lulu042@fry.fr.invalid> - 2020-03-30 16:54 +0200
Re: vitesse manipulation liste (generateur ?) ast <ast@invalid> - 2020-04-09 13:27 +0200
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-27 00:50 +0100 |
| Subject | vitesse manipulation liste (generateur ?) |
| Message-ID | <slrnr7qfv1.ibk.lulu042@Minty.Rock-n-Roll.org> |
Bonjour,
J'ai besoin de manipuler des listes rapidement pour manipuler une image.
D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
listes :
((r,0,0),(a,0,0),(x,0,0),....)
((0,v,0),(0,b,0),(0,y,0),....)
((0,0,b),(0,0,c),(0,0,z),....)
Et je veux faire ça le plus rapidement possible.
J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
comment en "fabriquer" et les exemples que je trouve sur le web ne
m'aident pas vraiment. (plus essais infructueux).
Mon code :
8<-----------8<---------8<----------8<----------8<----------8<----------8<
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PIL import Image
Fichier_Image = "Anna_et_Lulu.jpg"
ze_image = Image.open( Fichier_Image ).convert("RGB")
ze_image.show()
(l, h) = ze_image.size
# création de l'image rouge
ze_image_rouge = Image.new("RGB",(l,h))
# traitement pixel par pixel :
for y in range(h): # pour y variant de 0 à h-1
for x in range(l): # pour x variant de 0 à l-1
(rouge, vert, bleu) = ze_image.getpixel((x,y))
ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
# création en mémoire de l'image rouge
ze_image_rouge_fast = Image.new("RGB",(l,h))
liste_pixels = list(ze_image.getdata())
liste_pixels_rouges=[]
for i in range(len(liste_pixels)):
liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
ze_image_rouge_fast.putdata(liste_pixels_rouges)
ze_image_rouge.show()
ze_image_rouge_fast.show()
8<-----------8<---------8<----------8<----------8<----------8<----------8<
Sur une image de 1.600.000 pixels, la première double boucle avec deux
for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
Je crois que c'est en jouant sur ma manière de créer ces trois listes et
de les remplir que je peux gagner le plus.
Merci de vos avis
[toc] | [next] | [standalone]
| From | Nicolas <nicolasp@aaton.com> |
|---|---|
| Date | 2020-03-27 13:12 +0100 |
| Message-ID | <5e7dedb9$0$9896$426a74cc@news.free.fr> |
| In reply to | #3306 |
Le 27/03/2020 à 00:50, Lulu a écrit :
>
> Bonjour,
>
> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
> listes :
> ((r,0,0),(a,0,0),(x,0,0),....)
> ((0,v,0),(0,b,0),(0,y,0),....)
> ((0,0,b),(0,0,c),(0,0,z),....)
>
> Et je veux faire ça le plus rapidement possible.
> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
> comment en "fabriquer" et les exemples que je trouve sur le web ne
> m'aident pas vraiment. (plus essais infructueux).
>
>
> Mon code :
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
> #!/usr/bin/python3
> # -*- coding: utf-8 -*-
>
> from PIL import Image
>
> Fichier_Image = "Anna_et_Lulu.jpg"
>
> ze_image = Image.open( Fichier_Image ).convert("RGB")
> ze_image.show()
>
> (l, h) = ze_image.size
>
> # création de l'image rouge
> ze_image_rouge = Image.new("RGB",(l,h))
>
> # traitement pixel par pixel :
> for y in range(h): # pour y variant de 0 à h-1
> for x in range(l): # pour x variant de 0 à l-1
> (rouge, vert, bleu) = ze_image.getpixel((x,y))
> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>
> # création en mémoire de l'image rouge
> ze_image_rouge_fast = Image.new("RGB",(l,h))
>
> liste_pixels = list(ze_image.getdata())
> liste_pixels_rouges=[]
>
> for i in range(len(liste_pixels)):
> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>
> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>
> ze_image_rouge.show()
> ze_image_rouge_fast.show()
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>
> Sur une image de 1.600.000 pixels, la première double boucle avec deux
> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>
> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
> de les remplir que je peux gagner le plus.
>
Pour créer les listes :
(l, h) = ze_image.size
l1 = [[0,0,0]] * (l*h)
l2 = [[0,0,0]] * (l*h)
l3 = [[0,0,0]] * (l*h)
Reste à remplir avec les données.
GetPixel() est très lent. A n'utiliser que ponctuellement.
Il est préférable de passer par tostring().
Un truc du genre : pix_data = ze_image.convert("RGB").tostring("raw", "RGB")
Si les images sont déjà en RVB, pas forcément besoin d'appeler convert().
pix_data est une liste d'octets R,V,B,R,V,B,R...
Attention, avec les images dont les couleurs sont codées sur plus que
8bits.
Nicolas
> Merci de vos avis
>
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-27 15:29 +0100 |
| Message-ID | <slrnr7s3eo.666.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3307 |
Le 27-03-2020, Nicolas <nicolasp@aaton.com> a écrit :
> Le 27/03/2020 à 00:50, Lulu a écrit :
>> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>> listes :
>> ((r,0,0),(a,0,0),(x,0,0),....)
>> ((0,v,0),(0,b,0),(0,y,0),....)
>> ((0,0,b),(0,0,c),(0,0,z),....)
>>
>> Et je veux faire ça le plus rapidement possible.
>> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
>> comment en "fabriquer" et les exemples que je trouve sur le web ne
>> m'aident pas vraiment. (plus essais infructueux).
J'avais aussi essayé la "compréhension de liste" (par exemple ici :
https://openclassrooms.com/fr/courses/1206331-utilisation-avancee-des-listes-en-python
), mais je n'ai rien compris...
>> Mon code :
>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>> #!/usr/bin/python3
>> # -*- coding: utf-8 -*-
>>
>> from PIL import Image
>>
>> Fichier_Image = "Anna_et_Lulu.jpg"
>>
>> ze_image = Image.open( Fichier_Image ).convert("RGB")
>> ze_image.show()
>>
>> (l, h) = ze_image.size
>>
>> # création de l'image rouge
>> ze_image_rouge = Image.new("RGB",(l,h))
>>
>> # traitement pixel par pixel :
>> for y in range(h): # pour y variant de 0 à h-1
>> for x in range(l): # pour x variant de 0 à l-1
>> (rouge, vert, bleu) = ze_image.getpixel((x,y))
>> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>>
>> # création en mémoire de l'image rouge
>> ze_image_rouge_fast = Image.new("RGB",(l,h))
>>
>> liste_pixels = list(ze_image.getdata())
>> liste_pixels_rouges=[]
>>
>> for i in range(len(liste_pixels)):
>> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>>
>> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>>
>> ze_image_rouge.show()
>> ze_image_rouge_fast.show()
>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>>
>> Sur une image de 1.600.000 pixels, la première double boucle avec deux
>> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
>> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>>
>> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
>> de les remplir que je peux gagner le plus.
>>
>
> Pour créer les listes :
>
> (l, h) = ze_image.size
> l1 = [[0,0,0]] * (l*h)
> l2 = [[0,0,0]] * (l*h)
> l3 = [[0,0,0]] * (l*h)
Merci, je ne savais pas qu'on pouvait faire cette opération sur une
liste.
> Reste à remplir avec les données.
Mais je ne vois pas comment faire...
> GetPixel() est très lent. A n'utiliser que ponctuellement.
Oui, j'ai vu.
> Il est préférable de passer par tostring().
> Un truc du genre : pix_data = ze_image.convert("RGB").tostring("raw", "RGB")
> Si les images sont déjà en RVB, pas forcément besoin d'appeler convert().
> pix_data est une liste d'octets R,V,B,R,V,B,R...
Je ne vois pas du tout comment remplir les listes l1, l2 et l3 avec ton
exemple de « ze_image.convert("RGB").tostring("raw", "RGB") ».
J'ai cherché ce que pouvait faire cette fonction, mais les exemples que
j'ai trouvés me semblent sans aucun rapport avec mon problème.
> Attention, avec les images dont les couleurs sont codées sur plus que
> 8bits.
Oui, je n'avais pas pensé à ce problème.
Merci pour ton aide.
[toc] | [prev] | [next] | [standalone]
| From | Nicolas <nicolasp@aaton.com> |
|---|---|
| Date | 2020-03-28 12:27 +0100 |
| Message-ID | <5e7f34af$0$21605$426a74cc@news.free.fr> |
| In reply to | #3308 |
Le 27/03/2020 à 15:29, Lulu a écrit :
> Le 27-03-2020, Nicolas <nicolasp@aaton.com> a écrit :
>> Le 27/03/2020 à 00:50, Lulu a écrit :
>
>>> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
>>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>>> listes :
>>> ((r,0,0),(a,0,0),(x,0,0),....)
>>> ((0,v,0),(0,b,0),(0,y,0),....)
>>> ((0,0,b),(0,0,c),(0,0,z),....)
>>>
>>> Et je veux faire ça le plus rapidement possible.
>>> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
>>> comment en "fabriquer" et les exemples que je trouve sur le web ne
>>> m'aident pas vraiment. (plus essais infructueux).
>
> J'avais aussi essayé la "compréhension de liste" (par exemple ici :
> https://openclassrooms.com/fr/courses/1206331-utilisation-avancee-des-listes-en-python
> ), mais je n'ai rien compris...
>
La compréhension de liste, c'est pas compliqué.
----------------------
Soit le code suivant :
l_in = [1, 45, 89, 56, 4]
l_out = []
for e in l_in :
l_out.append(e)
C'est exactement la même chose que :
l_out = [e for e in l_in]
--------------------------
On peut compléter un peu :
l_out = []
for e in l_in :
l_out.append(traitement(e))
est équivalent à :
l_out = [traitement(e) for e in l_in]
------------------
Version complète :
l_out = []
for e in l_in :
if is_ok(e) :
l_out.append(traitement(e))
est équivalent à :
l_out = [traitement(e) for e in l_in if is_ok(e)]
Les 4 lignes sont "mises à plat" en une seule ligne.
Ca serait plus facile à expliquer avec des couleurs ou un dessin mais,
sur la mailing list, c'est pas possible.
>>> Mon code :
>>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>>> #!/usr/bin/python3
>>> # -*- coding: utf-8 -*-
>>>
>>> from PIL import Image
>>>
>>> Fichier_Image = "Anna_et_Lulu.jpg"
>>>
>>> ze_image = Image.open( Fichier_Image ).convert("RGB")
>>> ze_image.show()
>>>
>>> (l, h) = ze_image.size
>>>
>>> # création de l'image rouge
>>> ze_image_rouge = Image.new("RGB",(l,h))
>>>
>>> # traitement pixel par pixel :
>>> for y in range(h): # pour y variant de 0 à h-1
>>> for x in range(l): # pour x variant de 0 à l-1
>>> (rouge, vert, bleu) = ze_image.getpixel((x,y))
>>> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>>>
>>> # création en mémoire de l'image rouge
>>> ze_image_rouge_fast = Image.new("RGB",(l,h))
>>>
>>> liste_pixels = list(ze_image.getdata())
>>> liste_pixels_rouges=[]
>>>
>>> for i in range(len(liste_pixels)):
>>> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>>>
>>> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>>>
>>> ze_image_rouge.show()
>>> ze_image_rouge_fast.show()
>>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>>>
>>> Sur une image de 1.600.000 pixels, la première double boucle avec deux
>>> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
>>> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>>>
>>> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
>>> de les remplir que je peux gagner le plus.
>>>
>>
>> Pour créer les listes :
>>
>> (l, h) = ze_image.size
>> l1 = [[0,0,0]] * (l*h)
>> l2 = [[0,0,0]] * (l*h)
>> l3 = [[0,0,0]] * (l*h)
>
> Merci, je ne savais pas qu'on pouvait faire cette opération sur une
> liste.
>
>> Reste à remplir avec les données.
>
> Mais je ne vois pas comment faire...
>
>> GetPixel() est très lent. A n'utiliser que ponctuellement.
>
> Oui, j'ai vu.
>
>> Il est préférable de passer par tostring().
>> Un truc du genre : pix_data = ze_image.convert("RGB").tostring("raw", "RGB")
>> Si les images sont déjà en RVB, pas forcément besoin d'appeler convert().
>> pix_data est une liste d'octets R,V,B,R,V,B,R...
>
> Je ne vois pas du tout comment remplir les listes l1, l2 et l3 avec ton
> exemple de « ze_image.convert("RGB").tostring("raw", "RGB") ».
> J'ai cherché ce que pouvait faire cette fonction, mais les exemples que
> j'ai trouvés me semblent sans aucun rapport avec mon problème.
>
Je peux écrire un exemple si ça t'intéresse mais il faut que je trouve
un peu de temps pour ça ;)
>> Attention, avec les images dont les couleurs sont codées sur plus que
>> 8bits.
>
> Oui, je n'avais pas pensé à ce problème.
>
>
> Merci pour ton aide.
>
De rien.
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-28 18:08 +0100 |
| Message-ID | <slrnr7v147.f9b.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3314 |
Le 28-03-2020, Nicolas <nicolasp@aaton.com> a écrit :
> Le 27/03/2020 à 15:29, Lulu a écrit :
>> Le 27-03-2020, Nicolas <nicolasp@aaton.com> a écrit :
>>> Le 27/03/2020 à 00:50, Lulu a écrit :
>>
>>>> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
>>>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>>>> listes :
>>>> ((r,0,0),(a,0,0),(x,0,0),....)
>>>> ((0,v,0),(0,b,0),(0,y,0),....)
>>>> ((0,0,b),(0,0,c),(0,0,z),....)
>>>>
>>>> Et je veux faire ça le plus rapidement possible.
>>>> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
>>>> comment en "fabriquer" et les exemples que je trouve sur le web ne
>>>> m'aident pas vraiment. (plus essais infructueux).
>>
>> J'avais aussi essayé la "compréhension de liste" (par exemple ici :
>> https://openclassrooms.com/fr/courses/1206331-utilisation-avancee-des-listes-en-python
>> ), mais je n'ai rien compris...
>>
> La compréhension de liste, c'est pas compliqué.
>
> ----------------------
> Soit le code suivant :
>
> l_in = [1, 45, 89, 56, 4]
>
> l_out = []
> for e in l_in :
> l_out.append(e)
>
> C'est exactement la même chose que :
> l_out = [e for e in l_in]
>
> --------------------------
> On peut compléter un peu :
>
> l_out = []
> for e in l_in :
> l_out.append(traitement(e))
>
> est équivalent à :
> l_out = [traitement(e) for e in l_in]
>
> ------------------
> Version complète :
> l_out = []
> for e in l_in :
> if is_ok(e) :
> l_out.append(traitement(e))
>
> est équivalent à :
> l_out = [traitement(e) for e in l_in if is_ok(e)]
où j'imagine que traitement() et ok() sont deux fonctions ?
> Les 4 lignes sont "mises à plat" en une seule ligne.
>
> Ca serait plus facile à expliquer avec des couleurs ou un dessin mais,
> sur la mailing list, c'est pas possible.
Donc pour mon exemple de liste de tuples.
>>>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>>>> listes :
>>>> ((r,0,0),(a,0,0),(x,0,0),....)
>>>> ((0,v,0),(0,b,0),(0,y,0),....)
>>>> ((0,0,b),(0,0,c),(0,0,z),....)
j'obtiens mes 3 listes avec l1 = [ (e[0], 0, 0) for e in l_in ]
l2 = [ (0, e[1], 0) for e in l_in ] et l3 = [ (0, 0, e[2]) for e in l_in ]
(Bizarrement, c'est aussi l'exemple de zip(list) et zip(*list)) donné
par Pierre qui m'a aussi permis de comprendre ;-)
Donc mille mercis encore à vous deux.
Je viens de tester dans mon script et la manipulation de liste par
compréhension est la plus rapide des 4 manipulations que je tente :
-=-=-=-
Image : ws_SBK-07_0834.jpg
taille de l'image : 1024 px × 768 px
nombre de pixels : 786432
-=-=-=-
1: Traitement par une boucle sur les 786432 pixels.
durée = 9.874 seconde(s)
-=-=-=-
2: Traitement par boucle avec list.append().
durée = 2.402 seconde(s)
4 fois plus rapide.
-=-=-=-
3: Traitement par compréhension de liste.
durée = 1.495 seconde(s)
6 fois plus rapide.
-=-=-=-
4: Traitement par split avec zip(*liste) et merge par zip(liste).
durée = 2.786 seconde(s)
3 fois plus rapide.
-=-=-=-
5: Traitement par split de liste et fausse compréhension
durée = 2.688 seconde(s)
3 fois plus rapide.
-=-=-=-
6: Traitement par Image.split().
durée = 0.002264 seconde(s)
4361 fois plus rapide.
Mon code :
8<-----------8<---------8<----------8<----------8<----------8<----------8<
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from datetime import datetime
from PIL import Image, ImageFilter
# Fichier_Image = "Les_Horribles_Cernettes.png"
# Fichier_Image = "avengers-endseries-comics.png"
# Fichier_Image = "Anna_et_Lulu.jpg"
Fichier_Image = "ws_SBK-07_0834.jpg"
# Fichier_Image = "Sauzon.jpg"
print("-=-=-=-\nImage : ", Fichier_Image)
try:
ze_image = Image.open( Fichier_Image ).convert("RGB")
except:
print('\n' * 2)
print(" Erreur : le fichier \n",Fichier_Image,"\" existe-t-il ?")
print('\n' * 2)
sys.exit(1)
# j'appelle la méthode 'show' de la classe PIL.Image.Image (liste des méthodes help(Image))
ze_image.show()
(l, h) = ze_image.size
print("taille de l'image :", l, "px ×", h, "px")
nb_pixels = l*h
print("nombre de pixels :",nb_pixels)
# 1er procédé
# création en mémoire des 3 images à calculer
ze_image_rouge_p1 = Image.new("RGB",(l,h))
ze_image_verte_p1 = Image.new("RGB",(l,h))
ze_image_bleue_p1 = Image.new("RGB",(l,h))
# mesure du temps de traitement :
timestamp_debut = datetime.timestamp(datetime.now())
# traitement pixel par pixel :
print("-=-=-=-\n1: Traitement par une boucle sur les", nb_pixels,"pixels.")
for y in range(h): # pour y variant de 0 à h-1
for x in range(l): # pour x variant de 0 à l-1
(rouge, vert, bleu) = ze_image.getpixel((x,y))
ze_image_rouge_p1.putpixel((x,y), ( rouge, 0, 0))
ze_image_verte_p1.putpixel((x,y), ( 0, vert, 0))
ze_image_bleue_p1.putpixel((x,y), ( 0, 0, bleu))
# mesure du temps de traitement :
timestamp_fin = datetime.timestamp(datetime.now())
duree_1 = timestamp_fin - timestamp_debut
print('durée =',"{:0.3f}".format(duree_1),"seconde(s)")
# 2ème procédé
# création en mémoire des 3 images à calculer
ze_image_rouge_p2 = Image.new("RGB",(l,h))
ze_image_verte_p2 = Image.new("RGB",(l,h))
ze_image_bleue_p2 = Image.new("RGB",(l,h))
liste_pixels = []
liste_pixels_rouges = []
liste_pixels_verts =[]
liste_pixels_bleus = []
print("-=-=-=-\n2: Traitement par boucle avec list.append().")
timestamp_debut = datetime.timestamp(datetime.now())
liste_pixels = list(ze_image.getdata())
for i in range(len(liste_pixels)):
liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
liste_pixels_verts.append((0, liste_pixels[i][1], 0))
liste_pixels_bleus.append((0, 0, liste_pixels[i][2]))
ze_image_rouge_p2.putdata(liste_pixels_rouges)
ze_image_verte_p2.putdata(liste_pixels_verts)
ze_image_bleue_p2.putdata(liste_pixels_bleus)
timestamp_fin = datetime.timestamp(datetime.now())
duree_2 = timestamp_fin - timestamp_debut
print('durée =',"{:0.3f}".format(duree_2),"seconde(s)")
print(int(duree_1/duree_2), "fois plus rapide.")
# 3ème procédé
# création en mémoire des 3 images à calculer
ze_image_rouge_p3 = Image.new("RGB",(l,h))
ze_image_verte_p3 = Image.new("RGB",(l,h))
ze_image_bleue_p3 = Image.new("RGB",(l,h))
liste_pixels = []
# liste_pixels_rouges = []
liste_pixels_verts =[]
liste_pixels_bleus = []
print("-=-=-=-\n3: Traitement par compréhension de liste.")
timestamp_debut = datetime.timestamp(datetime.now())
liste_pixels = list(ze_image.getdata())
#print("liste_pixels[:30] = ", liste_pixels[:30])
liste_pixels_rouges = [ (e[0], 0, 0) for e in liste_pixels ]
liste_pixels_verts = [ (0, e[1], 0) for e in liste_pixels ]
liste_pixels_bleus = [ (0, 0, e[2]) for e in liste_pixels ]
ze_image_rouge_p3.putdata(liste_pixels_rouges)
ze_image_verte_p3.putdata(liste_pixels_verts)
ze_image_bleue_p3.putdata(liste_pixels_bleus)
timestamp_fin = datetime.timestamp(datetime.now())
duree_3 = timestamp_fin - timestamp_debut
print('durée =',"{:0.3f}".format(duree_3),"seconde(s)")
print(int(duree_1/duree_3), "fois plus rapide.")
# 4ème procédé
# création en mémoire des 3 images à calculer
ze_image_rouge_p4 = Image.new("RGB",(l,h))
ze_image_verte_p4 = Image.new("RGB",(l,h))
ze_image_bleue_p4 = Image.new("RGB",(l,h))
liste_pixels = []
liste_pixels_rouges = []
liste_pixels_verts =[]
liste_pixels_bleus = []
liste_pixels_zero = []
print("-=-=-=-\n4: Traitement par split avec zip(*liste) et merge par zip(liste).")
timestamp_debut = datetime.timestamp(datetime.now())
liste_pixels = list(ze_image.getdata())
liste_pixels_rouges, liste_pixels_verts, liste_pixels_bleus = list(zip(*liste_pixels))
liste_pixels_zero = [0] * nb_pixels
ze_image_rouge_p4.putdata(list(zip(liste_pixels_rouges, liste_pixels_zero, liste_pixels_zero)))
ze_image_verte_p4.putdata(list(zip(liste_pixels_zero, liste_pixels_verts, liste_pixels_zero)))
ze_image_bleue_p4.putdata(list(zip(liste_pixels_zero, liste_pixels_zero, liste_pixels_bleus)))
timestamp_fin = datetime.timestamp(datetime.now())
duree_4 = timestamp_fin - timestamp_debut
print('durée =',"{:0.3f}".format(duree_4),"seconde(s)")
print(int(duree_1/duree_4), "fois plus rapide.")
# 5ème procédé
liste_pixels = []
liste_pixels_rouges = []
liste_pixels_verts =[]
liste_pixels_bleus = []
liste_pixels_zero = []
ze_image_rouge_p5 = Image.new("RGB",(l,h))
ze_image_verte_p5 = Image.new("RGB",(l,h))
ze_image_bleue_p5 = Image.new("RGB",(l,h))
print("-=-=-=-\n5: Traitement par split de liste et fausse compréhension")
timestamp_debut = datetime.timestamp(datetime.now())
liste_pixels = list(ze_image.getdata())
liste_pixels_rouges, liste_pixels_verts, liste_pixels_bleus = list(zip(*liste_pixels))
liste_pixels_rouges = [(x, 0, 0) for x in liste_pixels_rouges ]
liste_pixels_verts = [(0, x, 0) for x in liste_pixels_verts ]
liste_pixels_bleus = [(0, 0, x) for x in liste_pixels_bleus ]
ze_image_rouge_p5.putdata(liste_pixels_rouges)
ze_image_verte_p5.putdata(liste_pixels_verts)
ze_image_bleue_p5.putdata(liste_pixels_bleus)
timestamp_fin = datetime.timestamp(datetime.now())
duree_5 = timestamp_fin - timestamp_debut
print('durée =',"{:0.3f}".format(duree_5),"seconde(s)")
print(int(duree_1/duree_5), "fois plus rapide.")
# 6ème procédé
print("-=-=-=-\n6: Traitement par Image.split().")
timestamp_debut = datetime.timestamp(datetime.now())
ze_image_splited = Image.Image.split(ze_image)
timestamp_fin = datetime.timestamp(datetime.now())
duree_6 = timestamp_fin - timestamp_debut
print('durée =',"{:0.6f}".format(duree_6),"seconde(s)")
print(int(duree_1/duree_6), "fois plus rapide.")
x = input("Afficher les images [O/n] ? ")
if x == "" or x[0] == "o" or x[0] == "O" :
ze_image_rouge_p1.show()
ze_image_verte_p1.show()
ze_image_bleue_p1.show()
ze_image_rouge_p2.show()
ze_image_verte_p2.show()
ze_image_bleue_p2.show()
ze_image_rouge_p3.show()
ze_image_verte_p3.show()
ze_image_bleue_p3.show()
ze_image_rouge_p4.show()
ze_image_verte_p4.show()
ze_image_bleue_p4.show()
ze_image_rouge_p5.show()
ze_image_verte_p5.show()
ze_image_bleue_p5.show()
ze_image_splited[0].show()
ze_image_splited[1].show()
ze_image_splited[2].show()
[toc] | [prev] | [next] | [standalone]
| From | Nicolas <nicolasp@aaton.com> |
|---|---|
| Date | 2020-03-28 21:38 +0100 |
| Message-ID | <5e7fb5b1$0$16801$426a74cc@news.free.fr> |
| In reply to | #3315 |
Le 28/03/2020 à 18:08, Lulu a écrit :
>>> J'avais aussi essayé la "compréhension de liste" (par exemple ici :
>>> https://openclassrooms.com/fr/courses/1206331-utilisation-avancee-des-listes-en-python
>>> ), mais je n'ai rien compris...
>>>
>> La compréhension de liste, c'est pas compliqué.
>>
>> ----------------------
>> Soit le code suivant :
>>
>> l_in = [1, 45, 89, 56, 4]
>>
>> l_out = []
>> for e in l_in :
>> l_out.append(e)
>>
>> C'est exactement la même chose que :
>> l_out = [e for e in l_in]
>>
>> --------------------------
>> On peut compléter un peu :
>>
>> l_out = []
>> for e in l_in :
>> l_out.append(traitement(e))
>>
>> est équivalent à :
>> l_out = [traitement(e) for e in l_in]
>>
>> ------------------
>> Version complète :
>> l_out = []
>> for e in l_in :
>> if is_ok(e) :
>> l_out.append(traitement(e))
>>
>> est équivalent à :
>> l_out = [traitement(e) for e in l_in if is_ok(e)]
>
> où j'imagine que traitement() et ok() sont deux fonctions ?
Tout à fait. Des fonctions à toi que tu as :)
C'était un exemple, l'utilisation de fonctions n'est pas obligatoire.
Un exemple sans fonction :
l_out = [e*2 for e in l_in if e > 10]
>> Les 4 lignes sont "mises à plat" en une seule ligne.
>>
>> Ca serait plus facile à expliquer avec des couleurs ou un dessin mais,
>> sur la mailing list, c'est pas possible.
>
> Donc pour mon exemple de liste de tuples.
>
>>>>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>>>>> listes :
>>>>> ((r,0,0),(a,0,0),(x,0,0),....)
>>>>> ((0,v,0),(0,b,0),(0,y,0),....)
>>>>> ((0,0,b),(0,0,c),(0,0,z),....)
>
> j'obtiens mes 3 listes avec l1 = [ (e[0], 0, 0) for e in l_in ]
> l2 = [ (0, e[1], 0) for e in l_in ] et l3 = [ (0, 0, e[2]) for e in l_in ]
>
C'est ça :)
> (Bizarrement, c'est aussi l'exemple de zip(list) et zip(*list)) donné
> par Pierre qui m'a aussi permis de comprendre ;-)
>
> Donc mille mercis encore à vous deux.
>
> Je viens de tester dans mon script et la manipulation de liste par
> compréhension est la plus rapide des 4 manipulations que je tente :
> -=-=-=-
> Image : ws_SBK-07_0834.jpg
> taille de l'image : 1024 px × 768 px
> nombre de pixels : 786432
> -=-=-=-
> 1: Traitement par une boucle sur les 786432 pixels.
> durée = 9.874 seconde(s)
> -=-=-=-
> 2: Traitement par boucle avec list.append().
> durée = 2.402 seconde(s)
> 4 fois plus rapide.
> -=-=-=-
> 3: Traitement par compréhension de liste.
> durée = 1.495 seconde(s)
> 6 fois plus rapide.
> -=-=-=-
> 4: Traitement par split avec zip(*liste) et merge par zip(liste).
> durée = 2.786 seconde(s)
> 3 fois plus rapide.
> -=-=-=-
> 5: Traitement par split de liste et fausse compréhension
> durée = 2.688 seconde(s)
> 3 fois plus rapide.
> -=-=-=-
> 6: Traitement par Image.split().
> durée = 0.002264 seconde(s)
> 4361 fois plus rapide.
>
Image.split() n'est pas écrit en Python mais en C. Impossible à battre ;)
> Mon code :
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
> #!/usr/bin/python3
> # -*- coding: utf-8 -*-
>
> import sys
> from datetime import datetime
> from PIL import Image, ImageFilter
>
> # Fichier_Image = "Les_Horribles_Cernettes.png"
> # Fichier_Image = "avengers-endseries-comics.png"
> # Fichier_Image = "Anna_et_Lulu.jpg"
> Fichier_Image = "ws_SBK-07_0834.jpg"
> # Fichier_Image = "Sauzon.jpg"
>
> print("-=-=-=-\nImage : ", Fichier_Image)
> try:
> ze_image = Image.open( Fichier_Image ).convert("RGB")
> except:
> print('\n' * 2)
> print(" Erreur : le fichier \n",Fichier_Image,"\" existe-t-il ?")
> print('\n' * 2)
> sys.exit(1)
>
> # j'appelle la méthode 'show' de la classe PIL.Image.Image (liste des méthodes help(Image))
> ze_image.show()
>
> (l, h) = ze_image.size
> print("taille de l'image :", l, "px ×", h, "px")
> nb_pixels = l*h
> print("nombre de pixels :",nb_pixels)
>
>
> # 1er procédé
>
>
> # création en mémoire des 3 images à calculer
> ze_image_rouge_p1 = Image.new("RGB",(l,h))
> ze_image_verte_p1 = Image.new("RGB",(l,h))
> ze_image_bleue_p1 = Image.new("RGB",(l,h))
>
> # mesure du temps de traitement :
> timestamp_debut = datetime.timestamp(datetime.now())
> # traitement pixel par pixel :
> print("-=-=-=-\n1: Traitement par une boucle sur les", nb_pixels,"pixels.")
> for y in range(h): # pour y variant de 0 à h-1
> for x in range(l): # pour x variant de 0 à l-1
> (rouge, vert, bleu) = ze_image.getpixel((x,y))
>
> ze_image_rouge_p1.putpixel((x,y), ( rouge, 0, 0))
> ze_image_verte_p1.putpixel((x,y), ( 0, vert, 0))
> ze_image_bleue_p1.putpixel((x,y), ( 0, 0, bleu))
>
> # mesure du temps de traitement :
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_1 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.3f}".format(duree_1),"seconde(s)")
>
>
> # 2ème procédé
>
>
> # création en mémoire des 3 images à calculer
> ze_image_rouge_p2 = Image.new("RGB",(l,h))
> ze_image_verte_p2 = Image.new("RGB",(l,h))
> ze_image_bleue_p2 = Image.new("RGB",(l,h))
>
> liste_pixels = []
> liste_pixels_rouges = []
> liste_pixels_verts =[]
> liste_pixels_bleus = []
>
> print("-=-=-=-\n2: Traitement par boucle avec list.append().")
> timestamp_debut = datetime.timestamp(datetime.now())
>
> liste_pixels = list(ze_image.getdata())
>
> for i in range(len(liste_pixels)):
> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
> liste_pixels_verts.append((0, liste_pixels[i][1], 0))
> liste_pixels_bleus.append((0, 0, liste_pixels[i][2]))
>
> ze_image_rouge_p2.putdata(liste_pixels_rouges)
> ze_image_verte_p2.putdata(liste_pixels_verts)
> ze_image_bleue_p2.putdata(liste_pixels_bleus)
>
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_2 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.3f}".format(duree_2),"seconde(s)")
> print(int(duree_1/duree_2), "fois plus rapide.")
>
>
> # 3ème procédé
>
>
> # création en mémoire des 3 images à calculer
> ze_image_rouge_p3 = Image.new("RGB",(l,h))
> ze_image_verte_p3 = Image.new("RGB",(l,h))
> ze_image_bleue_p3 = Image.new("RGB",(l,h))
>
> liste_pixels = []
> # liste_pixels_rouges = []
> liste_pixels_verts =[]
> liste_pixels_bleus = []
>
> print("-=-=-=-\n3: Traitement par compréhension de liste.")
> timestamp_debut = datetime.timestamp(datetime.now())
>
> liste_pixels = list(ze_image.getdata())
> #print("liste_pixels[:30] = ", liste_pixels[:30])
>
> liste_pixels_rouges = [ (e[0], 0, 0) for e in liste_pixels ]
> liste_pixels_verts = [ (0, e[1], 0) for e in liste_pixels ]
> liste_pixels_bleus = [ (0, 0, e[2]) for e in liste_pixels ]
>
> ze_image_rouge_p3.putdata(liste_pixels_rouges)
> ze_image_verte_p3.putdata(liste_pixels_verts)
> ze_image_bleue_p3.putdata(liste_pixels_bleus)
>
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_3 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.3f}".format(duree_3),"seconde(s)")
> print(int(duree_1/duree_3), "fois plus rapide.")
>
>
> # 4ème procédé
>
>
> # création en mémoire des 3 images à calculer
> ze_image_rouge_p4 = Image.new("RGB",(l,h))
> ze_image_verte_p4 = Image.new("RGB",(l,h))
> ze_image_bleue_p4 = Image.new("RGB",(l,h))
>
> liste_pixels = []
> liste_pixels_rouges = []
> liste_pixels_verts =[]
> liste_pixels_bleus = []
> liste_pixels_zero = []
>
> print("-=-=-=-\n4: Traitement par split avec zip(*liste) et merge par zip(liste).")
> timestamp_debut = datetime.timestamp(datetime.now())
>
> liste_pixels = list(ze_image.getdata())
>
> liste_pixels_rouges, liste_pixels_verts, liste_pixels_bleus = list(zip(*liste_pixels))
> liste_pixels_zero = [0] * nb_pixels
>
> ze_image_rouge_p4.putdata(list(zip(liste_pixels_rouges, liste_pixels_zero, liste_pixels_zero)))
> ze_image_verte_p4.putdata(list(zip(liste_pixels_zero, liste_pixels_verts, liste_pixels_zero)))
> ze_image_bleue_p4.putdata(list(zip(liste_pixels_zero, liste_pixels_zero, liste_pixels_bleus)))
>
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_4 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.3f}".format(duree_4),"seconde(s)")
> print(int(duree_1/duree_4), "fois plus rapide.")
>
>
> # 5ème procédé
>
>
> liste_pixels = []
> liste_pixels_rouges = []
> liste_pixels_verts =[]
> liste_pixels_bleus = []
> liste_pixels_zero = []
>
> ze_image_rouge_p5 = Image.new("RGB",(l,h))
> ze_image_verte_p5 = Image.new("RGB",(l,h))
> ze_image_bleue_p5 = Image.new("RGB",(l,h))
> print("-=-=-=-\n5: Traitement par split de liste et fausse compréhension")
> timestamp_debut = datetime.timestamp(datetime.now())
>
> liste_pixels = list(ze_image.getdata())
> liste_pixels_rouges, liste_pixels_verts, liste_pixels_bleus = list(zip(*liste_pixels))
>
> liste_pixels_rouges = [(x, 0, 0) for x in liste_pixels_rouges ]
> liste_pixels_verts = [(0, x, 0) for x in liste_pixels_verts ]
> liste_pixels_bleus = [(0, 0, x) for x in liste_pixels_bleus ]
>
> ze_image_rouge_p5.putdata(liste_pixels_rouges)
> ze_image_verte_p5.putdata(liste_pixels_verts)
> ze_image_bleue_p5.putdata(liste_pixels_bleus)
>
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_5 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.3f}".format(duree_5),"seconde(s)")
> print(int(duree_1/duree_5), "fois plus rapide.")
>
>
> # 6ème procédé
>
>
> print("-=-=-=-\n6: Traitement par Image.split().")
> timestamp_debut = datetime.timestamp(datetime.now())
>
> ze_image_splited = Image.Image.split(ze_image)
>
> timestamp_fin = datetime.timestamp(datetime.now())
> duree_6 = timestamp_fin - timestamp_debut
> print('durée =',"{:0.6f}".format(duree_6),"seconde(s)")
> print(int(duree_1/duree_6), "fois plus rapide.")
>
> x = input("Afficher les images [O/n] ? ")
> if x == "" or x[0] == "o" or x[0] == "O" :
> ze_image_rouge_p1.show()
> ze_image_verte_p1.show()
> ze_image_bleue_p1.show()
>
> ze_image_rouge_p2.show()
> ze_image_verte_p2.show()
> ze_image_bleue_p2.show()
>
> ze_image_rouge_p3.show()
> ze_image_verte_p3.show()
> ze_image_bleue_p3.show()
>
> ze_image_rouge_p4.show()
> ze_image_verte_p4.show()
> ze_image_bleue_p4.show()
>
> ze_image_rouge_p5.show()
> ze_image_verte_p5.show()
> ze_image_bleue_p5.show()
>
> ze_image_splited[0].show()
> ze_image_splited[1].show()
> ze_image_splited[2].show()
>
[toc] | [prev] | [next] | [standalone]
| From | Pierre Maurette <maurette.pierre@free.fr> |
|---|---|
| Date | 2020-03-27 17:36 +0100 |
| Message-ID | <mn.dc207e4317695ba7.79899@free.fr> |
| In reply to | #3306 |
Lulu :
> Bonjour,
>
> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
> listes :
> ((r,0,0),(a,0,0),(x,0,0),....)
> ((0,v,0),(0,b,0),(0,y,0),....)
> ((0,0,b),(0,0,c),(0,0,z),....)
>
> Et je veux faire ça le plus rapidement possible.
> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
> comment en "fabriquer" et les exemples que je trouve sur le web ne
> m'aident pas vraiment. (plus essais infructueux).
>
>
> Mon code :
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
> #!/usr/bin/python3
> # -*- coding: utf-8 -*-
>
> from PIL import Image
>
> Fichier_Image = "Anna_et_Lulu.jpg"
>
> ze_image = Image.open( Fichier_Image ).convert("RGB")
> ze_image.show()
>
> (l, h) = ze_image.size
>
> # création de l'image rouge
> ze_image_rouge = Image.new("RGB",(l,h))
>
> # traitement pixel par pixel :
> for y in range(h): # pour y variant de 0 à h-1
> for x in range(l): # pour x variant de 0 à l-1
> (rouge, vert, bleu) = ze_image.getpixel((x,y))
> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>
> # création en mémoire de l'image rouge
> ze_image_rouge_fast = Image.new("RGB",(l,h))
>
> liste_pixels = list(ze_image.getdata())
> liste_pixels_rouges=[]
>
> for i in range(len(liste_pixels)):
> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>
> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>
> ze_image_rouge.show()
> ze_image_rouge_fast.show()
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>
> Sur une image de 1.600.000 pixels, la première double boucle avec deux
> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>
> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
> de les remplir que je peux gagner le plus.
>
> Merci de vos avis
Fondamentalement une réponse est dans zip(*zipped).
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
RVBs =
[(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)]
print(RVBs)
(_rouge, _vert, _bleu) = list(zip(*RVBs))
im_rouge = [(x, 0, 0) for x in _rouge]
im_vert = [(0, x, 0) for x in _vert]
im_bleu = [(0, 0, x) for x in _bleu]
print(im_rouge)
print(im_vert)
print(im_bleu)
Remarques:
Avez-vous vraiment besoin d'une image "RVB" pour chaque channel ?
Normalement un channel se représente dans une image "L".
Peut-être y a-t-il moyen de tout faire à partir de PIL (Image.split(),
Image.getchannel(channel), et des fonctions de convertion ).
--
Pierre Maurette
[toc] | [prev] | [next] | [standalone]
| From | Pierre Maurette <maurette.pierre@free.fr> |
|---|---|
| Date | 2020-03-27 17:38 +0100 |
| Message-ID | <mn.dc227e43c1e316f3.79899@free.fr> |
| In reply to | #3309 |
Pierre Maurette : [...] > Fondamentalement une réponse est dans zip(*zipped). > > #! /usr/bin/env python3 > # -*- coding: utf-8 -*- > > RVBs = [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)] > print(RVBs) > > (_rouge, _vert, _bleu) = list(zip(*RVBs)) > > im_rouge = [(x, 0, 0) for x in _rouge] > im_vert = [(0, x, 0) for x in _vert] > im_bleu = [(0, 0, x) for x in _bleu] > > print(im_rouge) > print(im_vert) > print(im_bleu) > > Remarques: > > Avez-vous vraiment besoin d'une image "RVB" pour chaque channel ? Normalement > un channel se représente dans une image "L". > Peut-être y a-t-il moyen de tout faire à partir de PIL (Image.split(), > Image.getchannel(channel), et des fonctions de convertion ). Pour info, en utilisant zip et une liste de "0" (zob): #! /usr/bin/env python3 # -*- coding: utf-8 -*- RVBs = [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)] print(RVBs) (_rouge, _vert, _bleu, zob) = list(zip(*RVBs)) + [([0,] * len(RVBs)),] (im_rouge, im_vert, im_bleu) = (list(zip(_rouge, zob, zob)), list(zip(zob, _vert, zob)), list(zip(zob, zob, _bleu))) print(im_rouge) print(im_vert) print(im_bleu) -- Pierre Maurette
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-28 01:00 +0100 |
| Message-ID | <slrnr7t4sr.99f.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3310 |
Le 27-03-2020, Pierre Maurette <maurette.pierre@free.fr> a écrit : > Pierre Maurette : > > [...] > >> Fondamentalement une réponse est dans zip(*zipped). >> >> #! /usr/bin/env python3 >> # -*- coding: utf-8 -*- >> >> RVBs = [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)] >> print(RVBs) >> >> (_rouge, _vert, _bleu) = list(zip(*RVBs)) >> >> im_rouge = [(x, 0, 0) for x in _rouge] >> im_vert = [(0, x, 0) for x in _vert] >> im_bleu = [(0, 0, x) for x in _bleu] >> >> print(im_rouge) >> print(im_vert) >> print(im_bleu) > > Pour info, en utilisant zip et une liste de "0" (zob): > > #! /usr/bin/env python3 > # -*- coding: utf-8 -*- > > RVBs = > [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)] > print(RVBs) > > (_rouge, _vert, _bleu, zob) = list(zip(*RVBs)) + [([0,] * len(RVBs)),] > > (im_rouge, im_vert, im_bleu) = (list(zip(_rouge, zob, zob)), > list(zip(zob, _vert, zob)), list(zip(zob, zob, _bleu))) > > print(im_rouge) > print(im_vert) > print(im_bleu) Je vais tester aussi (en utilisant un nom plus "académique" pour zob ;-))
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-28 00:57 +0100 |
| Message-ID | <slrnr7t4o0.99f.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3309 |
Le 27-03-2020, Pierre Maurette <maurette.pierre@free.fr> a écrit :
> Lulu :
>> Bonjour,
>>
>> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
>> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
>> listes :
>> ((r,0,0),(a,0,0),(x,0,0),....)
>> ((0,v,0),(0,b,0),(0,y,0),....)
>> ((0,0,b),(0,0,c),(0,0,z),....)
>>
>> Et je veux faire ça le plus rapidement possible.
>> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
>> comment en "fabriquer" et les exemples que je trouve sur le web ne
>> m'aident pas vraiment. (plus essais infructueux).
>>
>>
>> Mon code :
>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>> #!/usr/bin/python3
>> # -*- coding: utf-8 -*-
>>
>> from PIL import Image
>>
>> Fichier_Image = "Anna_et_Lulu.jpg"
>>
>> ze_image = Image.open( Fichier_Image ).convert("RGB")
>> ze_image.show()
>>
>> (l, h) = ze_image.size
>>
>> # création de l'image rouge
>> ze_image_rouge = Image.new("RGB",(l,h))
>>
>> # traitement pixel par pixel :
>> for y in range(h): # pour y variant de 0 à h-1
>> for x in range(l): # pour x variant de 0 à l-1
>> (rouge, vert, bleu) = ze_image.getpixel((x,y))
>> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>>
>> # création en mémoire de l'image rouge
>> ze_image_rouge_fast = Image.new("RGB",(l,h))
>>
>> liste_pixels = list(ze_image.getdata())
>> liste_pixels_rouges=[]
>>
>> for i in range(len(liste_pixels)):
>> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>>
>> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>>
>> ze_image_rouge.show()
>> ze_image_rouge_fast.show()
>> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>>
>> Sur une image de 1.600.000 pixels, la première double boucle avec deux
>> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
>> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>>
>> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
>> de les remplir que je peux gagner le plus.
>>
>> Merci de vos avis
>
> Fondamentalement une réponse est dans zip(*zipped).
J'arrivais justement sur le ng pour demander la fonction réciproque de
zip, car après une petite heure à lire de la doc sur zip, j'avais (mal
compris donc) que zip servait à "merger" des listes comme dans cet
exemple :
>>> zipped = list(zip([1,2,3],[4,5,6])
>>> zipped
>>> [(1,4),(2,5),(3,6)]
> #! /usr/bin/env python3
> # -*- coding: utf-8 -*-
>
> RVBs =
> [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)]
> print(RVBs)
>
> (_rouge, _vert, _bleu) = list(zip(*RVBs))
Je note la subtilité de l'étoile devant la liste.
Si RVBs est une liste, quel est cet objet désigné par *RVB ?
En tout cas, pour reprendre mon exemple :
>>> (x,y) = list(zip(*zipped))
>>> x
(1, 2, 3)
>>>
(4, 5, 6)
Donc ça marche, ça fait ce dont j'ai besoin.
> im_rouge = [(x, 0, 0) for x in _rouge]
> im_vert = [(0, x, 0) for x in _vert]
> im_bleu = [(0, 0, x) for x in _bleu]
>
> print(im_rouge)
> print(im_vert)
> print(im_bleu)
Je note !
> Remarques:
>
> Avez-vous vraiment besoin d'une image "RVB" pour chaque channel ?
A mon niveau, je voulais poursuivre mon apprentissage sur les listes et
comment les manipuler.
Je n'ai effectivement pas besoin d'une image RVB pour chaque channel,
mais mes élèves, oui !
C'est à but pédagogique, ils ont besoin que la composante rouge d'une
image soit... rouge.
Même si c'est pour leur faire remarquer ensuite que puisque cette
composante étant codée sur 8 bits avec finalement un seul canal puisque
tous les pixels verts et bleus sont à zéro, alors on a bien des niveaux
de gris (ils savent déjà qu'un capteur CCD n'est sensible qu'à la
luminance et qu'il ne fabrique des pixels RVB que grâce au filtre de
Bayer)
> Normalement un channel se représente dans une image "L".
On est bien d'accord et c'est ce que mes élèves (seconde) finiront par
comprendre.
> Peut-être y a-t-il moyen de tout faire à partir de PIL (Image.split(),
> Image.getchannel(channel), et des fonctions de convertion ).
OK, je vais voir ça.
Merci pour vos réponses, toujours de qualité.
C'est rigolo, je relisais justement avant hier nos échanges d'août
dernier dans lesquels vous m'expliquiez bibliothèques, modules, classes
et fonctions... (le sujet était "manipulation d'image")
Merci encore.
[toc] | [prev] | [next] | [standalone]
| From | Nicolas <nicolasp@aaton.com> |
|---|---|
| Date | 2020-03-28 12:12 +0100 |
| Message-ID | <5e7f313a$0$15200$426a74cc@news.free.fr> |
| In reply to | #3311 |
...
> Je n'ai effectivement pas besoin d'une image RVB pour chaque channel,
> mais mes élèves, oui !
>
> C'est à but pédagogique, ils ont besoin que la composante rouge d'une
> image soit... rouge.
>
Pour des élèves de seconde, je n'irai pas dans la voie "zip()".
Mon fils a pris la spécialisation NSI (il est en seconde).
Le programme est très chargé, voire même absurde. Apprendre à coder des
nombres à virgule fixe et des nombres à virgule flottante alors qu'ils
n'ont même pas intégré la logique de base... Mais je m'égare.
Donc, le programme est très chargé et les élèves ont (beaucoup) de mal a
digérer tout ce qu'ils doivent ingurgiter. Leur faire manipuler des
listes, c'est fondamental en Python. Mais, à mon avis, il faut rester le
plus simple possible.
Qu'elle est la différence entre
l = [1, 3, 5, 9]
for e in l :
print(e)
et
l = [1, 3, 5, 9]
for i in range(len(l)) :
print(l[i])
Dans quel cas faut-il utiliser la 1ere forme ? La deuxième forme ?
Ce sont des exemples simples mais ils en sont encore, pour beaucoup, à
mélanger les deux formes d'écriture.
"zip()" est très utile mais le risque de les embrouiller est là.
Il vaut mieux leur apprendre à parfaitement maitriser les bases.
Mais ce n'est que mon avis ;)
Nicolas
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-28 19:15 +0100 |
| Message-ID | <slrnr7v51i.f9b.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3313 |
Le 28-03-2020, Nicolas <nicolasp@aaton.com> a écrit : >> Je n'ai effectivement pas besoin d'une image RVB pour chaque channel, >> mais mes élèves, oui ! >> >> C'est à but pédagogique, ils ont besoin que la composante rouge d'une >> image soit... rouge. > > Pour des élèves de seconde, je n'irai pas dans la voie "zip()". Tu as évidemment raison, je ne parlais de but pédagogique que pour éviter de les surprendre par une composante rouge qui s'affiche en niveau de gris. Mais comprendre zip(), c'était aussi un but pédagogique, mais pour moi seul ;-) Je ne donnerai mon code source qu'aux quelques geeks de mes 120 élèves qui me poseraient des questions sur la manipulation des listes... > Mon fils a pris la spécialisation NSI (il est en seconde). Euh... NSI (Numérique et Sciences Informatiques), c'est en première. Je suis prof de seconde en Physique/Chimie et SNT (Sciences Numériques et Technologie) > Le programme est très chargé, voire même absurde. Apprendre à coder des > nombres à virgule fixe et des nombres à virgule flottante alors qu'ils > n'ont même pas intégré la logique de base... Mais je m'égare. > > Donc, le programme est très chargé et les élèves ont (beaucoup) de mal a > digérer tout ce qu'ils doivent ingurgiter. Leur faire manipuler des > listes, c'est fondamental en Python. Mais, à mon avis, il faut rester le > plus simple possible. Oui. > Qu'elle est la différence entre > > l = [1, 3, 5, 9] > for e in l : > print(e) > > et > > l = [1, 3, 5, 9] > for i in range(len(l)) : > print(l[i]) > > Dans quel cas faut-il utiliser la 1ere forme ? La deuxième forme ? Ça, j'ai su mais j'ai oublié... Peux-tu rafraichir ma mémoire ? > Ce sont des exemples simples mais ils en sont encore, pour beaucoup, à > mélanger les deux formes d'écriture. > > "zip()" est très utile mais le risque de les embrouiller est là. > > Il vaut mieux leur apprendre à parfaitement maitriser les bases. Je suis bien d'accord. > Mais ce n'est que mon avis ;) Tout à fait valable (mais ça n'est que mon avis ;-)
[toc] | [prev] | [next] | [standalone]
| From | Nicolas <nicolasp@aaton.com> |
|---|---|
| Date | 2020-03-28 21:26 +0100 |
| Message-ID | <5e7fb2dc$0$4725$426a74cc@news.free.fr> |
| In reply to | #3316 |
Le 28/03/2020 à 19:15, Lulu a écrit :
>
> Mais comprendre zip(), c'était aussi un but pédagogique, mais pour moi
> seul ;-)
Dans ce cas, rien à dire. ;)
>
> Je ne donnerai mon code source qu'aux quelques geeks de mes 120 élèves
> qui me poseraient des questions sur la manipulation des listes...
>
>> Mon fils a pris la spécialisation NSI (il est en seconde).
>
> Euh... NSI (Numérique et Sciences Informatiques), c'est en première.
> Je suis prof de seconde en Physique/Chimie et SNT (Sciences Numériques
> et Technologie)
Oups, désolé. Il est en première :p
>> Qu'elle est la différence entre
>>
>> l = [1, 3, 5, 9]
>> for e in l :
>> print(e)
>>
>> et
>>
>> l = [1, 3, 5, 9]
>> for i in range(len(l)) :
>> print(l[i])
>>
>> Dans quel cas faut-il utiliser la 1ere forme ? La deuxième forme ?
>
> Ça, j'ai su mais j'ai oublié...
> Peux-tu rafraichir ma mémoire ?
Les deux exemples font exactement la même chose. Ils affichent les
éléments de la liste "l".
Dans le premier exemple, on itère sur les éléments de la liste.
Avec "for e in l", e vaut successivement 1, 3, 5 et 9.
On peut afficher l'élément de la liste directement avec "print(e)"
Dans le second exemple, on itère sur les indices des éléments de la liste.
Avec "for i in range(len(l))", i vaut successivement 0, 1, 2 et 3.
Du coup, pour afficher l'élément de la liste on ne fait pas "print(e)"
mais "print(l[i])".
En Python, la première forme est préférable.
Pourquoi s’embêter avec des indices quand il n'y en a pas besoin ?
En plus, ça évite les bugs dû aux erreurs de gestion des indices.
Mais, parfois, on a besoin de l'indice. Par exemple, pour afficher :
0 -> 1
1 -> 3
2 -> 5
3 -> 9
On écrira :
for i in range(len(l)) :
print(i, "->", l[i])
Pas le choix, il faut l'indice.
On peut faire mieux en écrivant :
for i,e in enumerate(l) :
print(i, "->", e)
"enumerate()" renvoie des tuples contenant l'indice et l'élément
correspondant de la liste.
L'écriture est plus concise et le risque de bug est réduit :
"enumerate(l) " est plus simple que "range(len(l))" et on a i et e en phase.
Bon week-end
[toc] | [prev] | [next] | [standalone]
| From | Lulu <lulu042@fry.fr.invalid> |
|---|---|
| Date | 2020-03-30 16:54 +0200 |
| Message-ID | <slrnr8421m.df2.lulu042@Minty.Rock-n-Roll.org> |
| In reply to | #3317 |
Le 28-03-2020, Nicolas <nicolasp@aaton.com> a écrit : > Le 28/03/2020 à 19:15, Lulu a écrit : >>> Qu'elle est la différence entre >>> >>> l = [1, 3, 5, 9] >>> for e in l : >>> print(e) >>> >>> et >>> >>> l = [1, 3, 5, 9] >>> for i in range(len(l)) : >>> print(l[i]) >>> >>> Dans quel cas faut-il utiliser la 1ere forme ? La deuxième forme ? >> >> Ça, j'ai su mais j'ai oublié... >> Peux-tu rafraichir ma mémoire ? > > Les deux exemples font exactement la même chose. Ils affichent les > éléments de la liste "l". > > Dans le premier exemple, on itère sur les éléments de la liste. > Avec "for e in l", e vaut successivement 1, 3, 5 et 9. > On peut afficher l'élément de la liste directement avec "print(e)" > > Dans le second exemple, on itère sur les indices des éléments de la liste. > Avec "for i in range(len(l))", i vaut successivement 0, 1, 2 et 3. > Du coup, pour afficher l'élément de la liste on ne fait pas "print(e)" > mais "print(l[i])". > > En Python, la première forme est préférable. OK. Et j'ai testé, la première forme est aussi plus rapide de 30% environ. > Pourquoi s’embêter avec des indices quand il n'y en a pas besoin ? Effectivement. > En plus, ça évite les bugs dû aux erreurs de gestion des indices. > > Mais, parfois, on a besoin de l'indice. Par exemple, pour afficher : > 0 -> 1 > 1 -> 3 > 2 -> 5 > 3 -> 9 > > On écrira : > for i in range(len(l)) : > print(i, "->", l[i]) > > Pas le choix, il faut l'indice. > > On peut faire mieux en écrivant : > for i,e in enumerate(l) : > print(i, "->", e) > > "enumerate()" renvoie des tuples contenant l'indice et l'élément > correspondant de la liste. > > L'écriture est plus concise et le risque de bug est réduit : > "enumerate(l) " est plus simple que "range(len(l))" et on a i et e en phase. OK, je note le enumerate() > Bon week-end Tout pareil. Merci pour tes réponses instructives.
[toc] | [prev] | [next] | [standalone]
| From | ast <ast@invalid> |
|---|---|
| Date | 2020-04-09 13:27 +0200 |
| Message-ID | <5e8f06a3$0$4700$426a74cc@news.free.fr> |
| In reply to | #3306 |
Le 27/03/2020 à 00:50, Lulu a écrit :
>
> Bonjour,
>
> J'ai besoin de manipuler des listes rapidement pour manipuler une image.
> D'une liste ((r,v,b),(a,b,c),(x,y,z),.....), je veux passer à trois
> listes :
> ((r,0,0),(a,0,0),(x,0,0),....)
> ((0,v,0),(0,b,0),(0,y,0),....)
> ((0,0,b),(0,0,c),(0,0,z),....)
>
> Et je veux faire ça le plus rapidement possible.
> J'imagine que ça pourrait passer par un générateur, mais je ne sais pas
> comment en "fabriquer" et les exemples que je trouve sur le web ne
> m'aident pas vraiment. (plus essais infructueux).
>
>
> Mon code :
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
> #!/usr/bin/python3
> # -*- coding: utf-8 -*-
>
> from PIL import Image
>
> Fichier_Image = "Anna_et_Lulu.jpg"
>
> ze_image = Image.open( Fichier_Image ).convert("RGB")
> ze_image.show()
>
> (l, h) = ze_image.size
>
> # création de l'image rouge
> ze_image_rouge = Image.new("RGB",(l,h))
>
> # traitement pixel par pixel :
> for y in range(h): # pour y variant de 0 à h-1
> for x in range(l): # pour x variant de 0 à l-1
> (rouge, vert, bleu) = ze_image.getpixel((x,y))
> ze_image_rouge.putpixel((x,y), ( rouge, 0, 0))
>
> # création en mémoire de l'image rouge
> ze_image_rouge_fast = Image.new("RGB",(l,h))
>
> liste_pixels = list(ze_image.getdata())
> liste_pixels_rouges=[]
>
> for i in range(len(liste_pixels)):
> liste_pixels_rouges.append((liste_pixels[i][0], 0, 0))
>
> ze_image_rouge_fast.putdata(liste_pixels_rouges)
>
> ze_image_rouge.show()
> ze_image_rouge_fast.show()
> 8<-----------8<---------8<----------8<----------8<----------8<----------8<
>
> Sur une image de 1.600.000 pixels, la première double boucle avec deux
> for imbriqués bricole pendant 7 secondes (pas très étonnant), mais la
> deuxième boucle qui remplit trois listes n'est que 4 fois plus rapide.
>
> Je crois que c'est en jouant sur ma manière de créer ces trois listes et
> de les remplir que je peux gagner le plus.
>
> Merci de vos avis
>
L = [(1,2,3),(11,12,13),(21,22,23),(31,32,33),(411,412,413),(521,522,523)]
g1 = ((x, 0, 0) for x,y,z in L)
g2 = ((0, y, 0) for x,y,z in L)
g1 = ((0, 0, Z) for x,y,z in L)
next(g1)
(1, 0, 0)
next(g1)
(11, 0, 0)
for _, y, _ in g2:
print(y)
2
12
22
32
412
522
[toc] | [prev] | [standalone]
Back to top | Article view | fr.comp.lang.python
csiph-web