J'ai du mal à détecter les rayures sur ces images. En fait, il 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 le scratch uniquement.
À l'heure actuelle, j'ai essayé certains types de filtres (lissage, moyenne, médiane, filtre gaussien ou détecteur Sobel Edge) pour effacer le bruit et détecter les rayures, mais ils n'aident pas beaucoup. Pourriez-vous suggérer une idée? Quelques outils ou algorithmes que je devrais considérer?
Ceci 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 aucune 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
im1 = imresize(imread('scratch.jpg'),0.5);
gray = rgb2gray(im);
gSize = 15;
gray = imfilter(gray,fspecial('gaussian',[gSize,gSize],gSize/2),'replicate');
[~,~,mg,~] = ImageFeatures.Gradients(gray);
`mgBw = mg> 0,3 * max (mg (:));
mgBw = imclose(mgBw,strel('disk',1));
mgBw = bwareaopen(mgBw,500);
mgBw = imclose(mgBw,strel('disk',2));
mgBw = imfill(mgBw,'holes');
Essayez la procédure ci-dessus sur vos images, j'espère que cela fonctionnera
Merci
Les valeurs pour le masque gaussien sont données ci-dessous.
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 Sobel:
1, 2, 1;
0, 0, 0;
-1,-2, 1;
et
1, 0,-1;
2, 0,-2;
1, 0,-1;
Code d'amplitude du gradient Sobel (ImageFeatures.Gradient):
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
J'ai essayé la procédure suivante pour la détection. La sortie semble modérée, mais j'ai quand même pensé au partage.
appliquer un flou médian avec différentes tailles de fenêtre, puis prendre la différence absolue: je fais cela pour améliorer les marques de rayures et en même temps obtenir un aplatissement de l'éclairage. Vous trouverez ci-dessous les différences d'images obtenues de cette façon.
utilisez la segmentation d'arrière-plan/premier plan basée sur le mélange gaussien pour segmenter les marques de rayure dans l'image de différence. L'idée est que nous pouvons extraire m x n fenêtres de cette image et les former. Comme les rayures ne occupent pas une grande zone dans l'image de différence, nous pouvons penser que l'arrière-plan appris devrait se rapprocher de la zone en dehors des rayures. Cette méthode a mieux fonctionné pour les deux images de différence que d'appliquer un seuil à l'image de différence. Cette méthode n'a pas bien fonctionné lorsque j'ai alimenté directement l'image sous-échantillonnée. 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 d'éclairage aplatie. Voici les images segmentées. Cette procédure est lente car elle vérifie chaque fenêtre m x n possible dans l'image.
utilisez la transformée de Hough probabiliste pour détecter les lignes dans l'image segmentée. En utilisant la densité de lignes dans les régions ou en utilisant un filtrage morphologique pour les lignes, je pense qu'il est possible d'arriver à une estimation raisonnable de l'endroit où se trouvent les rayures.
Voici le code
code de segmentation en arrière-plan:
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;
}
principale:
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);
}
Je suis la procédure d'Ankit Dixit pour détecter les rayures et obtenir des problèmes. Tout d'abord, parce que j'utilise C++ au lieu de MATLAB, je voudrais donc vérifier s'il y a un 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 fenêtre 15x15 au lieu de 5x5? Deuxièmement, mon image après le masque Sobel ne semble pas aussi bonne que la vôtre. Y a-t-il des spéciaux/différents dans Sobel de Matlab?
Voici les 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