Détection de rayures sur l'image avec beaucoup de bruit

j'ai du mal à détecter scratch sur ces images. En fait, c'est très facile à voir par les yeux humains. Cependant, lors de l'application de certains algorithmes, il y a beaucoup de bruit et je n'ai pas pu extraire l'égratignure seulement.

Voici ces images: enter image description here

enter image description here

a l'heure actuelle, j'ai essayé certains types de filtre (lissage, moyenne, médiane, filtre gaussien ou détecteur de bord de Sobel) pour effacer le bruit et détecter de rien mais ils ne l'aide pas beaucoup. Pourriez-vous suggérer une idée? Certains outils ou algorithmes que je devrais considérer?

19
demandé sur SergV 2015-10-20 05:54:55

3 réponses

C'est mon implémentation pour la détection de défauts, c'est une approche très simple mais efficace, j'ai implémenté ce code dans MATLAB, mais il n'y a pas de difficulté à le porter sur n'importe quelle langue car il utilise des opérations de traitement d'image de base.

clc

clear all

close all

  1. lire à la fois les Images et les downsample them(pour un calcul rapide) par le facteur de 2.

im1 = imresize(imread('scratch.jpg'),0.5);

Scratch 1 enter image description here

  1. les transformer en échelle grise.

gray = rgb2gray(im);

GrayImage enter image description here

  1. appliquer un filtre gaussien de taille 15 X 15.

gSize = 15;

gray = imfilter(gray,fspecial('gaussian',[gSize,gSize],gSize/2),'replicate');

enter image description here enter image description here

  1. Trouver Ampleur du Gradient des Images à l'aide de masque de Sobel.

[~,~,mg,~] = ImageFeatures.Gradients(gray);

enter image description here enter image description here

  1. Gradient de seuil magnitude avec un seuil de 30 percentile de max valeur.

`mgBw = mg > 0,3 * max (mg (:));

enter image description here enter image description here

  1. appliquer l'opération morpholgical fermeture de l'image binaire par un masque de disque de 3 X 3.

mgBw = imclose(mgBw,strel('disk',1));

enter image description here enter image description here

  1. Appliquer Particules Analyser (CCL).

mgBw = bwareaopen(mgBw,500);

enter image description here enter image description here

  1. encore une fois fermez L'Image pour joindre les lignes ensemble.

mgBw = imclose(mgBw,strel('disk',2));

enter image description here enter image description here

  1. remplir les trous dans le image.

mgBw = imfill(mgBw,'holes');

enter image description here enter image description here

  1. Annotations Finales:

enter image description here enter image description here

Essayez la procédure ci-Dessus sur vos images espère que cela va fonctionner

Merci

les valeurs pour le masque gaussien sont données ci-dessous je viens de copier comme il est, vous pouvez seulement utilisez les valeurs 4 places après la décimale et encore une chose avant l'échelle de convolution vos valeurs d'image entre 0 et 1:

         0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;
         0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
         0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
         0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
         0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
         0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
         0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
         0.00392315394879368,0.00440372804277458,0.00485606890058492,0.00526051663974220,0.00559823553262373,0.00585265795345929,0.00601082839853353,0.00606449615428972,0.00601082839853353,0.00585265795345929,0.00559823553262373,0.00526051663974220,0.00485606890058492,0.00440372804277458,0.00392315394879368;
         0.00388843599983945,0.00436475725361032,0.00481309512122034,0.00521396370030743,0.00554869395001131,0.00580086485975791,0.00595763557555571,0.00601082839853353,0.00595763557555571,0.00580086485975791,0.00554869395001131,0.00521396370030743,0.00481309512122034,0.00436475725361032,0.00388843599983945;
         0.00378611472031542,0.00424990193722614,0.00468644212981339,0.00507676215263394,0.00540268422664802,0.00564821944786971,0.00580086485975791,0.00585265795345929,0.00580086485975791,0.00564821944786971,0.00540268422664802,0.00507676215263394,0.00468644212981339,0.00424990193722614,0.00378611472031542;
         0.00362152753952273,0.00406515334132644,0.00448271658130972,0.00485606890058492,0.00516782273108746,0.00540268422664802,0.00554869395001131,0.00559823553262373,0.00554869395001131,0.00540268422664802,0.00516782273108746,0.00485606890058492,0.00448271658130972,0.00406515334132644,0.00362152753952273;
         0.00340305543986557,0.00381991909245893,0.00421229243210782,0.00456312191696750,0.00485606890058492,0.00507676215263394,0.00521396370030743,0.00526051663974220,0.00521396370030743,0.00507676215263394,0.00485606890058492,0.00456312191696750,0.00421229243210782,0.00381991909245893,0.00340305543986557;
         0.00314141610419987,0.00352622975612324,0.00388843599983945,0.00421229243210782,0.00448271658130972,0.00468644212981339,0.00481309512122034,0.00485606890058492,0.00481309512122034,0.00468644212981339,0.00448271658130972,0.00421229243210782,0.00388843599983945,0.00352622975612324,0.00314141610419987;
         0.00284879446220838,0.00319776287779517,0.00352622975612324,0.00381991909245893,0.00406515334132644,0.00424990193722614,0.00436475725361032,0.00440372804277458,0.00436475725361032,0.00424990193722614,0.00406515334132644,0.00381991909245893,0.00352622975612324,0.00319776287779517,0.00284879446220838;
         0.00253790859361804,0.00284879446220838,0.00314141610419987,0.00340305543986557,0.00362152753952273,0.00378611472031542,0.00388843599983945,0.00392315394879368,0.00388843599983945,0.00378611472031542,0.00362152753952273,0.00340305543986557,0.00314141610419987,0.00284879446220838,0.00253790859361804;

Masque De Sobel:

 1, 2, 1;
 0, 0, 0;
-1,-2, 1;

et

 1, 0,-1;
 2, 0,-2;
 1, 0,-1;

Code De Magnitude Du Gradient De Sobel (ImageFeatures.Dégradé):

function [gx,gy,mag,phi] = Gradients(gray)
    gray = double(gray);
    horzmask = fspecial('sobel');
  %  vertmask = horzmask';

    gx = imfilter(gray,horzmask,'replicate');
    gy = imfilter(gray,horzmask','replicate');

    phi = (atan2((gy),(gx)));

    mag = mat2gray(sqrt(gx.^2+gy.^2));
end
7
répondu Ankit Dixit 2015-10-29 11:50:42

j'ai essayé la procédure suivante pour la détection. La production semble modérée, mais j'ai quand même pensé à partager.

  • sous-échantillonner l'image couleur.
  • appliquer le flou médian avec différentes tailles de fenêtre, puis prendre la différence absolue: je le fais pour améliorer les marques de rayure et en même temps obtenir l'éclairage aplatissement. Ci-dessous sont les différentes images obtenues façon. sample difference image sample difference image 2

  • utilisez une segmentation de fond/premier plan basée sur un mélange gaussien pour segmenter les marques de rayure dans l'image de différence. Idée ici est, nous pouvons extraire m x N fenêtres de cette image et de former. Comme les rayures n'occupent pas une grande surface dans l'image de différence, nous pouvons penser que le fond appris devrait se rapprocher de la région à l'extérieur des rayures. Cette méthode fonctionnait mieux pour les deux la différence des images que l'application d'un seuil à l'image de différence. Cette méthode n'a pas bien fonctionné quand j'ai alimenté l'image downsampled directement. Je pense que cela est dû à la nature non uniforme des valeurs de couleur des pixels dans les régions. J'ai donc utilisé l'image de différence aplatie de l'éclairage. Voici les images segmentées. Cette procédure est lente car elle vérifie toutes les fenêtres m x n image. segmented segmented 2

  • utiliser la Transformée de Hough probabiliste pour détecter les lignes dans l'image segmentée. En utilisant la densité des lignes dans les régions ou en utilisant le filtrage morphologique pour les lignes, je pense qu'il est possible d'arriver à une estimation raisonnable quant à l'endroit où les marques de rayure sont. hough lones hough lines 2

Voici le code

arrière-plan de la segmentation code:

Mat threshold_mog(Mat& im, Size window)
{
    BackgroundSubtractorMOG2 bgModel;
    Mat fgMask;
    Mat output = Mat::ones(im.rows, im.cols, CV_8U);

    for (int r = 0; r < im.rows - window.height; r++)
    {
        for (int c = 0; c < im.cols - window.width; c++)
        {
            bgModel.operator()(im(Rect(c, r, window.width, window.height)), fgMask);
        }
    }

    for (int r = 0; r < im.rows - window.height; r++)
    {
        for (int c = 0; c < im.cols - window.width; c++)
        {
            Mat region = im(Rect(c, r, window.width, window.height));
        bgModel.operator()(region, fgMask, 0);
            fgMask.copyTo(output(Rect(c, r, window.width, window.height)));
        }
    }

    return output;
}

main:

Mat rgb = imread("scratch_2.png.jpg");

pyrDown(rgb, rgb);

Mat med, med2, dif, bw;

medianBlur(rgb, med, 3);
medianBlur(rgb, med2, 21);

absdiff(med2, med, dif);

bw = threshold_mog(dif, Size(15, 15));

Mat dst = bw.clone();
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, CV_PI/180, 8, 10, 20);
for( size_t i = 0; i < lines.size(); i++ )
{
    Vec4i l = lines[i];
    line(rgb, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 1, CV_AA);
}
2
répondu dhanushka 2015-10-21 03:31:10

je suis la procédure D'Ankit Dixit pour détecter les égratignures et avoir des problèmes. Tout d'abord, parce que j'utilise C++ au lieu de MATLAB, donc je voudrais vérifier s'il y a malentendu sur l'algorithme.

pour l'instant, je n'utilise que le filtre gaussien 5x5 car il est disponible. Quelle est la raison pour laquelle vous avez choisi la taille de la fenêtre 15x15 au lieu de 5x5? Deuxièmement, mon image après le masque de Sobel ne semble pas aussi bonne que la vôtre. Est-ce qu'il y a une différence avec Sobel? Matlab?

Voici des images: Gris: http://s15.postimg.org/q8s5y2sjf/Gray_Image.png Filtre gaussien 5x5: http://s1.postimg.org/80r9x20tr/Gaussian_Filter_5x5.png Faire Sobel: http://s21.postimg.org/vxwyju58n/Sobel_Image.png

0
répondu anhnha 2015-10-23 03:24:28