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

Images Discussion :

Traitement d'images avec la ToolBox


Sujet :

Images

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut Traitement d'images avec la ToolBox
    Bonjour,

    Dans le cadre de mon alternance, je dois développer un algorithme de reconnaissance de défauts sur une image et j'ai besoin de votre aide pour décomposer le problème d'une part, et le résoudre d'autre part.

    => Ce n'est pas une mince affaire.

    Je suis en entreprise et j'ai beaucoup de temps à y consacrer. Mes compétences en développement sont limitées mais justement ça tombe bien, je compte les développer !! Je dispose d'une toolbox traitement d'image censée m'aider dans cette tâche.

    Ci-dessous, la façon dont je compte approcher le problème. J'aimerais avoir vos avis sur la méthode...

    Par la suite, j'aimerais vous exposer les problèmes que je rencontre dans la partie opérationnelle (lorsque j'exécute le code).

    J'ai des images de tailles variables (16 000 pixels x 16 000 pixels environ, mais c'est la majeur partie du temps rectangulaire) codées sur 8 bits et monochromes (N&B).

    Je dois :

    - repérer une zone "particulière" et la sélectionner, tout le reste sera cropé
    - l'enregistrer dans une nouvelle image qui deviendra ma nouvelle image de travail

    Ensuite viendra l'analyse de l'image, mais c'est encore un autre problème...

    Pour repérer cette zone de façon automatique, j'ai pensé à seuiller mais ce n'est pas très pertinent dans mon cas car je retrouve des valeurs dans ma zone d’intérêt et ailleurs identiques.

    J'ai alors fait quelques recherches et je suis tombé sur l'algo split and merge. J'ai piqué l'algo (sur ce forum) et je l'ai adapté à ma situation et je réaliser quelques tests (je ne suis pas sur que ce me soit très utile pour mon problème mais au moins j'apprends des choses :

    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
    tic
     
    clear all;
    close all;
    clc
     
     dossier_img = ('XXXXX');
     nom_img = ('XXXX.jpg');
     
     chemin_img = [dossier_img,'\',nom_img];
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%%%%%%%%%% Lecture de l'image brut %%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
        I0 = imread(chemin_img);
     
    % Je redimensionne pour avoir quelque chose de carré, mais j'aimerais bien ne pas avoir à le faire et que ça marche pour une image rectangulaire ...
    I = imresize(I0, 'OutputSize',[600 600]);
     
    figure;
    imshow(I);
    title('Resized Image');
     
     
    [width, height, dim] = size(I);
    threshold1 = 2 %ça c'est mon critère pour qu'il resplit ou non
    taillem = 2 % ???
     
         %% Découpe
    Q=[1 1 width height];
    S=[];
     
    I1=double(I);
    Q=[1 1 width height];
    S=[];
     
    while(isempty(Q)==0)
        x1=Q(1,1); y1=Q(1,2);
        tRx=Q(1,3)-1; tRy=Q(1,4)-1;
        x2=x1+tRx ; y2=y1+tRy ; 
        R=I1(x1 : x2,y1 : y2, : ); 
     
        if ( max(max(R(:,:,1)))-min(min(R(:,:,1))) > threshold1 ||...
        max(max(R(:,:,2)))-min(min(R(:,:,2))) > threshold1 ||...
        max(max(R(:,:,3)))-min(min(R(:,:,3))) > threshold1 )
            szx=round(tRx/2);
            szy=round(tRy/2);
     
            if ((szx >= taillem) & (szy >= taillem))
                b1x=x1;
                b1y=y1;
     
                b2x=x1;
                b2y=y1+szy;
     
                b3x=x1+szx;
                b3y=y1;
     
                b4x=szx+x1;
                b4y=szy+y1;
     
                Q(1, : )=[];
                Q=[Q ;[b1x b1y szx szy; b2x b2y szx szy; b3x b3y szx szy; b4x b4y szx szy]];
     
            else
                S=[S; [y1 x1 tRx+1 tRy+1]];
                Q(1, : )=[];
            end
     
        else
            Q(1, : )=[];
            S=[S; [y1 x1 tRx+1 tRy+1]];
        end 
    end
     
    % Fonction d'affichage des blocs
    couleur = strvcat('r','y','g','c','b','m','k','w');
    [aS,bS]=size(S);
    for k=1:aS
          rectangle('Position',[S(k,1),S(k,2),S(k,3),S(k,4)]);
    end
     
    axis tight
     
    toc

    J'arrive à le faire tourner pour de petites images <1000 px x 1000 px mais dès que je mets ma grosse image, il plante et m'indique ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Index exceeds matrix dimensions.
     
    Error in Lecture_image_tests_grosses_images (line 62)
        max(max(R(:,:,2)))-min(min(R(:,:,2))) > threshold1 ||...
    Je récapitule :

    1) Suis-je sur la bonne voie pour isoler une zone (qui se ressemble) grâce à cette méthode ?
    2) Pourquoi le code fonctionne pour des petites images mais pas des grandes ?
    3) J'ai essayé d'utiliser la Toolbox mais je ne sais pas bien l'utiliser, du coup je ne vois pas ce qu'elle peut m'apporter. J'image qu'elle contient des "aides" au traitement d'images mais pas de la façon dont je l'imaginais .
    ==> En outre, comment repérer une zone qui se ressemble sur des images qui se ressemblent aussi mais ne sont pas identiques ? La toolbox n'a-t-elle pas des fonctions qui automatisent un peu cela ?

    Merci pour votre aide
    Romain

  2. #2
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Salut,
    Citation Envoyé par RomainDF42 Voir le message
    2) Pourquoi le code fonctionne pour des petites images mais pas des grandes ?
    Parce que tu dépasses la limite supérieure de ta variable. J'aurais pu être + précis, mais :

    Citation Envoyé par RomainDF42 Voir le message
    3) J'ai essayé d'utiliser la Toolbox mais je ne sais pas bien l'utiliser, du coup je ne vois pas ce qu'elle peut m'apporter. J'image qu'elle contient des "aides" au traitement d'images mais pas de la façon dont je l'imaginais .
    C'est quoi, ça, la Toolbox ? En quel langage tu codes ?
    Je vais passer pour un béotien (raf), mais jamais entendu parler de ça...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  3. #3
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 619
    Points : 188 594
    Points
    188 594
    Par défaut
    Citation Envoyé par Jipété Voir le message
    C'est quoi, ça, la Toolbox ? En quel langage tu codes ?
    Je vais passer pour un béotien (raf), mais jamais entendu parler de ça...
    Pour RomainDF42, MATLAB, c'est la vie, c'est le seul outil informatique dont on pourrait jamais avoir besoin, c'est donc un détail inutile à préciser .
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Bonjour,
    Oui c'est du Matlab et une toolbox c'est un module.

  5. #5
    Membre éclairé
    Avatar de Kangourou
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    579
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 579
    Points : 859
    Points
    859
    Par défaut
    Bonjour,

    juste une petite remarque, c'est que le traitement d'images est en général très dépendant de ce que l'on cherche à analyser / extraire des images. Donc donner des pistes de réflexions sans plus de détails sur le contenu ça va être un peu dur... Donner une image exemple aiderait beaucoup. Si ce n'est pas possible, peut etre trouver une image qui lui ressemble.

    Une première chose à faire pourrait être de se familiariser avec les différents outils, et en particulier regarder les pages d'aides fournies par Matlab (elles sont en général assez bien faites).

    Sinon quelques pistes de segmentation :
    * seuillage -> ok si on cherche à segmenter un zone homogène contrastée par rapport au fond. Souvent pas suffisant en tant que tel, et il on a intérêt à réduire le bruit dans l'image par des filtres (plat, gaussien, médian...)
    * détection de contours ->on se cherche plus à détecter les bords des objets. Ça peut être bien dans le cas d'objets industriels, avec des bords bien marqués.
    * ou alors essayer de détecter des structures particulières. Exemples : détecteur de coins (Harris), ou des lignes droites (-> transformée de Hough).
    Pour le split and merge, je n'ai jamais trop utilisé directement. Ca décompose l'image en fonction d'un critère d'homogénéité, mais comment comptes-tu utiliser le résultat ?

    pour la fonction resize : si tu donnes une taille fixe, tu risque de déformer l'image non ? Tu peux aussi spécifier un facteur de réduction je crois (ex : I2 = imresize(I, .20); ).

    A+

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Voici une illustration de ce que je dois inspecter (la partie capteur) sauf que l'image que je récupère est grande et je veux supprimer les bords (comme les fils par exemple et l'extérieur du boîtier) :
    Nom : sensor.jpg
Affichages : 444
Taille : 71,0 Ko

    Sur l'exemple ci-dessus, qui provient d'internet, on a une matrice de pixels uniforme. J'ai pris cet exemple car c'est le cas le plus simple auquel je suis confronté. Je débute sur des produits similaires. Mes images sont monochromes (ça aurait été trop simple sinon...).

    Je compte utiliser le résultat du split and merge pour créer un "masque" qui soit ma zone d'intérêt (cela doit bien fonctionner lorsqu'on a une zone assez homogène comme sur la photo ci-dessus).
    Concernant le redimensionnement, en effet je déforme l'image mais comme c'est pour tester, je m'en fiche pour l'instant. Cependant tu as raison, comme j'ai indiqué dans mon premier message, j'aimerais que ça marche pour des images rectangulaires plutôt qu'obligatoirement carrées...

    Merci pour les première interventions, je continue de chercher une méthode robuste et pas trop compliquée à mettre en oeuvre

    Romain

  7. #7
    Membre éclairé
    Avatar de Kangourou
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    579
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 579
    Points : 859
    Points
    859
    Par défaut
    Salut,

    attention avec la notion d'homogène, car sur l'image que tu as montrée, la zone centrale montre une variation lente en fonction de la position. Et dans certains cas, ca peut donner des segmentations au milieu de la zone d'intérêt...

    Vu le type d'image, tu peux essayer une détection des contours.
    Sinon une approche qui pourrait donner des résultats est d'utiliser une ligne de partage des eaux (watershed) avec marqueurs :
    1. D'abord on calcule une image de gradient (par exemple avec "imgradient")
    2. ensuite on définit des marqueurs. L'idée est d'avoir un marqueur tout autour de l'image, et un autre marqueur au centre de l'image (on suppose qu'il est dans la région d'intérêt)
    3. on impose les minima sur l'image de gradient (imimposemin)
    4. puis on calcule la ligne de partage des eaux (watershed).

    Ce qu'on devrait obtenir est une image étiquetée (label) avec une région qui correspond à la plaque, et une région pour le reste. Bon, il est fort possible quand même que la frontière entre les deux régions ne soit pas totalement celle que l'on souhaite, mais l'approche est assez générique.

    A++

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Je n'abandonne pas ton idée kangourou mais j'ai peut-être trouvé une méthode intéressante aussi :

    Je fais une détection de contours avec le filtre edge(img,'canny') et j'obtiens quelque chose d'intéressant !

    Nom : Capture.PNG
Affichages : 478
Taille : 48,2 Ko

    L'idée serait de définir la région centrale comme mon masque (avec des marqueurs comme tu l'indiquais ?) en remplissant les trous (je sais qu'il existe une fonction "fill_holes"), que je pourrais ensuite appliquer à mon image de référence par soustraction ? Peut-être qu'avec un seuillage je peux récupérer cette zone centrale ?

    => Comme je l'ai peut-être déjà indiqué, à terme il faudrait que la détection et le rognage soit automatique, c'est pourquoi je m'attache à trouver une méthode qui fonctionne peut importe l'orientation de mon image ou la taille de la zone centrale, etc.

    Merci de ton aide


    EDIT :
    Pour info, j'ai trouvé un code de blob_detection d'un gars qui s'appelle ImageAnalyst.

    J'ai testé sur une photo de mon image (c'est moins lourd pour faire des tests), c'est sympa ! Il faut encore que j'adapte le code à mon cas. Je n'ose pas le faire tourner pour l'instant avec ma vraie image sachant qu'avec 1MPixels ça met quand même 25s, donc avec 256MPixels il va exploser le nombre de blobs trouvés.

    Nom : Capture2.PNG
Affichages : 492
Taille : 227,1 Ko

    Il faudrait que je remonte les critères en amont pour pas qu'il calcule des blobs inutiles ... Sachant que je veux uniquement la zone la plus grande.
    Soit je définis une valeur sur la surface (area) soit je mets une fonctions max quelque part. C'est ma mission de demain.

    Si quelqu'un sait faire ça "easy", ce serait super d'avoir un coup de main pour nettoyer le code initial

    Voici mon code à l'instant t :

    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
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    tic
    
    clear all;close all;clc;
    
    %% Sélection de l'image XXXXX
    
    % dossier_img = ('XXX');
    % nom_img = ('XXX');
    
    %% Création chemin et lecture de l'image
    
    chemin_img = fullfile(dossier_img,nom_img);
    I = imread(chemin_img);
    I = rgb2gray(I);
    captionFontSize = 14;
    
    %% XXXXXXXXXXXX
    
    subplot(3, 3, 1);
    imshow(I);
    % Maximize the figure window.
    set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
    % Force it to display RIGHT NOW (otherwise it might not display until it's all done, unless you've stopped at a breakpoint.)
    drawnow;
    caption = sprintf('Original');
    title(caption, 'FontSize', captionFontSize);
    axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
    
    % Just for fun, let's get its histogram and display it.
    [pixelCount, grayLevels] = imhist(I);
    subplot(3, 3, 2);
    bar(pixelCount);
    title('Histogram of original image', 'FontSize', captionFontSize);
    xlim([0 grayLevels(end)]); % Scale x axis manually.
    grid on;
    thresholdValue = 95; (c'est fixé un peu arbitrairement pour l'instant)
    binaryImage = I > thresholdValue; % Bright objects will be chosen if you use >.
    % ========== IMPORTANT OPTION ============================================================
    % Use < if you want to find dark objects instead of bright objects.
    %   binaryImage = originalImage < thresholdValue; % Dark objects will be chosen if you use <.
    
    % Do a "hole fill" to get rid of any background pixels or "holes" inside the blobs.
    binaryImage = imfill(binaryImage, 'holes');
    
    % Show the threshold as a vertical red bar on the histogram.
    hold on;
    maxYValue = ylim;
    line([thresholdValue, thresholdValue], maxYValue, 'Color', 'r');
    % Place a text label on the bar chart showing the threshold.
    annotationText = sprintf('Thresholded at %d gray levels', thresholdValue);
    % For text(), the x and y need to be of the data class "double" so let's cast both to double.
    text(double(thresholdValue + 5), double(0.5 * maxYValue(2)), annotationText, 'FontSize', 10, 'Color', [0 .5 0]);
    text(double(thresholdValue - 70), double(0.94 * maxYValue(2)), 'Background', 'FontSize', 10, 'Color', [0 0 .5]);
    text(double(thresholdValue + 50), double(0.94 * maxYValue(2)), 'Foreground', 'FontSize', 10, 'Color', [0 0 .5]);
    
    % Display the binary image.
    subplot(3, 3, 3);
    imshow(binaryImage); 
    title('Binary Image, obtained by thresholding', 'FontSize', captionFontSize); 
    
    % Identify individual blobs by seeing which pixels are connected to each other.
    % Each group of connected pixels will be given a label, a number, to identify it and distinguish it from the other blobs.
    % Do connected components labeling with either bwlabel() or bwconncomp().
    labeledImage = bwlabel(binaryImage, 8);     % Label each blob so we can make measurements of it (j'aurais vraiment aimé mettre plus, genre fixer une valeur très haute pour avoir uniquement de grandes zones mais dans l'aide c'est écrit 4 ou 8...)
    % labeledImage is an integer-valued image where all pixels in the blobs have values of 1, or 2, or 3, or ... etc.
    subplot(3, 3, 4);
    imshow(labeledImage, []);  % Show the gray scale image.
    title('Labeled Image, from bwlabel()', 'FontSize', captionFontSize);
    
    % Let's assign each blob a different color to visually show the user the distinct blobs.
    coloredLabels = label2rgb (labeledImage, 'hsv', 'k', 'shuffle'); % pseudo random color labels
    % coloredLabels is an RGB image.  We could have applied a colormap instead (but only with R2014b and later)
    subplot(3, 3, 5);
    imshow(coloredLabels);
    axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
    caption = sprintf('Labels colorés\n Numérotation de haut en bas, de gauche à droite.');
    title(caption, 'FontSize', captionFontSize);
    
    % Get all the blob properties.  Can only pass in originalImage in version R2008a and later.
    blobMeasurements = regionprops(labeledImage, I, 'all');
    numberOfBlobs = size(blobMeasurements, 1);
    
    % bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
    % Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.
    subplot(3, 3, 6);
    imshow(I);
    title('Outlines, from bwboundaries()', 'FontSize', captionFontSize); 
    axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
    hold on;
    boundaries = bwboundaries(binaryImage);
    numberOfBoundaries = size(boundaries, 1);
    for k = 1 : numberOfBoundaries
    	thisBoundary = boundaries{k};
    	plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
    end
    hold off;
    
    textFontSize = 14;	% Used to control size of "blob number" labels put atop the image.
    labelShiftX = -7;	% Used to align the labels in the centers of the coins.
    blobECD = zeros(1, numberOfBlobs);
    % Print header line in the command window.
    fprintf(1,'Blob #      Mean Intensity  Area   Perimeter    Centroid       Diameter\n');
    % Loop over all blobs printing their measurements to the command window.
    for k = 1 : numberOfBlobs           % Loop through all blobs.
    	% Find the mean of each blob.  (R2008a has a better way where you can pass the original image
    	% directly into regionprops.  The way below works for all versions including earlier versions.)
    	thisBlobsPixels = blobMeasurements(k).PixelIdxList;  % Get list of pixels in current blob.
    	meanGL = mean(I(thisBlobsPixels)); % Find mean intensity (in original image!)
    	meanGL2008a = blobMeasurements(k).MeanIntensity; % Mean again, but only for version >= R2008a
    	
    	blobArea = blobMeasurements(k).Area;		% Get area.
    	blobPerimeter = blobMeasurements(k).Perimeter;		% Get perimeter.
    	blobCentroid = blobMeasurements(k).Centroid;		% Get centroid one at a time
    	blobECD(k) = sqrt(4 * blobArea / pi);					% Compute ECD - Equivalent Circular Diameter.
    	fprintf(1,'#%2d %17.1f %11.1f %8.1f %8.1f %8.1f % 8.1f\n', k, meanGL, blobArea, blobPerimeter, blobCentroid, blobECD(k));
    	% Put the "blob number" labels on the "boundaries" grayscale image.
    	text(blobCentroid(1) + labelShiftX, blobCentroid(2), num2str(k), 'FontSize', textFontSize, 'FontWeight', 'Bold');
    end
    
    % Now, I'll show you another way to get centroids.
    % We can get the centroids of ALL the blobs into 2 arrays,
    % one for the centroid x values and one for the centroid y values.
    allBlobCentroids = [blobMeasurements.Centroid];
    centroidsX = allBlobCentroids(1:2:end-1);
    centroidsY = allBlobCentroids(2:2:end);
    % Put the labels on the rgb labeled image also.
    subplot(3, 3, 5);
    for k = 1 : numberOfBlobs           % Loop through all blobs.
    	text(centroidsX(k) + labelShiftX, centroidsY(k), num2str(k), 'FontSize', textFontSize, 'FontWeight', 'Bold');
    end
    
    % Now I'll demonstrate how to select certain blobs based using the ismember() function.
    % Let's say that we wanted to find only those blobs
    % with an intensity between 150 and 220 and an area less than 2000 pixels.
    % This would give us the three brightest dimes (the smaller coin type).
    allBlobIntensities = [blobMeasurements.MeanIntensity];
    allBlobAreas = [blobMeasurements.Area];
    % Get a list of the blobs that meet our criteria and we need to keep.
    % These will be logical indices - lists of true or false depending on whether the feature meets the criteria or not.
    % for example [1, 0, 0, 1, 1, 0, 1, .....].  Elements 1, 4, 5, 7, ... are true, others are false.
    allowableIntensityIndexes = (allBlobIntensities > 20) & (allBlobIntensities < 220); (fixé là aussi un peu arbitrairement...)
    allowableAreaIndexes = allBlobAreas > 400000; % Take the small objects. (j'ai fixé 400 000 pixels pour mon image de 1MPixels, mais sur 256MPixels, il faudrait que je fasse un essai. Bon le ratio sera le même donc une règle de trois et c'est bon mais j'aurais aimé éviter de calculer tout ce qu'il y a avant pour rien....)
    % Now let's get actual indexes, rather than logical indexes, of the  features that meet the criteria.
    % for example [1, 4, 5, 7, .....] to continue using the example from above.
    keeperIndexes = find(allowableIntensityIndexes & allowableAreaIndexes);
    % Extract only those blobs that meet our criteria, and
    % eliminate those blobs that don't meet our criteria.
    % Note how we use ismember() to do this.  Result will be an image - the same as labeledImage but with only the blobs listed in keeperIndexes in it.
    keeperBlobsImage = ismember(labeledImage, keeperIndexes);
    % Re-label with only the keeper blobs kept.
    labeledDimeImage = bwlabel(keeperBlobsImage, 8);     % Label each blob so we can make measurements of it
    % Now we're done.  We have a labeled image of blobs that meet our specified criteria.
    subplot(3, 3, 7);
    imshow(labeledDimeImage, []);
    axis image;
    title('"Keeper" blobs (3 brightest dimes in a re-labeled image)', 'FontSize', captionFontSize);
    
    % Plot the centroids in the original image in the upper left.
    % Dimes will have a red cross, nickels will have a blue X.
    message = sprintf('Now I will plot the centroids over the original image in the upper left.\nPlease look at the upper left image.');
    reply = questdlg(message, 'Plot Centroids?', 'OK', 'Cancel', 'Cancel');
    % Note: reply will = '' for Upper right X, 'OK' for OK, and 'Cancel' for Cancel.
    if strcmpi(reply, 'Cancel')
    	return;
    end
    subplot(3, 3, 1);
    hold on; % Don't blow away image.
    for k = 1 : numberOfBlobs           % Loop through all keeper blobs.
    	% Identify if blob #k is a dime or nickel.
    	itsADime = allBlobAreas(k) < 2200; % Dimes are small.
    	if itsADime
    		% Plot dimes with a red +.
    		plot(centroidsX(k), centroidsY(k), 'r+', 'MarkerSize', 10, 'LineWidth', 2);
    	else
    		% Plot dimes with a blue x.
    		plot(centroidsX(k), centroidsY(k), 'bx', 'MarkerSize', 10, 'LineWidth', 2);
    	end
    end
    
    
    % Now use the keeper blobs as a mask on the original image.
    % This will let us display the original image in the regions of the keeper blobs.
    maskedImageDime = I; % Simply a copy at first.
    maskedImageDime(~keeperBlobsImage) = 0;  % Set all non-keeper pixels to zero.
    subplot(3, 3, 8);
    imshow(maskedImageDime);
    axis image;
    title('Only the 3 brightest dimes from the original image', 'FontSize', captionFontSize);
    
    % Now let's get the nickels (the larger coin type).
    keeperIndexes = find(allBlobAreas > 2000);  % Take the larger objects.
    % Note how we use ismember to select the blobs that meet our criteria.
    nickelBinaryImage = ismember(labeledImage, keeperIndexes);
    % Let's get the nickels from the original grayscale image, with the other non-nickel pixels blackened.
    % In other words, we will create a "masked" image.
    maskedImageNickel = I; % Simply a copy at first.
    maskedImageNickel(~nickelBinaryImage) = 0;  % Set all non-nickel pixels to zero.
    subplot(3, 3, 9);
    imshow(maskedImageNickel, []);
    axis image;
    title('Only the nickels from the original image', 'FontSize', captionFontSize);
    
    elapsedTime = toc;
    % Alert user that the demo is done and give them the option to save an image.
    message = sprintf('Done making measurements of the features.\n\nElapsed time = %.2f seconds.', elapsedTime);
    message = sprintf('%s\n\nCheck out the figure window for the images.\nCheck out the command window for the numerical results.', message);
    message = sprintf('%s\n\nDo you want to save the pseudo-colored image?', message);
    reply = questdlg(message, 'Save image?', 'Yes', 'No', 'No');
    % Note: reply will = '' for Upper right X, 'Yes' for Yes, and 'No' for No.
    if strcmpi(reply, 'Yes')
    	% Ask user for a filename.
    	FilterSpec = {'*.PNG', 'PNG Images (*.png)'; '*.tif', 'TIFF images (*.tif)'; '*.*', 'All Files (*.*)'};
    	DialogTitle = 'Save image file name';
    	% Get the default filename.  Make sure it's in the folder where this m-file lives.
    	% (If they run this file but the cd is another folder then pwd will show that folder, not this one.
    	thisFile = mfilename('fullpath');
    	[thisFolder, baseFileName, ext] = fileparts(thisFile);
    	DefaultName = sprintf('%s/%s.tif', thisFolder, baseFileName);
    	[fileName, specifiedFolder] = uiputfile(FilterSpec, DialogTitle, DefaultName);
    	if fileName ~= 0
    		% Parse what they actually specified.
    		[folder, baseFileName, ext] = fileparts(fileName);
    		% Create the full filename, making sure it has a tif filename.
    		fullImageFileName = fullfile(specifiedFolder, [baseFileName '.tif']);
    		% Save the labeled image as a tif image.
    		imwrite(uint8(coloredLabels), fullImageFileName);
    		% Just for fun, read image back into the imtool utility to demonstrate that tool.
    		tifimage = imread(fullImageFileName);
    		imtool(tifimage, []);
    	end
    end
    
    message = sprintf('Would you like to crop out each coin to individual images?');
    reply = questdlg(message, 'Extract Individual Images?', 'Yes', 'No', 'Yes');
    % Note: reply will = '' for Upper right X, 'Yes' for Yes, and 'No' for No.
    if strcmpi(reply, 'Yes')
    	figure;	% Create a new figure window.
    	% Maximize the figure window.
    	set(gcf, 'Units','Normalized','OuterPosition',[0 0 1 1]);
    	for k = 1 : numberOfBlobs           % Loop through all blobs.
    		% Find the bounding box of each blob.
    		thisBlobsBoundingBox = blobMeasurements(k).BoundingBox;  % Get list of pixels in current blob.
    		% Extract out this coin into it's own image.
    		subImage = imcrop(originalImage, thisBlobsBoundingBox);
    		% Determine if it's a dime (small) or a nickel (large coin).
    		if blobMeasurements(k).Area > 2200
    			coinType = 'nickel';
    		else
    			coinType = 'dime';
    		end
    		% Display the image with informative caption.
    		subplot(3, 4, k);
    		imshow(subImage);
    		caption = sprintf('Coin #%d is a %s.\nDiameter = %.1f pixels\nArea = %d pixels', ...
    			k, coinType, blobECD(k), blobMeasurements(k).Area);
    		title(caption, 'FontSize', textFontSize);
    	end
    
    	% Display the MATLAB "peaks" logo.
    	logoFig = subplot(3, 4, 11:12);
    	caption = sprintf('A MATLAB Tutorial by ImageAnalyst');
    	text(0.5,1.15, caption, 'Color','r', 'FontSize', 18, 'FontWeight','b', 'HorizontalAlignment', 'Center') ;
    	positionOfLowerRightPlot = get(logoFig, 'position');
    	L = 40*membrane(1,25);
    	logoax = axes('CameraPosition', [-193.4013 -265.1546  220.4819],...
    		'CameraTarget',[26 26 10], ...
    		'CameraUpVector',[0 0 1], ...
    		'CameraViewAngle',9.5, ...
    		'DataAspectRatio', [1 1 .9],...
    		'Position', positionOfLowerRightPlot, ...
    		'Visible','off', ...
    		'XLim',[1 51], ...
    		'YLim',[1 51], ...
    		'ZLim',[-13 40], ...
    		'parent',gcf);
    	s = surface(L, ...
    		'EdgeColor','none', ...
    		'FaceColor',[0.9 0.2 0.2], ...
    		'FaceLighting','phong', ...
    		'AmbientStrength',0.3, ...
    		'DiffuseStrength',0.6, ... 
    		'Clipping','off',...
    		'BackFaceLighting','lit', ...
    		'SpecularStrength',1, ...
    		'SpecularColorReflectance',1, ...
    		'SpecularExponent',7, ...
    		'Tag','TheMathWorksLogo', ...
    		'parent',logoax);
    	l1 = light('Position',[40 100 20], ...
    		'Style','local', ...
    		'Color',[0 0.8 0.8], ...
    		'parent',logoax);
    	l2 = light('Position',[.5 -1 .4], ...
    		'Color',[0.8 0.8 0], ...
    		'parent',logoax);
    end
    
    toc

    Romain

  9. #9
    Membre éclairé
    Avatar de Kangourou
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    579
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 579
    Points : 859
    Points
    859
    Par défaut
    hello,

    comme filtres que tu peux appliquer, tu peux aussi regarder du côté de la morphologie mathématique. En particulier, les fermetures morphologiques vont faire disparaitre tous les éléments noirs plus petits que la taille de l'élément structurant. Dans le cas de ta première image, ca simplifie bcp les calculs suivants. Et je pense que ca peut aussi être utile pour le résultat d'un seuillage auto.

    a++

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Génial !! La fonction bwareaopen (que j'ai trouvée dans google grâce à ton mot clé) m'a vraiment aidée ! En effet, elle supprime toutes les régions (ou labels) de la matrice en dessous du seuil fixé !

    C'est radical car ça ignore les données (et tant mieux dans mon cas) contrairement à un "filtre" qui n'afficherait par la suite que ce qui nous intéresse.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    binaryImage = bwareaopen(binaryImage, crit_taille_region);
    Exécution du code en 10 secondes avec une image 1MPixels :
    Nom : Captureeeeee.PNG
Affichages : 411
Taille : 3,5 Ko


    Je teste ASAP avec mon image de 256MPixels :p

    La fonction enregistrement fonctionne elle aussi donc :

    => Il me reste à vérifier que je ne perds pas d'informations sur les bords de mon masque et à l'intérieur car j'ai joué avec des critères issus du code de base et j'ai peur que certains pixels disparaissent (ce serait dommage, c'est ce qui m'intéresse au final : les défauts ...).

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Avec l'image 256MPixels, ça met environ 30 minutes.

    J'ai vu sur le net qu'il existe des fonctions "gpu"quelque chose. Je ne sais pas trop comment cela fonctionne mais vraisemblablement il faut une toolbox spécifique (parallel processing Toolbox) pour les utiliser. Est-ce que du coup ça utiliserait la carte graphique ?
    Comme je travaille sur des images, ça devrait aller plus vite, non ?

    Romain

Discussions similaires

  1. Comment faire du traitement d'images avec C?
    Par The-msx dans le forum C
    Réponses: 5
    Dernier message: 07/07/2008, 10h05
  2. Traitement d'image avec C++Builder
    Par Imed Soufi dans le forum C++Builder
    Réponses: 11
    Dernier message: 19/04/2008, 17h00
  3. Traitement d'image avec une Webcam ?
    Par kyoleroi dans le forum LabVIEW
    Réponses: 3
    Dernier message: 18/04/2008, 11h17
  4. je dois implémenter des programmes en traitement d'image avec java.
    Par inès83 dans le forum Traitement d'images
    Réponses: 1
    Dernier message: 22/02/2008, 12h55
  5. Traitement d'images avec c++
    Par Vinch006 dans le forum C++
    Réponses: 15
    Dernier message: 23/08/2006, 22h53

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