Electrónica, Electricidad y Sonido
Sistema de reconocimiento automático matrículas
INFORME FINAL
SISTEMA DE RECONOCIMIENTO AUTOMATICO DE
PLACAS PARA UN PARQUEADERO
INFORME FINAL
OBJETIVO:
Utilizar técnicas de procesamiento de imágenes para solucionar un problema específico, el cual será la creación de un sistema reconocedor automático de placas que podrá ser instalado a la entrada de un parqueadero.
DESARROLLO DEL PROYECTO
Restricciones: Las imágenes tomadas pueden ser de cualquier tamaño, pero la placa debe cumplir con las siguientes condiciones de 150 a 210 pixels y de 50 a 110 pixels de ancho. Ademas, las fotos tomadas de la placa no pueden estar inclinadas.
Procedimiento: Inicialmente se necesita diferenciar si la imagen está en escala de grises o en RGB para poder hacer la conversión correspondiente. Se utiliza el siguiente código:
I=imread('C:\foto104.jpg');
info=imfinfo('C:\foto104.jpg');
if info.ColorType=='truecolor' %Ciclo para determinar si es a color o en
I=rgb2gray(I); %escala de grises para poder hacer o no la
else %conversion necesaria
I=I;
End
Una vez realizado esto se recorta la imagen para poder eliminar zonas en las que no existe información relevante a la placa como los bordes superiores y externos, se muestra en la figura 1. Se observaron las fotos para determinar cual es el rango aproximado que se puede cortar.
Figura 1. Imagen Recortada
Después del recorte se determina el umbral óptimo de la imagen. Esto se hace calculando el gradiente de la imagen utilizando la técnica de Sobel para hallar posibles picos en la imagen, y luego las siguientes ecuaciones:
Se implementó el siguiente código para definir una función para calcular el umbral óptimo de cada foto en particular:
% umbral=UmbralOptimo(imagen, filasImagen, columnasImagen, gradiente);
% Algoritmo para calcular el umbral optimo para la binarizacion.
function umbral=UmbralOptimo(imagen, filasImagen, columnasImagen, gradiente)
% Creo una variable que me dice de que color era el ultimo grupo que guarde
% de esta forma se que la cola del final de la fila pertenece al otro color
% la variable se llama ultimoColor, si vale cero fue oscuro y si vale uno
% fue claro.
numOscuros=0;
numClaros=0;
oscuros=0;
claros=0;
cont=0;
acum=0;
% Este if es para solucionar el problema que ocurre si no hay bordes en la
% primer fila entonces no se sabe si es clara o oscura.
% Supongo continuidad en los colores, si en la segunda fila tampoco hay bordes
% estos los supongo del mismo color que la primera.
if imagen(1,1)<(max(max(imagen))/2)
% Como es oscuro pongo que el ultimo color fue claro.
ultimoColor=1;
else
% Como es claro pongo que el ultimo color fue oscuro.
ultimoColor=0;
end
for i=1:filasImagen
if ultimoColor==0
numClaros=numClaros+cont;
cont=0;
claros=claros+acum;
acum=0;
else
numOscuros=numOscuros+cont;
cont=0;
oscuros=oscuros+acum;
acum=0;
end
for j=1:columnasImagen
if gradiente(i,j)==0
cont=cont+1;
acum=acum+imagen(i,j);
else
if gradiente(i,j)==-1
numOscuros=numOscuros+cont;
cont=1;
oscuros=oscuros+acum;
acum=imagen(i,j);
ultimoColor=0;
else
numClaros=numClaros+cont;
cont=1;
claros=claros+acum;
acum=imagen(i,j);
ultimoColor=1;
end
end
end
end
if ultimoColor==0
numClaros=numClaros+cont;
claros=claros+acum;
else
numOscuros=numOscuros+cont;
oscuros=oscuros+acum;
end
% Media de los claros.
mediaClaros=claros/numClaros;
% Media de los oscuros.
mediaOscuros=oscuros/numOscuros;
% Umbral optimo para la binarizacion.
umbral=(mediaOscuros*numClaros+mediaClaros*numOscuros)/(numClaros+numOscuros);
Se definió la siguiente función para calcular el gradiente de Sobel:
% gradienteSobel=Sobel(imagen, filasImagen, columnasImagen, X_Porciento);
function gradienteSobel=Sobel(imagen, filasImagen, columnasImagen, X_Porciento)
% Kernel Sobel para calcular el gradiente en la direccion horizontal.
kernel=(1/8)*[-1 0 1; -2 0 2; -1 0 1];
gradiente=Filtro(imagen, filasImagen, columnasImagen, kernel);
% Calculo del umbral para clasificar la respuesta del Sobel, este es tal que
% solo un X% de los gradientes van a superar el umbral.
moduloGradiente=abs(gradiente(:));
maximoModuloGradiente=round(max(moduloGradiente));
minimoModuloGradiente=round(min(moduloGradiente));
nivelesGradiente=maximoModuloGradiente-minimoModuloGradiente;
histogramaGradiente=hist(moduloGradiente, nivelesGradiente);
histogramaGradienteAcumulado=cumsum(histogramaGradiente);
umbralSobel=nivelesGradiente;
while (umbralSobel > 0)&(histogramaGradienteAcumulado(umbralSobel) > (filasImagen*columnasImagen*(1-(X_Porciento/100))))
umbralSobel=umbralSobel-1;
end
umbralSobel=minimoModuloGradiente+umbralSobel;
% Clasificacion de la respuesta del Sobel en 1, 0 o -1.
gradienteSobel=[];
for i=1:filasImagen
for j=1:columnasImagen
if gradiente(i,j) > umbralSobel
gradienteSobel(i,j)=1;
else
if gradiente(i,j) < -umbralSobel
gradienteSobel(i,j)=-1;
else
gradienteSobel(i,j)=0;
end
end
end
end
Finalmente se implementó el siguiente código para el recorte y la determinación del umbral:
[R C]=size(I); %Halla el tamaño de la imagen
cropsize=[(R*0.25) (C*0.15) (C*0.625) (R*0.6)]; %Determina seccion a cortar
Ic=imcrop(I,cropsize); %Recorta la imagen para eliminar fondo innecesario
figure; imshow(Ic) %Grafica Zona recortada
Id=double(Ic); [R C]=size(Ic) %Convierte imagen a doble para operaciones
I2=sobel(Id,R,C,2.5); %Halla gradiente de sobel
umbral=umbraloptimo(Id,R,C,I2); %Halla umbral optimo
Posteriormente se realizan operaciones morfológicas. Inicialmente se utilizará un elemento estructurante circular de radio 10 píxeles para realizar una transformación “bottom-hat”, que primero hace una operación de “closing” (dilatación y luego erosión) y luego resta la imagen obtenida de la imagen original para resaltar la placa y ciertos bordes como se puede ver en la figura 2. Luego se aplica el umbral hallado anteriormente como se muestra en la figura 3. Para eliminar el ruido se hace primero una operación de “closing” (dilatación y luego erosión) utilizando un elemento estructurante horizontal hallado basándose en la separación que existe entre los caracteres de la placa como se muestra en la figura 4. Después se realiza “opening” (erosión y luego dilatación) con un elemento estructurante vertical hallado basándose en la altura de los caracteres de la placa como se ve en la figura 5. Finalmente se realizan dilataciones verticales y horizontales para expandir la zona de la placa como se ve en la figura 6. Se implementó el siguiente código:
st=strel('disk',10); %Elemento estructurante de 10 pixeles de radio
IM2=imbothat(Ic,st); %Hace Bottom-Hat
I3=IM2>umbral; %Aplica Umbral
LH=strel('line',60,0); %Elemento estructurante lineal horizontal
IM3=imclose(I3,LH); %Closing con elemento estructurante
LV=strel('line',20,90); %Elemento estructurante lineal vertical
IM4=imopen(IM3,LV); %Hace opening con elemento estructurante
figure;imshow(IM4) %Muestra Imagen
DIV=strel('line',35,90); %Elemento estructurante lineal vertical
DIH=strel('line',20,0); %Elemento estrucutrante lineal horizontal
IM5=imdilate(IM4,DIV); %Dilata con E.E. vertical
IM6=imdilate(IM5,DIH); %Dilata con E.E. horizontal
figure; imshow(IM6) %Muestra imagen
Figura 2. Top-Hat | Figura 3. Umbral |
Figura 4. Closing Horizontal | Figura 5. Opening Vertical |
Figura 6. Dilatación |
Finalmente a partir de la imagen binarizada de la zona de la placa, se pueden hallar la ubicación de la placa y sus dimensiones para hacer un recorte de la imagen original de la zona de la placa como se muestra en la figura 7. Se implementó el siguiente código:
L=bwlabel(IM6); %Crea regiones
stats=regionprops(L,'all'); %Estadisticas de las regiones
Idx=find([stats.Area]>(7000)); %Diferencia las regiones con Area > 7000
IM6=ismember(L,Idx); %Crea una imagen con dichas regiones
L=bwlabel(IM6); %Crea regiones
stats = regionprops(L,'all'); %Estadisticas de las regiones
E=stats(1).BoundingBox; %Toma tamaño de la region
X=E.*[[1] [0] [0] [0]]; X=max(X); %Determina eje X esquina superior Izq. Placa
Y=E.*[[0] [1] [0] [0]]; Y=max(Y); %Determina eje Y esquina superior Der. Placa
W=E.*[[0] [0] [1] [0]]; W=max(W) %Determina Ancho Placa
H=E.*[[0] [0] [0] [1]]; H=max(H); %Determina Altura placa
Corte=[X Y W H]; %Determina coordenadas de corte
IMF=imcrop(Ic,Corte); %Realiza el corte
figure; imshow(IMF) %Muestra imagen de la zona de la placa
Figura 7. Recorte Placa
A continuación procedemos a binarizar la imagen de la placa recortada con un umbral de 120, para poder recortar aun mas la placa y así borrar las líneas y elementos que nos producen ruido (Figura 8). Esto lo podemos realizar mediante una estadística de la región tomada, y aplicando un porcentaje de recorte posible por las características estándar que tienen las placas. Se realiza un filtro para ayudar a depurar un poco mas la imagen (Figura 9). Se binariza la imagen obtenida (Figura 10). Y por ultimo se aplica una propiedad de región para que solo las áreas mayores a 1.5% del total queden presentes. El siguiente es el código implementado:
umbral=120; %Aplico un Umbral de 120
placa=IMF>umbral; %Aplica umbral a placa
L=bwlabel(placa); %Crea regiones
stats=regionprops(L,'all'); %Estadisticas de las regiones
placadx=find([stats.Area]>(4500)); %Diferencia las regiones con Area > 4500
placa=ismember(L,placadx); %Crea una imagen con dichas regiones
L=bwlabel(placa); %Crea regiones
stats=regionprops(L,'all'); %Estadisticas de las regiones
E2=stats(1).BoundingBox; %Toma tamaño de la region
X2=E2.*[[1] [0] [0] [0]]; X2=max(X2); %Determina eje X esquina superior Izq. Placa
Y2=E2.*[[0] [1] [0] [0]]; Y2=max(Y2); %Determina eje Y esquina superior Der. Placa
W2=E2.*[[0] [0] [1] [0]]; W2=max(W2); %Determina Anchura placa
H2=E2.*[[0] [0] [0] [1]]; H2=max(H2); %Determina Altura placa
Corte2=[X2 Y2 W2 H2]; %Determina coordenadas de corte
C2=imcrop(IMF,Corte2); %Realiza el corte
Wx=round(W2*0.94); Hx=round(H2*0.756);
Cortex=[4 12 Wx Hx];
C2=imcrop(C2,Cortex);
figure; imshow(C2) %Muestra Imagen
C3=imbothat(C2,st);
figure; imshow(C3)
umbral2=90;
C5=C3>umbral2;
figure; imshow(C5)
L=bwlabel(C5);
stats=regionprops(L,'all');
placadx=find([stats.Area]>((W2*H2)*0.015)); %Diferencia las regiones con Area > 1.5% del area total
placa=ismember(L,placadx); %Crea una imagen con dichas regiones
figure; imshow(placa)
FIGURA 8 | FIGURA 9 |
FIGURA 10 |
El siguiente paso es recortar cada carácter por separado, para esto utilizamos el comando bwlabel para que nos divida la imagen en regiones y poder determinar el área que posee cada región (que en este caso nos demarcará el área ocupada por el carácter) y poder recortarlo con el comando imcrop, obteniendo cada carácter en una variable por separado. Luego, a cada carácter se le realiza un nuevo dimensionamiento (24*42) para estandarizar los caracteres y poder realizar el reconocimiento de la letra y del numero. La figura 11 muestra los 6 caracteres recortados. El código utilizado es el siguiente:
L=bwlabel(placa);
stats=regionprops(L,'all');
E3=stats(1).BoundingBox; %Toma tamaño de la region 1, primer caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L1=imcrop(C2,Corte3); %Realiza el corte
L1b=imresize(L1,[42 24]);
L1b=L1b>150;
figure; imshow(L1b) %Muestra el primer caracter
E3=stats(2).BoundingBox; %Toma tamaño de la region 2, segundo caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L2=imcrop(C2,Corte3); %Realiza el corte
L2b=imresize(L2,[42 24]);
L2b=L2b>150;
figure; imshow(L2b) %Muestra el segundo caracter
E3=stats(3).BoundingBox; %Toma tamaño de la region 3, tercer caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L3=imcrop(C2,Corte3); %Realiza el corte
L3b=imresize(L3,[42 24]);
L3b=L3b>150;
figure; imshow(L3b) %Muestra el tercer caracter
E3=stats(4).BoundingBox; %Toma tamaño de la region 4, cuarto caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L4=imcrop(C2,Corte3); %Realiza el corte
L4b=imresize(L4,[42 24]);
L4b=L4b>150;
figure; imshow(L4b) %Muestra el cuarto caracter
E3=stats(5).BoundingBox; %Toma tamaño de la region 5, quinto caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L5=imcrop(C2,Corte3); %Realiza el corte
L5b=imresize(L5,[42 24]);
L5b=L5b>150;
figure; imshow(L5b) %Muestra el quinto caracter
E3=stats(6).BoundingBox; %Toma tamaño de la region 6, sexto caracter
X3=E3.*[[1] [0] [0] [0]]; X3=max(X3); %Determina eje X esquina superior Izq. Placa
Y3=E3.*[[0] [1] [0] [0]]; Y3=max(Y3); %Determina eje Y esquina superior Der. Placa
W3=E3.*[[0] [0] [1] [0]]; W3=max(W3); %Determina Anchura placa
H3=E3.*[[0] [0] [0] [1]]; H3=max(H3); %Determina Altura placa
Corte3=[X3 Y3 W3 H3]; %Determina coordenadas de corte
L6=imcrop(C2,Corte3); %Realiza el corte
L6b=imresize(L6,[42 24]);
L6b=L6b>150;
figure; imshow(L6b) %Muestra el sexto carácter
Figura 11. Caracteres de la placa |
Desarrollo del OCR: En este momento ya poseemos los caracteres individuales que componen el numero de la placa, por lo que se procederá a realizar una base de datos de las 24 letras del alfabeto en mayúscula (no se tiene en cuanta la letra CH ni la Ñ), y los dígitos del 0 al 9. Para ello se realizaran archivos de imagen con los caracteres de 21*42 pixels, binarizados, que serán cargados a matlab mediante variables, y luego se creara una matriz denominada alfabeto que contenga todas la letras del alfabeto, Figura 12, y una matriz denominada numeral que contiene todos los digitos del 0 al 9, Figura 13. El siguiente es el código implementado.
a=imread('C:\MATLAB6p5\work\A.bmp'); b=imread('C:\MATLAB6p5\work\B.bmp');
c=imread('C:\MATLAB6p5\work\C.bmp'); d=imread('C:\MATLAB6p5\work\D.bmp');
e=imread('C:\MATLAB6p5\work\E.bmp'); f=imread('C:\MATLAB6p5\work\F.bmp');
g=imread('C:\MATLAB6p5\work\G.bmp'); h=imread('C:\MATLAB6p5\work\H.bmp');
i=imread('C:\MATLAB6p5\work\I.bmp'); j=imread('C:\MATLAB6p5\work\J.bmp');
k=imread('C:\MATLAB6p5\work\K.bmp'); l=imread('C:\MATLAB6p5\work\L.bmp');
m=imread('C:\MATLAB6p5\work\M.bmp'); n=imread('C:\MATLAB6p5\work\N.bmp');
o=imread('C:\MATLAB6p5\work\O.bmp'); p=imread('C:\MATLAB6p5\work\P.bmp');
q=imread('C:\MATLAB6p5\work\Q.bmp'); r=imread('C:\MATLAB6p5\work\R.bmp');
s=imread('C:\MATLAB6p5\work\S.bmp'); t=imread('C:\MATLAB6p5\work\T.bmp');
u=imread('C:\MATLAB6p5\work\U.bmp'); v=imread('C:\MATLAB6p5\work\V.bmp');
w=imread('C:\MATLAB6p5\work\W.bmp'); x=imread('C:\MATLAB6p5\work\X.bmp');
y=imread('C:\MATLAB6p5\work\Y.bmp'); z=imread('C:\MATLAB6p5\work\Z.bmp');
uno=imread('C:\MATLAB6p5\work\1.bmp'); dos=imread('C:\MATLAB6p5\work\2.bmp');
tres=imread('C:\MATLAB6p5\work\3.bmp'); cuatro=imread('C:\MATLAB6p5\work\4.bmp');
cinco=imread('C:\MATLAB6p5\work\5.bmp'); seis=imread('C:\MATLAB6p5\work\6.bmp');
siete=imread('C:\MATLAB6p5\work\7.bmp'); ocho=imread('C:\MATLAB6p5\work\8.bmp');
nueve=imread('C:\MATLAB6p5\work\9.bmp'); cero=imread('C:\MATLAB6p5\work\0.bmp');
alfabeto=[[a] [b] [c] [d] [e] [f] [g] [h] [i] [j] [k] [l] [m] [n] [o] [p] [q] [r] [s] [t] [u] [v] [w] [x] [y] [z]];
numeral=[[uno] [dos] [tres] [cuatro] [cinco] [seis] [siete] [ocho] [nueve] [cero]];
Figura 12. Matriz alfabeto |
Figura 13 Matriz numeral |
Procedemos a realizar una conversión de matrices a un arreglo de celdas de las variables numeral, alfabeto y matricula, para poder trabajar con elementos separados y definidos por una posición para poder realizar operaciones individuales sobre cada uno de los elementos. El siguiente es el código utilizado:
matricula=[[L1b] [L2b] [L3b] [L4b] [L5b] [L6b]];
ab=mat2cell(alfabeto,[42],[24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24]);
numero=mat2cell(numeral,[42],[24 24 24 24 24 24 24 24 24 24]);
plac=mat2cell(matricula,[42],[24 24 24 24 24 24]);
Por ultimo, debemos encontrar un método adecuado para realizar el reconocimiento del carácter hallado en la placa con uno presenta en la base de datos. En esta caso se utilizo la técnica de correlación. Matlab permite calcular el coeficiente de correlación entre dos matrices bidimensionales, dando como resultado un valor que representa la igualdad entre dos matrices. corr2 realiza el coeficiente de correlación usando la expresión:
donde = mean2(A), and = mean2(B)
Se desarrolló un ciclo, el cual toma los valores de la correlación del carácter que está siendo analizado y lo introduce en una matriz de 3 filas por 26 o 10 columnas, según sean letras o números respectivamente. Posteriormente se hallan los máximos de las tres columnas y son almacenados en otra matriz. Finalmente se encuentran las posiciones en las que estaban los máximos para así determinar la letra o el número al que corresponden y mediante otro ciclo se muestra esto en pantalla. El código implementado fue el siguiente:
%Ciclo que reconoce las letras y les asigna la posicion en la matriz de abecedario
fila=1;
ind=1;
while fila < 4
posp=1;
for posp=1:3
plc=plac{1,posp};
pos=1;
temp=0;
while pos<27
temp=ab{1,pos};
co=corr2(temp,plc);
letra(fila,pos)=co;
pos=pos+1;
end
fila=fila+1;
posp=posp+1;
end
end
for ind = 1:3
maxs=max(letra,[],2);
[posx posy]=find(letra==maxs(ind,1));
letras(ind)=posy
ind=ind+1;
end
%Ciclo que reconoce los numeros y les asigna la posicion en la matriz de
%numeros
fila=1;
ind=1;
while fila < 4
posp=4;
for posp=4:6
plc=plac{1,posp};
pos=1;
temp=0;
while pos<11
temp=numero{1,pos};
co=corr2(temp,plc);
num(fila,pos)=co;
pos=pos+1;
end
fila=fila+1;
posp=posp+1;
end
end
for ind = 1:3
maxs=max(num,[],2);
[posx posy]=find(num==maxs(ind,1));
nums(ind)=posy
ind=ind+1;
end
close all
mal='a';
ltr=1;
lt=1;
while ltr < 4
while lt < 4
if letras(ltr)== 1
mal(lt)='A'
elseif letras(ltr) == 2
mal(lt)='B'
elseif letras(ltr) == 3
mal(lt)='C'
elseif letras(ltr) == 4
mal(lt)='D'
elseif letras(ltr) == 5
mal(lt)='E'
elseif letras(ltr) == 6
mal(lt)='F'
elseif letras(ltr) == 7
mal(lt)='G'
elseif letras(ltr) == 8
mal(lt)='H'
elseif letras(ltr) == 9
mal(lt)='I'
elseif letras(ltr) == 10
mal(lt)='J'
elseif letras(ltr) == 11
mal(lt)='K'
elseif letras(ltr) == 12
mal(lt)='L'
elseif letras(ltr) == 13
mal(lt)='M'
elseif letras(ltr) == 14
mal(lt)='N'
elseif letras(ltr) == 15
mal(lt)='O'
elseif letras(ltr) == 16
mal(lt)='P'
elseif letras(ltr) == 17
mal(lt)='Q'
elseif letras(ltr) == 18
mal(lt)='R'
elseif letras(ltr) == 19
mal(lt)='S'
elseif letras(ltr) == 20
mal(lt)='T'
elseif letras(ltr) == 21
mal(lt)='U'
elseif letras(ltr) == 22
mal(lt)='V'
elseif letras(ltr) == 23
mal(lt)='W'
elseif letras(ltr) == 24
mal(lt)='X'
elseif letras(ltr) == 25
mal(lt)='Y'
elseif letras(ltr) == 26
mal(lt)='Z'
else
mal(lt)='Paila'
end
lt=lt+1;
ltr=ltr+1;
end
end
nmr=1;
man='1';
nm=1;
while nmr < 4
while nm < 4
if nums(nmr)== 1
man(nm)='1'
elseif nums(nmr) == 2
man(nm)='2'
elseif nums(nmr) == 3
man(nm)='3'
elseif nums(nmr) == 4
man(nm)='4'
elseif nums(nmr) == 5
man(nm)='5'
elseif nums(nmr) == 6
man(nm)='6'
elseif nums(nmr) == 7
man(nm)='7'
elseif nums(nmr) == 8
man(nm)='8'
elseif nums(nmr) == 9
man(nm)='9'
elseif nums(nmr) == 10
man(nm)='0'
else
disp('Paila')
end
nm=nm+1;
nmr=nmr+1;
end
end
plate=horzcat(mal,man);
disp(plate)
CONCLUSIONES
-
La utilización de los elementos estructurantes, definidos en Matlab, es una herramienta poderosa para simplificar los procedimientos a realizar cuando trabajamos con imágenes y debemos eliminar estructuras y objetos irrelevantes al objetivo propuesto.
-
No es aconsejable utilizar elementos estructurantes y propiedades morfológicas si el objetivo es implementar el código en otro compilador y programa diferente al de matlab, pero por facilidad y economía de tiempo se podrían utilizar para tener un conocimiento inicial de los pasos que se deben realizar para cumplir el objetivo propuesto a la imagen.
-
Al utilizar métodos tradicionales de filtrado, erosionado y dilatado de imágenes, aseguramos la portabilidad del código hacia otros programas y dispositivos, como DSP´s, aunque su implementación es mas larga, dificultosa y de mayor cuidado.
Descargar
Enviado por: | Yesid Jarma |
Idioma: | castellano |
País: | Colombia |