IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Optimisation des boucles for


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 52
    Par défaut Optimisation des boucles for
    Bonjour,
    J'ai un soucis suite a la conversion d'un script java en python en effet, il y a un passage nécessitant quartes boucles for imbriquées afin de parcourir la matrice d'une image 200x250px par bloc carré de 35x35px. Le bloc carré est chaque fois déplacé d'un pixel vers la droite puis arrivé au dernier bloc pouvant rentrer dans les 250px de l'image de base, il descend d'un pixel, et ainsi dessuite jusqu'à se retrouver tout en bas à droite.

    En java, cela s'exécute en même pas 1 seconde, et en python, cela prend plusieurs minutes!

    Existe il un moyen d'optimiser le script pour gagner de la vitesse?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    >>> print Size
    [[ 250.  200.]
     [  35.   35.]
     [  35.   35.]]
    >>> 
     
     
    def COUNT():
        Res = zeros((Size[0,1],Size[0,0]))
        CountRet1, CountRet2 = 0, 0
        for x in range(0,Size[0,1]-Size[1,1],1): #Pour chaque Pattern pouvant entrer en hauteur
            print "Ligne ", x+1 ,"/",Size[0,1]-Size[1,1]
            for y in range(0,Size[0,0]-Size[1,0],1): # Pour chaque Pattern pouvant entrer en largeur
                #--< Parcours global de l'image avec les deux rétines
                for r in range (0,2,1):#--< Retine 1 puis 2
                    Sum = 0
                    for a in range(0,Size[1,1],1):
                        for b in range(0,Size[1,0],1):
                            if Res[a+x,b+y] != 1:
                                Sum += Weight[a,b,r] * Map[a+x,b+y]
                    if Sum > Threshold:
                        if r == 0:
                            CountRet1 += 1
                            rect = canvas.create_rectangle(y,x,y+Size[1,1],x+Size[1,0], width=2, outline="blue")
                        elif r == 1:
                            CountRet2 += 1
                            rect = canvas.create_rectangle(y,x,y+Size[1,1],x+Size[1,0], width=2, outline="red")
                        for a in range(0,Size[1,1],1):
                            for b in range (0,Size[1,0],1):
                                Res[a+x,b+y] = 1
        print "Nb Pattern_1 :",CountRet1
        print "Nb Pattern_2 :",CountRet2
    Merci!

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    >>> print Size
    [[ 250. 200.]
    [ 35. 35.]
    [ 35. 35.]]
    >>>
    donne à penser que tu utilises numpy. Est-ce bien le cas ?




    Si c’est c'est bien ça, j’attendrais une notation Size[0,1,:]

    Que désignent Size[0,1] et Size[0,0] ?





    for r in range (0,2,1):
    à la place de for r in (0,1):
    ça m’a bien fait rigoler

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    On dirait que c'est une convolution que tu calcules (ou plutôt deux, pour r=0 et r=1). Tu auras de bien meilleurs résultats en utilisant scipy; je pense en particulier à la fonction scipy.ndimage.convolve.
    Et si la matrice Weight est décomposable, cela irait encore plus vite de faire deux convolutions 1D au lieu d'une convolution 2D.

  4. #4
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 52
    Par défaut
    Citation Envoyé par eyquem Voir le message
    donne à penser que tu utilises numpy. Est-ce bien le cas ?
    Si c’est c'est bien ça, j’attendrais une notation Size[0,1,:]
    Oui, c'est numpy, seulement c'est à 2D donc je peux pas mettre 3 indice, je vois pas de problème dans ma notation...


    Citation Envoyé par eyquem Voir le message
    Que désignent Size[0,1] et Size[0,0] ?
    Size[0,0] correspond a la largeur de la 1ère image (250px)
    Size[0,1] correspond a la hauteur de cette même image (200px)

    ensuite sur la 2nd et 3ème ligne se sont les dimension de image 2 puis 3, qui sont a reconnaitre les unes a la suite des autres dans l'image principale.

    Citation Envoyé par eyquem Voir le message
    for r in range (0,2,1):
    à la place de for r in (0,1):
    ça m’a bien fait rigoler
    Effectivement c'est modifiable, et probablement pas que ici! Mais cela a t-il une grosse importance?

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonjour,

    en général mixer des tableaux numpy et des boucles for n'est pas une bonne idée. il vaut mieux utiliser les tableaux en tant que tout. en vectorisant, les gains sont très intéressants, mais cela demande un peu d'apprentissage

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 52
    Par défaut
    Citation Envoyé par kango Voir le message
    bonjour,

    en général mixer des tableaux numpy et des boucles for n'est pas une bonne idée. il vaut mieux utiliser les tableaux en tant que tout. en vectorisant, les gains sont très intéressants, mais cela demande un peu d'apprentissage
    effectivement, en utilisant un principe de sous matrice, c'est nettement plus rapide!
    Merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    def COUNT():
        print"Detecting..."
        Res = zeros((int(Size[0,1]),int(Size[0,0])))
        CountRet1, CountRet2 = 0, 0
        Line = 0
        for Line in range(0,int(Size[0,1]-Size[1,1]),1):
            for Column in range (0,int(Size[0,0]-Size[1,1]),1):
                for r in (0,1):
                    Sum = 0
                    if Res[Line:Line+int(Size[1,1]),Column:Column+int(Size[1,0])].sum() == 0:
                        Sum += Weight[:,:,r] * Map[Line:Line+int(Size[1,1]),Column:Column+int(Size[1,0])]
                        Sum = Sum.sum()
     
                        if Sum > Threshold:
                            if r == 0:
                                CountRet1 += 1
                                rect = canvas.create_rectangle(Column,Line,Column+Size[1,1],Line+Size[1,0], width=2, outline="blue")
                            elif r == 1:
                                CountRet2 += 1
                                rect = canvas.create_rectangle(Column,Line,Column+Size[1,1],Line+Size[1,0], width=2, outline="red")
                            root.update()#On actualise l'affichage
                            #On marque les pixels reconnus avec un contour de 5px (pour distinguer 2 motifs très proches)
                            Res[Line+5:Line+int(Size[1,1])-5,Column+5:Column+int(Size[1,0])-5] = ones((Size[1,1]-10,Size[1,0]-10))
     
     
        print "Pattern_1 detected:",CountRet1, "times"
        print "Pattern_2 detected:",CountRet2,  "times"

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Optimisation des boucles
    Par Programmeurfou dans le forum MATLAB
    Réponses: 5
    Dernier message: 07/11/2008, 11h46
  2. Utilisation des boucles for
    Par _Michel dans le forum Débuter
    Réponses: 6
    Dernier message: 23/09/2008, 11h49
  3. Optimiser 2 boucles FOR ?
    Par B&B dans le forum SQL
    Réponses: 6
    Dernier message: 18/04/2008, 15h43
  4. Comment optimiser plusieurs boucles FOR-END imbriquées
    Par totoc1001 dans le forum MATLAB
    Réponses: 26
    Dernier message: 13/05/2007, 17h59
  5. tableaux dynamiques ds des boucles FOR imbriquees
    Par areuh_fr dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 13/12/2006, 11h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo