Por fin después de mucho batallar ya encontramos el resultado de esta inconveniente que muchos lectores de nuestro sitio han presentado. Si tienes algo que aportar no dudes en dejar tu información.
Solución:
Esta es mi implementación para la detección de defectos, es un enfoque muy simple pero efectivo, he implementado este código en MATLAB, pero no hay ninguna dificultad para portarlo a cualquier lenguaje porque usa operaciones básicas de procesamiento de imágenes.
clc
clear all
close all
- Lea ambas imágenes y reduzca la resolución (para un cálculo rápido) por un factor de 2.
im1 = imresize(imread('scratch.jpg'),0.5);
- Conviértelos en escala de grises.
gray = rgb2gray(im);
- Aplicar un filtro gaussiano de tamaño 15 X 15.
gSize = 15;
gray = imfilter(gray,fspecial('gaussian',[gSize,gSize],gSize/2),'replicate');
- Descubra la magnitud del degradado de las imágenes utilizando la máscara de Sobel.
[~,~,mg,~] = ImageFeatures.Gradients(gray);
- Umbral Magnitud de gradiente con un umbral del percentil 30 del valor máximo.
`mgBw = mg> 0.3 * máx. (mg (:));
- Aplicar operación morfológica Cierre de imagen binaria mediante una máscara de disco de 3 X 3.
mgBw = imclose(mgBw,strel('disk',1));
- Aplicar análisis de partículas (CCL).
mgBw = bwareaopen(mgBw,500);
- De nuevo Cerrar imagen para unir líneas.
mgBw = imclose(mgBw,strel('disk',2));
- Rellena los agujeros en la imagen.
mgBw = imfill(mgBw,'holes');
- Anotaciones finales:
Pruebe el procedimiento anterior en sus imágenes, espero que funcione
Gracias
Los valores para la máscara gaussiana se dan a continuación. Acabo de copiarlo tal como está, solo puede usar valores 4 lugares después del decimal y una cosa más antes de la escala de convolución de los valores de su imagen entre 0 y 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;
Máscara de Sobel:
1, 2, 1;
0, 0, 0;
-1,-2, 1;
y
1, 0,-1;
2, 0,-2;
1, 0,-1;
Código de magnitud de degradado de 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
Intenté el siguiente procedimiento de detección. La salida parece moderada, pero aún así pensé en compartir.
- reducir la resolución de la imagen en color.
-
aplique el desenfoque medio con diferentes tamaños de ventana, luego tome la diferencia absoluta: estoy haciendo esto para mejorar las marcas de rayado y al mismo tiempo lograr el aplanamiento de la iluminación. A continuación se muestran las imágenes de diferencia obtenidas de esta manera.
-
utilice la segmentación de fondo / primer plano basada en la mezcla gaussiana para segmentar las marcas de arañazos en la imagen de diferencia. La idea aquí es que podemos extraer ventanas mxn de esta imagen y entrenar. Como las marcas de rayado no ocupan un área grande en la imagen de diferencia, podemos pensar que el fondo aprendido debería aproximarse a la región fuera de las marcas de rayado. Este método funcionó mejor para ambas imágenes de diferencia que aplicar un umbral a la imagen de diferencia. Este método no funcionó bien cuando alimenté directamente la imagen muestreada. Creo que esto se debe a la naturaleza no uniforme de los valores de color de los píxeles en las regiones. Así que utilicé la imagen de diferencia de iluminación aplanada. A continuación se muestran las imágenes segmentadas. Este procedimiento es lento ya que verifica todas las posibles ventanas mxn en la imagen.
-
utilice la transformada probabilística de Hough para detectar líneas en la imagen segmentada. Usando la densidad de línea en las regiones o usando el filtrado morfológico para las líneas, creo que es posible llegar a una suposición razonable de dónde están las marcas de rayado.
Aqui esta el codigo
código de segmentación en segundo plano:
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;
principal:
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 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);