Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Pierre Maurette Newsgroups: fr.comp.lang.python Subject: Re: vitesse manipulation liste (generateur ?) Date: Fri, 27 Mar 2020 17:36:23 +0100 Organization: A noiseless patient Spider Lines: 91 Message-ID: References: Reply-To: maurette.pierre@free.fr Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-15"; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="3564a57df5d63122e3e581e6c435eb55"; logging-data="19800"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19oHFNdfhKVCTwKl2iYCmsPyHsJGD8xNDc=" Cancel-Lock: sha1:scukN3elE91+/xqR6HNCJ8iYjYE= X-Newsreader: MesNews/1.08.06.00-fr X-Face: cmi$3R1_J{[}5K|8d'LDiJ$SsZ*gn,j*PhJ#KVGt+45,E_N9O}GrhhQ>fb&q<&lz=g%PEv' u"m)N|KrBMux?2:E?N7Uw3L#H>L#GwM}gY:.`W.qu z`1'W'h-AXPmB]#7~<+@H.<0M`-jBkCWbmkcT_*LBVD3|p1a?h1H;cHq{$-vbeP@Hdcqp5z~lwU7ZK `~ Xref: csiph.com fr.comp.lang.python:3309 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