Saltar al contenido

Detección de rayones en la imagen con mucho ruido.

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

  1. 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);

Rasguño 1

ingrese la descripción de la imagen aquí

  1. Conviértelos en escala de grises.

gray = rgb2gray(im);

GrayImageingrese la descripción de la imagen aquí

  1. Aplicar un filtro gaussiano de tamaño 15 X 15.

gSize = 15;

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

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. Descubra la magnitud del degradado de las imágenes utilizando la máscara de Sobel.

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

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. Umbral Magnitud de gradiente con un umbral del percentil 30 del valor máximo.

`mgBw = mg> 0.3 * máx. (mg (:));

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. 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));

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. Aplicar análisis de partículas (CCL).

mgBw = bwareaopen(mgBw,500);

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. De nuevo Cerrar imagen para unir líneas.

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

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. Rellena los agujeros en la imagen.

mgBw = imfill(mgBw,'holes');

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

  1. Anotaciones finales:

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

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.
    imagen de diferencia de muestraimagen de diferencia de muestra 2

  • 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.
    segmentariosegmentado 2

  • 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.
    aunque soloshough líneas 2

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);

Valoraciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *