elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  PRoblema con ejercicio en Matlab
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: PRoblema con ejercicio en Matlab  (Leído 2,615 veces)
Baphomet2204

Desconectado Desconectado

Mensajes: 56


Programo luego existo


Ver Perfil
PRoblema con ejercicio en Matlab
« en: 15 Octubre 2019, 20:33 pm »

Tomar una foto por una cámara, la foto se le saca a una hoja de árbol sobre una hoja de papel color rosa, leer la foto y obtener valor hexadecimal de los tonos amarillos, verdes y cafe descartando los colores rosa de la hoja, intentar detectar la forma de la hoja de árbol.

No he podido sacar el valor hexadecimal ni la forma, este es mi avance


Código
  1. imaqhwinfo  
  2.  
  3. cam=imaqhwinfo;  
  4.  
  5. cam.InstalledAdaptors;
  6.  
  7. vid=videoinput('winvideo',2,'yuy2_640x480');%ajustar para que tenga tamaño al de la caja
  8.  
  9.  
  10.  
  11. foto=getsnapshot(vid);
  12.  
  13. im_entrada=ycbcr2rgb(foto);
  14.  
  15. imshow(im_entrada)
  16.  
  17.  
  18.  
  19. im_g=rgb2gray(im_entrada);
  20.  
  21. umb=graythresh(im_g);
  22.  
  23. bw=im2bw(im_g,umb);
  24.  
  25. bw=not(bw);
  26.  
  27. bw=bwareaopen(bw,100);
  28.  
  29. [L1 Ne1]=bwlabel(bw);
  30.  
  31. propiedad=regionprops(L1);
  32.  
  33.  
  34.  
  35.  
  36.  
  37. %imshow(im_entrada);
  38.  
  39. % se selecciona la imajen para trabajar con ella y poder tomar la decicion  
  40.  
  41. %im_entrada = imread(rgb);
  42.  
  43. %Matrices que separa en tres a la imagen
  44.  
  45. imR = double(im_entrada(:,:,1)); %Componente rojo de la imagen de entrada
  46.  
  47. imG = double(im_entrada(:,:,2)); %Componente verde
  48.  
  49. imB = double(im_entrada(:,:,3)); %Componente azul
  50.  
  51.  
  52.  
  53. [N,M,Z]=size(im_entrada); %Tamaño de la imagen de entrada. N es varianle para renglos, M para columnas y Z  
  54.  
  55. %será una nueva variable que representará los tres componentes de la imagen RGB
  56.  
  57. Y = ones(N,M);
  58.  
  59. %Seis umbrales para la comparación de la imagen de entrada para obtener la
  60.  
  61. %imagen de salida. Tres umbrales serán superiores y tres serán inferiores
  62.  
  63. Tr1= 123.85;
  64.  
  65. Tr2= 238.15;
  66.  
  67. Tg1= 39.77;
  68.  
  69. Tg2= 165.23;
  70.  
  71. Tb1= 8.96;
  72.  
  73. Tb2= 126.04;
  74.  
  75.  
  76.  
  77. for i=1:N;
  78.  
  79.    for j=1:M;
  80.  
  81.        %Comparación de los tres componentes con los umbrales
  82.  
  83.        if((imR(i,j) > Tr1 && imR(i,j) < Tr2) && (imG(i,j) > Tg1 && imG(i,j) < Tg2) && (imB(i,j) > Tb1 && imB(i,j) < Tb2));
  84.  
  85.            %Si el valor cae dentro de los valores calculados del umbral,el pixel de la imagen de salida será color blanco ////////por lo cual el jitomate esta bueno  
  86.  
  87.            Y(i,j)=1;
  88.  
  89.        else
  90.  
  91.            Y(i,j)=0;
  92.  
  93.        end
  94.  
  95.    end
  96.  
  97. end
  98.  
  99. se = strel('disk',10); %Estructura morfológica. Dilatación y eroción, la región se dilata en forma de disco con un radio de 10px la redonda y después de erosiona 10px a la redonda.
  100.  
  101. imagen_cerrada = imclose(Y,se);
  102.  
  103.  
  104.  
  105.  
  106. %imshow(imagen_cerrada)
  107.  
  108.  
  109.  
  110. bwn = bwareaopen(imagen_cerrada,30); %Elimina los pixeles dispersos. En una imagen binaria elimina a todos los pixeles al número que se le asigna.
  111.  
  112.  
  113.  
  114.  
  115. [L Ne]=bwlabel(bwn);
  116.  
  117. propied=regionprops(L);
  118.  
  119. int i;
  120.  
  121. for i=0:i+1:Ne;
  122.  
  123.    area2=propied.Area;
  124.  
  125. end
  126.  
  127. for i=0:i+1:Ne1;
  128.  
  129.    area=propiedad.Area;
  130.  
  131. end
  132.  
  133. porcent=(area2/area)*100;
  134.  
  135. if(porcent>20);
  136.  
  137.    imshow([bwn,bw]);
  138.  
  139.    text=('El jitomate es comestible');
  140.  
  141.    disp(text);
  142.  
  143.   % sendUSB2(text);
  144.  
  145.  
  146.  
  147. end
  148.  
  149. disp(porcent);
  150.  
  151. imshow([bwn,bw]);
  152.  
  153. %imshow(bw);

si alguno tuviera una idea de como hacerlo, gracias de antemano


En línea

$Diseñando_vida

while(vivas)
{
       Come();
       //Duerme();
       Programa();
       Repite();
}
Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.391


Ver Perfil
Re: PRoblema con ejercicio en Matlab
« Respuesta #1 en: 16 Octubre 2019, 07:48 am »

De entrada el color rosa, míralo como el color chicle, es decir un valor como:
Verde = 0
Rojo = 255
Azul = 255

Tomando una foto, es muy probable que ese color se difumine en varios sonos similares, mejor si se escanea, aunque el resultado tampoco será perfecto.

Lo que se pide básicamente es obtener los colores de la hoja que no sean rosa, esto es el rosa se trata como si fuera un color transparente. Sin embargo, resulta ambiguo... no se aclara como debe ser el formato devuelto (aparte de que debe ser en hexadecimal)... ni si basta indicar una sola vez cada color o no.

Así que supondremos que se pide obtener todos los colores que no sean rosa, y que no se guarda posición del píxel para dicho color, y que se guarda para cada color píxel, haya aparecido previamente dicho color o no.



Código:


constantes byte RosaR=255, RosaA=255, RosaV=0  // valor canales del rosa-chicle
byte nivSimil  // nivel de similitud
byte r, a, v   // canal de cada colores
int f, p     // num filas y valor píxel
string hexColor  // color en hexadecimal.
int ancho, alto  // medidas d ela imagen
array int Imagen(,)   // array de dos dimensiones o unidimensional si se calcula fila a fila la posición absoluta del píxel...

fichero fiI  // fichero de entrada (Input), el de la imagen
fichero fio  // fichero  de salida (output), el del resultado

fiI.Abrir(rutaImagen) // se abre el fichero de entrada
fio.Abrir(ruta)   // se abre el fichero de salida.

alto = fiI.LeerEnCabecera(alto)
ancho = fiI.LeerEnCabecera(ancho)

// solo la que proceda... se leen los píxeles desde final de cabecera...
//    se supone que la imagen está descomprimida, sino es así, se precisa
//    el decodificador del formato de imagen para obtener el array de píxeles...
//    se da por supuesto conocer tal circunstancia.
Imagen(alto * ancho) = fiI.LeerPixeles  //lectura unidimensional
Imagen(alto, ancho) = fiI.LeerPixeles  // lectura bidimensional
fiI.Cerrar

nivSimil  = 16
bucle f por cada fila en la imagen  //imagen sería un array de píxeles, por ejemplo.
    bucle p por cada pixel en f          // p es el enésimo píxel en la f (fila) actual.
        // 1 obtener los canales del pixel.
        r  = (p and 255)
        v = ((p \ 256) and 255)
        b = (p \ 65536)
        
        // 2 descartar si es rosa o similar... vamos a suponer algún grado de similitud
        //   si, el color está 16 valores a un lado u otro por canal consideramos que es similar... y en tal caso se descarta, si no, se acepta.
       //  como dicho rosa está en los extremos, basta mirar hacia el otro extremo.
       Si (((v > = (RosaV + nivSimil  )) y ((R <= (RosaV - nivSimil)) y  ((a <= (RosaA - nivSimil)) )
           // formato: AAVVRR  (esto es primero azul, luego verde, luego rojo)
           // el operador '+' actúa como un concatenador de caracteres...
           hexcolor = (((a\16).ToChar) + ((a and 15).ToChar) + ((v\16).ToChar) + ((v and 15).ToChar)  + ((r\16).ToChar) + ((r and 15).ToChar)) + " "
           fiO.SaveToFile(appendtofinal, hexcolor)
       Sino
           fiO.SaveToFile(appendtofinal, "------ ")   // color rosa se guarda así, necesario si
           // ...se quiere mantener posición relativa de cada color que no sea rosa.
           // cada clor va separado por un espacio, para facilitar su 'lectura', visualmente...
       fin si
    siguiente
siguiente

fiO.Cerrar

Se puede optimizar, si al canal de rosa, ya se le aplica antes del bucle, el valor de similitud, en vez de ecalcularlo por cada píxel... como los valores de rosa son constantes, se rquerirán sendas variables, para ello.
Sería aún más útlil, si en vez del rosa, fuera cualquier otro color recibido por parámetro, tal color se descomprondría e sus canales, aunque en tal caso, la verificación para descartar, es más larga pues hay que descartar también los valores al otro lado del límite de cada canal, actualmente se aprovecha que el rosa, tiene sus tres canales en valores que a un lado son límite...


Falta obtener la forma... Ahora nos ocupamos de ella...
La forma es un contorno. Un contorno, es el recorrido perimetral de la forma.
Sea una imagn de X*Y medidas, podemos saber que el controno, será como máximo (X+Y) * 2 de tamaño... que es el perímetro de un rectángulo, en este caso del rectángulo que forma la imagen. Nótese que solo consideramos la forma externa, si por ejemplo la hoja tuviera uno o más rotos internos, esas formas no quedan detectadas... Eso es una fase posteiror, para aplicar una vez se entienda al menos la primera, detectar la forma externa.

Cómo se obtiene?. Básicamente definimos dos arrays uno del vertical y otro del horizontal, de una estructura que para el vertical define izquierdo y derecho y para el horizontal superior e inferior... una simple abstración, nos permite resumir ambas en inicio y fin. Cada una define un punto, una posicion, el par X,Y.

Código:
Estructura Posicion
    int X
    int Y
Fin estructura

Estructura Extremo
    posicion Inicial         // izquierda o superior
    posicion Final           // derecha o inferior
fin estructura

Array de Extremo PerimVertical(alto)
array de Extremo PerimHorizontal(ancho)

Array Extremo NumPuntos(0 a 1)  // 0 refiere vertical, 1 refiere horizontal, cantidad de puntos que cvontiene el array (el resto sobra)

int x, y, n   // punteros de avance para cada array...
Nótese que el contorno, será la línea que una dichos puntos... como también resulta ambiguo la forma en que deba ser devuelto, baste estos dos arrays y luego haz con ellos lo que quiera, posiblemente escribirlos a fichero o sarlo para dibujar en algún lienzo... y luego guardar la imagen resultante a fichero.

Aunque los siguientes bucles parezcan mucha sobrecarga de trabajo, en realidad, solo se recorre hasta encontrar un pixle que no sea similar al rosa.
Código:
// obtener la parte vertical izquierda...
n=0
bucle para y desde 0 hasta Alto-1  
    bucle para x desde 0 hasta Ancho-1  
         Si (Similar(Rosa, imagen(y, x), 16) = FALSE)
             PerimVertical(n).Inicial.X = x
             PerimVertical(n).Inicial.y = y
             n = (n +1)
             Salir del bucle
         fin si
    siguiente
siguiente
NumPuntos(0).Inicial = n   // solo los primeros 'n' puntos dle array PerimVertical son válidos

// obtener la parte vertical derecha...
n=0
bucle para y desde 0 hasta Alto-1  
    bucle para x desde Ancho-1 hasta 0 retrocediendo
         Si (Similar(Rosa, imagen(y, x), 16) = FALSE)
             PerimVertical(n).Final.X = x
             PerimVertical(n).Final.y = y
             n = (n +1)
             Salir del bucle
         fin si
    siguiente
siguiente
NumPuntos(0).Final = n  // solo los primeros 'n' puntos dle array PerimVertical son válidos

// obtener la parte horizontal superior...
n=0
bucle para x desde 0 hasta Ancho-1  
    bucle para y desde 0 hasta Alto-1  
         Si (Similar(Rosa, imagen(y, x), 16) = FALSE)
             PerimHorizontal(n).Inicial.X = x
             PerimHorizontal(n).Inicial.y = y
             n = (n +1)
             Salir del bucle
         fin si
    siguiente
siguiente
NumPuntos(1).Inicial = n   // solo los primeros 'n' puntos dle array PerimHorizontal son válidos

// obtener la parte horizontal inferior...
n=0
bucle para x desde Ancho-1 hasta 0 retrocediendo
    bucle para y desde 0 hasta Alto-1  
         Si (Similar(Rosa, imagen(y, x), 16) = FALSE)
             PerimHorizontal(n).Final.X = x
             PerimHorizontal(n).Final.y = y
             n = (n +1)
             Salir del bucle
         fin si
    siguiente
siguiente
NumPuntos(1).Final = n   // solo los primeros 'n' puntos dle array PerimHorizontal son válidos

y listo, lo que hagas luego con dichos arrays ya es cosa tuya, pués no queda definido... Como dije antes, se puede guardar a fichero, o genera la imagen de la forma, recoriendo los 4 arrays para pintar el píxel que refieren sus cordenadas... y quizás luego guardarla la imagen resultante a fichero.

Similar ahora la definimos como una función, para dejar más claro la funcionalidad de obtener el contorno.
Esta función hace lo que ya hemos hecho antes en código, pero integrado en la misma funcion.
Rosa lo pasamos entero, es más rentabale pasar los canales ya descompuestos... (para hacelro una sola vez, no con cada color).
Código:
Buleano = ColorSimilar(int Color, int colCandidato, int nivel)
    int r1, v1, a1, r2, g2, a2, r3, g3, a3
 
    // Descomponer el color base a comparar aplicado sus niveles máximo y minimo a cada canal...
    r1= fixToRangoByte((color and 255) + nivel)
    r2 =fixToRangoByte((color and 255) - nivel)

    g1= fixToRangoByte(((color \ 256) and 255) + nivel)
    g2 =fixToRangoByte(((color \ 256) and 255) - nivel)

    a1= fixToRangoByte((color \ 65536) + nivel)
    a2 =fixToRangoByte((color \ 65536) - nivel)

    // Descomponer el color candidato en sus canales...
    r3 = (colCandidato and 255)
    g3 = ((colCandidato\ 256) and 255)
    a3 = (colcandidato \ 65536)

    // Comparación:
    //    ejemplo para canal rojo: r= 45;  r1=(45+16) = 61;  r2= (45-16) = 29
    //        si r3 cae ente 29 y 61 el rojo es similar... igual para el resto de canales.
    Si ((r3 <= r1) y (r3 >= r2))
        Si ((g3 <= g1) y (g3 >= g2))
            Si ((a3 <= a1) y (a3 >= a2))
                devolver TRUE
            fin si
        fin si
    fin si
fin funcion

Byte = fixToRangoByte(int Valor)
    Si (valor < 0 )
       valor = 0
    osi (Valor > 255)
       valor = 255
    fin si

    devolver Valor
Fin funcion

Si en vez de hablar de similitud, pudiéramos hablar de igualdad, es decir que el rosa, no tuviera variedad tonal, el cálculo se aceleraría, pués bastaría comparar el píxel 'p', con rosa , en vez de calcular si es similar... pero sacando fotos, o escaneos, no habrá un color puro... la luminosidad del ambiente y los reflejos marcarán variaciones tonales.


« Última modificación: 16 Octubre 2019, 21:57 pm por NEBIRE » En línea

Baphomet2204

Desconectado Desconectado

Mensajes: 56


Programo luego existo


Ver Perfil
Re: PRoblema con ejercicio en Matlab
« Respuesta #2 en: 16 Octubre 2019, 17:24 pm »

Excelente amigo muchas gracias, llevaba 3 días rompiéndome la cabeza, apenas empiezo a usar matlab y quise aventarme con este problema, creo que sobrestime mis pobres capacidades en este lenguaje, gracias y un saludo
En línea

$Diseñando_vida

while(vivas)
{
       Come();
       //Duerme();
       Programa();
       Repite();
}
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[ problema ] ejercicio 100
Ejercicios
_mÙëK§™_ 2 4,986 Último mensaje 1 Diciembre 2007, 01:31 am
por Iñaki Viggers
Matlab
Programación General
Gm3z 0 2,430 Último mensaje 26 Noviembre 2012, 18:33 pm
por Gm3z
Problema con instalación de matlab.
Mac OS X
kondrag_X1 1 5,256 Último mensaje 27 Mayo 2014, 23:12 pm
por kondrag_X1
Problema para instalar matlab
GNU/Linux
Fox_Neo 4 4,235 Último mensaje 9 Mayo 2014, 15:26 pm
por Gh057
[MATLAB] Problema con errodlg y buttondownfcn
Programación General
DarK_FirefoX 0 1,808 Último mensaje 3 Diciembre 2015, 20:10 pm
por DarK_FirefoX
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines