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

Calcul scientifique Python Discussion :

Numpy replace vecteur dans un tab 3 dimensions [Python 3.X]


Sujet :

Calcul scientifique Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 37
    Par défaut Numpy replace vecteur dans un tab 3 dimensions
    Bonjour,

    Je cherche un faire une manip avec numpy. (je pense que c'est réalisable).
    J'ai un tableau 3 dimensions (une image), j'isole tout les couleurs de l'image avec .
    Mon but est de sélectionner une couleur (vecteur de 3) et de mettre tour le tableau à 0 sauf les ligne de la couleur sélectionner.
    J'ai déjà un résultat avec 2 boucles for mais c'est super long et je suis sur que numpy gère ce cas.

    J'ai déjà fait plusieurs essais avec combiné avec mais je n'obtient pas le résultat voulu.

    Avez des piste pour la méthode de numpy pour réaliser ça ?

  2. #2
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Salut,

    Je ne suis pas certain d'avoir bien saisi le problème. Un petit exemple serait le bienvenu. En 2D encore mieux.

    Si je prends:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    x = np.array([
        [0, 1, 1, 0],
        [1, 0, 1, 0],
    ])
    Je peux remplacer tous les 0 par des 2 :
    Puis remplacer tous ce qui n'est pas 2 par des 0 :
    L'une ou l'autre des méthodes permettent de remplacer des valeurs par d'autres. Mais si on parle de vecteur, pourvu que l'on obtienne l'indice de ce dernier, alors on peut aussi le remplacer. Dans cet exemple on remplace la colonne i (en comptant de zero) par des zéros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x[:, i:i+1] = np.zeros((x.shape[0], 1))
    J

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 37
    Par défaut
    Merci pour ta réponse.

    Oui j'ai fait beaucoup d'essais sur les matrices et remplacer par un nombre. Mais moi c'est un peu plus pousser pour le coup

    par exemple:

    mon tableau :
    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
    array([[[0, 55, 4],
            [0, 250, 10],
            [10,1 0, 0],
            ...,
            [0, 70, 90],
            [1, 10, 0],
            [0, 0, 0]],
     
           [[100, 0, 85],
            [150, 0, 0],
            [0, 204, 0],
            ...,
            [100, 0, 85],
            [40, 50, 0],
            [0, 0, 0]]])
    Je récupère toutes les couleur unique. Et par exemple si je sélectionne le vecteur [100, 0, 85], mon but est de mettre toutes les valeurs à 0 sauf les lignes qui sont égale à mon vecteur.
    pour obtenir :
    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
    array([[[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            ...,
            [0, 0, 0],
            [0 0, 0],
            [0, 0, 0]],
     
           [[100, 0, 85],
            [0, 0, 0],
            [0, 0, 0],
            ...,
            [100, 0, 85],
            [0, 0, 0],
            [0, 0, 0]]])
    Numpy a forcement prévu ce cas je pense (c'est plus précis ?)

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    J'appuie le message de Julien :
    Si vous avez déjà un code qui fonctionne mais qui est long alors :
    - Fournissez ce code, même s'il utilise des for- Donnez nous une matrice simple (nous balancer pas toute votre image, prenez en juste une petite sous partie, que l'on puisse tester)
    - En principe j'aurais aussi dit la matrice d'arrivée souhaitée (le résultat attendu), mais si vous nous transmettez correctement les 2 premiers points on devrait être capable d'identifier le résultat que vous souhaitez obtenir, à moins que votre code avec les for soit lui même bugger, dans ce cas ce 3ieme est lui aussi nécessaire.

    Tant qu'on n'a pas ca, difficile de vous aider correctement.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Salut,

    Citation Envoyé par dentfree Voir le message
    Avez des piste pour la méthode de numpy pour réaliser ça ?
    On peut faire çà avec all pour fabriquer un masque de booléen et s'en servir pour mettre à jour l'array initial.

    On part d'une image de 4 pixels ou la diagonale est à [1,2,3]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> import numpy as np
    >>> im = np.zeros((2,2,3))
    >>> im[0,0] = im[1,1] = [1,2,3]
    puis on fabrique un masque en sélectionnant ce qu'on veut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >>> mask = (im == [1,2,3]).all(axis=2)
    le masque est un tableau 2D de booléens.
    Puis on assigne d'autres valeurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> im[mask] = [5,5,5]
    >>> im
    array([[[5., 5., 5.],
            [0., 0., 0.]],
     
           [[0., 0., 0.],
            [5., 5., 5.]]])
    très pratique pour faire des seuillages (avec >=...)

    note: tout çà pour montrer qu'en levant un peu le nez du guidon, on peut reproduire le problème sans même image juste avec une matrices 2x2 de simulacres de pixels. L'important n'est pas tellement dans les dimensions du tableau mais dans sa structure et les opérations qu'on projette d'y faire.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 37
    Par défaut
    Voici le code (qui est fonctionnel):
    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
     
     
    def imshow_components(image):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        ret, labels = cv2.connectedComponents(gray)
        label_hue = np.uint8(179*labels/np.max(labels))
        blank_ch = 255*np.ones_like(label_hue)
        labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
     
        labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
        labeled_img[label_hue==0] = 0
        return (labeled_img)
     
    def mask_fct(img):
        img = imshow_components(img)
        coor = []
        colors = []
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                if (img[i][j][2] != 0 or img[i][j][1] != 0 or img[i][j][0] != 0):
                    coor.append((i, j))
                    color = (img[i][j][0], img[i][j][1], img[i][j][2])
                    if (color not in colors):
                        colors.append(color)
        nb_spot = (len(colors))
     
        mask = np.zeros((img.shape[0],img.shape[1],nb_spot), dtype=bool)
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                color = (img[i][j][0], img[i][j][1], img[i][j][2])
                if (color in colors):
                    index = colors.index(color)
                    mask[i][j][index] = True
        class_ids = np.zeros((nb_spot), dtype=np.int32)
        class_ids[:] = 1
        return(mask, class_ids)
    L'image est un fond noir avec plusieurs tache blanche dessus
    La fonction prend mon image en noir et blanc et retourne cette image mais avec une couleur différente par tache.
    un exemple d'image réduit a 10*10 pixels :
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
     
    array([[[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0, 255, 136],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0, 255, 136],
            [  0, 255, 136],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0, 255, 136],
            [  0, 255, 136],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [247, 255,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [255,   0, 119],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [255,   0, 119],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  8,   0, 255],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]],
     
           [[  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0],
            [  0,   0,   0]]], dtype=uint8)
    Ma première double boucle for est remplacer par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    colors =  np.unique(img.reshape(-1, img.shape[-1]), axis=0)
    Ce qui me donne un tableau avec chaque couleur unique de l'image, ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (array([[  0,   0,   0],
            [  0, 255, 136],
            [  8,   0, 255],
            [247, 255,   0],
            [255,   0, 119]], dtype=uint8))
    Mon but final est de sélectionner une couleur, par exemple [247, 255, 0] (présente dans mon tableau). Et dans mon image de 10*10 mettre tout les points à 0 excepter ceux de la couleur sélectionnée et ainsi isoler cette partie de l'image.

    Je pense qu'avec un code style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a = np.where(np.all(<mon image> != <ma couleur select>, axis=1), [0,0,0], <mon image>)
    je dois pas être trop loin mais je n'ai pas le résultat voulu

    Je ne peux pas plus détailler
    Le code est parfaitement fonctionnel pour mon utilisation mais super lent.

    @wiztricks, je vais essayer de creuser ta solution, merci

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Félicitation pour la rédaction de votre premier vrai message.
    Alors le masque que vous chercher à produire (10,10, nb_colors), alors qu'il serait plus facile d'avoir qqch comme un array de taille (nb_colors, 10,10) (modifier 10 par la taille de l'image bien sûr), voire même une liste de longueur nb_colors, dont chaque élément est un np.array booléen de taille (10,10).

    Wiztricks vous a en effet déjà donné ce qu'il vous faut je pense.

    Voici comment on peut construire un masque pour une couleur donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    colors =  np.unique(img.reshape(-1, img.shape[-1]), axis=0)
    print(colors)
     
    one_color = colors[3]
     
    mask = (img == one_color).all(axis=2)
    puis comment l'utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    img[np.invert(mask)]=[0,0,0]
     
    print(img)
    Notez le np.invert, car vous ne voulez pas modifier là où vous avez trouvez la couleur, mais vous voulez modifier (mettre à 0) partout où vous n'avez pas la couleur. Vous auriez aussi pu faire sans ce np.invert en construisant directement le mask des pixels qui ne sont pas de la couleur voulue:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mask = (img != one_color).all(axis=2)
    .

    A vous de voir comment vous voulez rassemblez ensuite l'information pour l'ensemble des couleurs.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 37
    Par défaut
    Merci de coup de main j'ai réussis l'optimisation voulu.

    Voici le code des fois que ça intéresse des gens pour plus tard>

    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
     
    def mask_fct(img):
        img = imshow_components(img)
        colors = np.unique(img.reshape(-1, img.shape[-1]), axis=0)
        colors = colors[1:]
        masks = None
        save_img = img.copy()
        for index, color in enumerate(colors):
            img = save_img.copy()
            mask = (img == color).all(axis=2)
            img[np.invert(mask)]=[0,0,0]
            img = img.astype(bool)
            mask = np.logical_or.reduce(img, axis=2) 
            if index == 0:
                masks = mask.copy()
            else:
                masks = np.dstack((masks, mask))
        class_ids = np.zeros((len(colors)), dtype=np.int32)
        class_ids[:] = 1
        return(masks, class_ids)
    Pour la forme de mon masque final (hauteur*largeur*nombre de couleur), je dois le laisser sous cette forme pour l'algo qui l'exploite après.

    Bonne journée et encore merci.

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

Discussions similaires

  1. [VBA-E] Utiliser le range dans un tab croisé dynamique
    Par GoLDoZ dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/03/2006, 16h12
  2. 2 valeurs distincts dans un tableau à 2 dimensions...
    Par toyyo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 23/08/2005, 16h00
  3. Couleur et onglet dans le Tab Control Page
    Par loufab dans le forum IHM
    Réponses: 15
    Dernier message: 04/05/2005, 00h04
  4. tri alphabétique dans un tableau deux dimensions
    Par *!!cocco!!* dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 06/12/2004, 21h38
  5. donée de plusieur vecteur dans une structure ??
    Par lipczynski dans le forum C++
    Réponses: 5
    Dernier message: 13/08/2004, 08h17

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