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 :

[PIL ou numpy]Correction de couleur sur une image


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Par défaut [PIL ou numpy]Correction de couleur sur une image
    Bonjour,

    Malgré mes recherches je n'ai pas encore trouvé comment faire.

    Voilà, c'est assez simple, je cherche a appliquer une correction de couleur sur une image, tel une courbe photoshop.

    l'idée est de passer par une courbe de bézier, mais PIL ne permet pas de le faire directement.

    Avez vous des solutions a me proposer.
    Merci d'avance.

  2. #2
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Par défaut Première solution mais trop, beaucoup trop lente...
    Bonjour,

    j'ai réussi a obtenir ce que je veux en créant une liste représentant mon bezier, mais si le traitement est assez rapide sur une petite image, il est beaucoup trop long sur une image haute definition (3000px x2000 px). Auriez vous une idée pour optimiser le temps de traitement, l'objectif étant de l'intégrer dans un serveur de traitement d'image.

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    factor=2 #facteur de correction pour retrouver les corrections de photoshop
     
    def make_bezier(xys):
        # xys should be a sequence of 2-tuples (Bezier control points)
        n = len(xys)
        combinations = pascal_row(n-1)
        def bezier(ts):
            # This uses the generalized formula for bezier curves
            # http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization
            result = []
            for t in ts:
                tpowers = (t**i for i in range(n))
                upowers = reversed([(1-t)**i for i in range(n)])
                coefs = [c*a*b for c, a, b in zip(combinations, tpowers, upowers)]
                result.append(
                    tuple(sum([coef*p for coef, p in zip(coefs, ps)]) for ps in zip(*xys)))
            return result
        return bezier
     
    def pascal_row(n):
        # This returns the nth row of Pascal's Triangle
        result = [1]
        x, numerator = 1, n
        for denominator in range(1, n//2+1):
            # print(numerator,denominator,x)
            x *= numerator
            x /= denominator
            result.append(x)
            numerator -= 1
        if n&1 == 0:
            # n is even
            result.extend(reversed(result[:-1]))
        else:
            result.extend(reversed(result))
        return result
     
    def bezierRGB(r,g,b):
        ts = [t/100.0 for t in range(101)]
        dcouches={}
        dcorr={'R':r,'G':g,'B':b}
        for c in dcorr :
            xys = [(0, 0), (128,128+(dcorr[c]*factor)), (255, 255)]
            bezier = make_bezier(xys)
            points = bezier(ts)
            dcouches[c]=points
        return [dcouches['R'],dcouches['G'],dcouches['B']]
     
    def newPoint(pt,bezier):
        #return (pt,bezier)
        a=0
        while pt > bezier[a][0] :
            a+=1
     
        if a>0 : npt = int(bezier[a][1])
        else : npt = int(bezier[0][1])
     
        return (pt,npt,bezier)
     
    def colorAdjustement(im,r,g,b):
        lbezierRGB=bezierRGB(r,g,b)
        width, height = im.size
        colortuples = im.getcolors(maxcolors=17000000)
        pix = im.load()
        u=max(len(lbezierRGB[0]),len(lbezierRGB[1]),len(lbezierRGB[2])) #longueur max des points de courbes
        print u
        for x in range(0, width):
            for y in range(0, height):
                ro,go,bo=list(pix[x,y])
                color=(ro,go,bo)
     
     
                if y==100 and x==100:
                    print newPoint(ro,lbezierRGB[0])
                if r !=0 :
                    ro = newPoint(ro,lbezierRGB[0])[1]
                if g !=0 :
                    go = newPoint(go,lbezierRGB[1])[1]
                if b !=0 :
                    bo = newPoint(bo,lbezierRGB[2])[1]
     
     
                im.putpixel((x, y), (ro,go,bo))
     
        return im
     
    if __name__ == '__main__':
        import Image
        im = Image.open("0002.JPG")
        im = colorAdjustement(im,30,10,0)
        im.save('0002_CorrectionBezier.JPG')
    Merci d'avance

  3. #3
    Membre confirmé

    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 19
    Par défaut
    Bonjour,

    Je suggère numpy pour construire une courbe de bézier.

    Un petit exemple avec numpy. La fonction adjust_colors prend en entrée une image couleur (np.array de taille (longueur, largeur, 3)), et quatre autres tableaux de taille (256,) qui correspondent à des courbes (bézier par exemple). Ces courbes vont être appliquées sur chaque canaux, rouge, vert, bleu, et les trois en même temps (changement de contraste).

    L'indice d'une valeur d'un tableau numpy correspond à l'abscisse d'un point de la courbe bézier, la valeur associée à cet indice correspond à l'ordonnée de ce point. Dès lors, il suffit, en travaillant sur un canal, de changer la valeur V d'un pixel par la valeur d'indice V de ce tableau.

    Un exemple plutôt rapide pour une photo couleur de taille 768x1024 (7-8 secondes) :

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import scipy.misc
    import numpy as np
    import matplotlib.pyplot as plt
     
    def adjust_colors(image, red, green, blue, value):
        for i in xrange(image.shape[0]):
            for j in xrange(image.shape[1]):
                image[i, j, 0] = red[image[i, j, 0]]
                image[i, j, 1] = green[image[i, j, 1]]
                image[i, j, 2] = blue[image[i, j, 2]]
                for x in xrange(image[i, j].shape[0]):
                    image[i, j, x] = value[image[i, j, x]]
     
    # load image
    photo = scipy.misc.face()
     
    # manipulation des canaux rgb l'image
    # courbe de couleur pour chaque canal
    # .
    #    .
    #      .
    #         .
    #            .
    # 0  50%  100%
    r = g = b = np.arange(0, 256)[::-1]
     
    # manipulation du contraste de l'image
    # courbe de contraste
    # .       .
    #  .     .
    #   .   .
    #    . .
    #     .
    # 0  50%  100%
    v0 = np.linspace(0, 255, 128)
    v1 = v0.copy()[::-1]
    v = np.concatenate((v1, v0))
    adjust_colors(photo, r, g, b, v)
     
    # affichage de l'image
    plt.imshow(photo)
    plt.show()

  4. #4
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Par défaut
    merci,

    j'ai testé votre code from scratch, mis a par que j'ai été obligé de changer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    photo = scipy.misc.face()
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    photo = scipy.misc.imread('0002.JPG')
    car scipy.misc.face n'existe pas dans la version mise à ma disposition.

    Malgré tout, mon image fait 3888x2592, et c'est la taille minimum des images que je vais devoir traiter et le temps d'exécution est encore trop long (cependant les corrections ne sont pas les même). Je pense que l'on est au même niveau que mon code.
    Je pense que tout se passe au niveau des doubles boucles.

    une lecture de time donne 97.8 pour votre code contre 113.6 pour le mien. Mieux mais il faudrait que j'arrive a tomber sous les 50 pour être bon.

    Je vais décortiquer votre code pour bien comprendre, car c'est un peu flou pour l'instant.

    Merci.

  5. #5
    Membre confirmé

    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 19
    Par défaut
    Autant pour moi.
    Maintenant, je te défie de faire mieux !

    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
    34
    35
    36
    37
    38
    39
    40
    import scipy.misc
    import numpy as np
    import matplotlib.pyplot as plt
     
    def adjust_colors(image, red, green, blue, value):
        image[:, :, 0] = red[image[:, :, 0]]
        image[:, :, 1] = green[image[:, :, 1]]
        image[:, :, 2] = blue[image[:, :, 2]]         
        for i in xrange(image.shape[2]):
             image[:, :, i] = value[image[:, :, i]]
     
    # load image
    photo = scipy.misc.face()
     
    # manipulation des canaux rgb l'image
    # courbe de couleur pour chaque canal
    # .
    #    .
    #      .
    #         .
    #            .
    # 0  50%  100%
    r = g = b = np.arange(0, 256)[::-1]
     
    # manipulation du contraste de l'image
    # courbe de contraste
    # .       .
    #  .     .
    #   .   .
    #    . .
    #     .
    # 0  50%  100%
    v0 = np.linspace(0, 255, 128)
    v1 = v0.copy()[::-1]
    v = np.concatenate((v1, v0))
    adjust_colors(photo, r, g, b, v)
     
    # affichage de l'image
    plt.imshow(photo)
    plt.show()

  6. #6
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Par défaut
    Pas mieux

    Mais j'ai besoin d'explication de texte. Pouvez vous m'expliquer le code. et comment passer les paramètres pour obtenir le type de correction juste RGB, comme le fait mon code.

    Merci d'avance.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 03/03/2015, 14h57
  2. [Débutant] Fleche, Texte, Cadre et Choix des couleurs sur une image
    Par niepoc dans le forum MATLAB
    Réponses: 10
    Dernier message: 16/07/2008, 16h44
  3. placer un filtre de couleur sur une image
    Par mm2405 dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 06/12/2007, 11h25
  4. [Pygame]Supprimer/masquer les pixels d'une même couleur sur une image
    Par Mysti¢ dans le forum Programmation multimédia/Jeux
    Réponses: 2
    Dernier message: 10/05/2007, 13h40
  5. [CSS]Supprimer couleur sur une image en lien
    Par Nasky dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 10/06/2006, 14h22

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