Estoy tratando de implementar varios algoritmos de binarización en la imagen que se muestra:
Aquí está el código:
clc;
clear;
x=imread('n2.jpg'); %load original image
% Ahora redimensionamos las imágenes para que el trabajo computacional sea más fácil para nosotros más adelante.
size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');
z=rgb2hsv(x); %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);
% ahora encontramos la media y la desviación estándar requerida para los algoritmos niblack y% sauvola
m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;
% de implementación del algoritmo de umbral niblack:
for p=1:1:500
for q=1:1:800
pixel=temp(p,q);
if(pixel>value)
temp(p,q)=1;
else
temp(p,q)=0;
end
end
end
figure;
imshow(temp);
title('result by niblack');
k=kittlerMet(g);
figure;
imshow(k);
title('result by kittlerMet');
% de implementación del algoritmo de umbral de Sauvola:
val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
pixel=t2(p,q);
if(pixel>value)
t2(p,q)=1;
else
t2(p,q)=0;
end
end
fin
figure;
imshow(t2);
title('result by sauvola');
Los resultados que obtuve son los que se muestran:
Como puede ver, las imágenes resultantes se degradan en los puntos más oscuros. ¿Podría alguien sugerirme cómo optimizar mi resultado?
image-processing
matlab
marca
fuente
fuente
Respuestas:
Su imagen no tiene brillo uniforme, por lo que no debe trabajar con un umbral uniforme. Necesitas un umbral adaptativo. Esto se puede implementar preprocesando la imagen para hacer que el brillo sea más uniforme en toda la imagen (código escrito en Mathematica, deberá implementar la versión de Matlab por usted mismo):
Una manera simple de hacer que el brillo sea uniforme es eliminar el texto real de la imagen usando un filtro de cierre:
El tamaño del filtro debe elegirse más grande que el ancho del trazo de la fuente y más pequeño que el tamaño de las manchas que está tratando de eliminar.
EDITAR: En los comentarios me pidieron que explicara qué hace una operación de cierre. Es una dilatación morfológica seguida de una erosión morfológica . La dilatación esencialmente mueve el elemento estructurante en cada posición de la imagen y selecciona el píxel más brillante debajo de la máscara, por lo tanto:
La operación de erosión hace lo opuesto (selecciona el píxel más oscuro debajo del elemento estructurante), por lo que si lo aplica en la imagen dilatada:
Por lo tanto, la operación de cierre elimina pequeños objetos oscuros con solo cambios menores en objetos oscuros más grandes y objetos brillantes.
Aquí hay un ejemplo con diferentes tamaños de elementos estructurantes:
A medida que aumenta el tamaño del elemento estructurante, se eliminan más y más caracteres. En radio = 5, se eliminan todos los caracteres. Si el radio aumenta aún más, también se eliminan las manchas más pequeñas:
Ahora solo divide la imagen original por esta "imagen blanca" para obtener una imagen de brillo (casi) uniforme:
Esta imagen ahora se puede binarizar con un umbral constante:
fuente
Clip[ImageData[white],{eps,Infinity}]
donde eps es un número pequeño, para estar seguro.La respuesta de Nikie parece la mejor y también parece estar funcionando y produciendo resultados. Entonces es un claro ganador.
Sin embargo, solo a la documentación agrego una referencia más, eso podría ser muy rápido.
Esta técnica se llama umbral adaptable que no requiere aprender el fondo explícitamente.
Esencialmente, en lugar de encontrar el umbral global más adecuado , podemos particionar la imagen en una ventana local (digamos aproximadamente 7x7 o apropiado) y encontrar umbrales que cambian a medida que la ventana se desplaza.
La referencia a continuación detalla el método exacto. http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm
Este método sería relativamente más rápido computacionalmente.
fuente
Otra forma de usar un filtro de paso de banda (en MATLAB). Jugar con la diferencia de los parámetros gaussianos puede dar mejores resultados. El proceso consiste básicamente en filtrar la imagen para eliminar los blobs de fondo de baja frecuencia, normalizar a [0,1] requerido para el comando 'graythresh', imagen umbral.
Cargar imagen y convertir a escala de grises doble:
Filtrar utilizando la diferencia del núcleo gaussiano y normalizar:
Calcular el umbral y hacer 010101:
fuente
Este es un buen código de Matlab para umbrales adaptativos: http://www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding
fuente
Intentaré esta codificación, pero no tengo una respuesta correcta ...
fuente