Procesamiento de imágenes José Luis Gómez-Muñoz Operaciones puntuales: El nuevo valor de cada punto (pixel) depende únicamente de su valor anterior Una matriz de números entre cero y uno se puede usar para representar una imagen en tonos de grises: Una matriz con valores entre 0.0 y 1.0: miPrimerMatriz = 0.0 0.0 0.0 0.0 0.3 0.0 0.3 0.0 0.3 0.7 0.0 0.3 0.3 0.7 1.0 0.0 880., 0.3, 0.3, 0.3<, 80., 0., 0.7, 0.7<, 80., 0.3, 0., 1.<, 80., 0., 0.3, 0.<< Interpretando 0.0 como negro, 1.0 como blanco, y valores intermedios como tonos de gris, se obtiene una pequeña "imagen": miPrimerImagen = Image@miPrimerMatrizD La matriz original puede ser obtenida de la imagen con el comando ImageData: LAD06.nb 2 ImageData@miPrimerImagenD 880., 0.3, 0.3, 0.3<, 80., 0., 0.7, 0.7<, 80., 0.3, 0., 1.<, 80., 0., 0.3, 0.<< Restando cada elemento de "1" para obtener el "negativo" de la imagen Mathematica le resta al número uno cada elemento de miPrimerMatriz para generar el correspondiente elemento de miSegundaMatriz miSegundaMatriz = 1 − miPrimerMatriz 881., 0.7, 0.7, 0.7<, 81., 1., 0.3, 0.3<, 81., 0.7, 1., 0.<, 81., 1., 0.7, 1.<< Se obtiene el "negativo" de la imagen original miSegundaImagen = Image@miSegundaMatrizD La matriz puede ser obtenida de la imagen con el comando ImageData: ImageData@miSegundaImagenD 881., 0.7, 0.7, 0.7<, 81., 1., 0.3, 0.3<, 81., 0.7, 1., 0.<, 81., 1., 0.7, 1.<< Elevando a la cuarta potencia cada número para aumentar el contraste Aquí se eleva a la cuarta potencia cada elemento de miSegundaMatriz. LAD06.nb 3 miTercerMatriz = miSegundaMatriz^ 4 881., 0.2401, 0.2401, 0.2401<, 81., 1., 0.0081, 0.0081<, 81., 0.2401, 1., 0.<, 81., 1., 0.2401, 1.<< Se obtiene una imagen similar a la anterior pero con más "contraste" miTercerImagen = Image@miTercerMatrizD La matriz original puede ser obtenida de la imagen con el comando ImageData: ImageData@miTercerImagenD 881., 0.2401, 0.2401, 0.2401<, 81., 1., 0.0081, 0.0081<, 81., 0.2401, 1., 0.<, 81., 1., 0.2401, 1.<< Importa una imagen JPG El comando FileNames permite mostrar las imágenes JPG que están en el folder "Mis documentos" de esta computadora. El resultado de este comando será diferente en tu computadora. Si obtienes como resultado una lista vacía, obtén una imagen JPG de internet y guárdala en la carpeta (folder) donde Mathematica busca archivos ("Mis documentos" si tu computadora usa Windows y Mathematica versión 7) FileNames@"∗.JPG"D 8ambassadors.jpg, h1.jpg, im01.jpg, landscape.jpg, lenna.jpg< Importa una de las imágenes JPG que aparecieron en tu computadora. LAD06.nb 4 miCuartaFoto = Import@"lenna.jpg"D La convertimos en una imagen en tonos de grises con el comando ColorConvert LAD06.nb 5 miCuartaImagen = ColorConvert@miCuartaFoto, "Grayscale"D La matriz puede ser obtenida de la imagen con el comando ImageData. La matriz es tan grande, que Mathematica tarda un poco, y finalmente decide no mostrarla completa. Si quieres ver más de la matriz, oprime el botón Show More, pero para evitar que la computadora quede trabada, No oprimas Show Full Outup. miCuartaMatriz = ImageData@miCuartaImagenD A very large output was generated. Here is a sample of it: 880.639216, 0.643137, 0.643137, 0.635294, 0.623529, 0.619608, 0.627451, 0.631373, 0.643137, 0.619608, 0.627451, 0.619608, 0.627451, 0.643137, 0.615686, 0.611765, 448, 0.486275, 0.462745, 0.47451, 0.458824, 0.478431, 0.447059, 0.466667, 0.466667, 0.498039, 0.596078, 0.670588, 0.67451, 0.678431, 0.678431, 0.607843, 0.513725<, 478, 81<< Show Less Show More Show Full Output Set Size Limit... LAD06.nb 6 Restando cada elemento de "1" para obtener el "negativo" de la imagen Mathematica le resta al número uno cada elemento de miCuartaMatriz para generar el correspondiente elemento de miQuintaMatriz. La matriz es tan grande, que Mathematica tarda un poco, y finalmente decide no mostrarla completa. Si quieres ver más de la matriz, oprime el botón Show More, pero para evitar que la computadora quede trabada, No oprimas Show Full Outup. miQuintaMatriz = 1 − miCuartaMatriz A very large output was generated. Here is a sample of it: 880.360784, 0.356863, 0.356863, 0.364706, 0.376471, 0.380392, 0.372549, 0.368627, 465, 0.403922, 0.329412, 0.32549, 0.321569, 0.321569, 0.392157, 0.486275<, 478, 81<< Show Less Show More Show Full Output Se obtiene el "negativo" de la imagen original Set Size Limit... LAD06.nb 7 miQuintaImagen = Image@miQuintaMatrizD Elevando a la cuarta potencia cada número para aumentar el contraste Aquí se eleva a la cuarta potencia cada elemento de miQuintaMatriz. La matriz es tan grande, que Mathematica tarda un poco, y finalmente decide no mostrarla completa. Si quieres ver más de la matriz, oprime el botón Show More, pero para evitar que la computadora quede trabada, No oprimas Show Full Outup. LAD06.nb 8 miSextaMatriz = miQuintaMatriz^ 4 A very large output was generated. Here is a sample of it: 880.016943, 0.0162183, 0.0162183, 0.0176918, 0.0200874, 0.0209376, 0.0192634, 466, 0.0266188, 0.0117749, 0.0112241, 0.0106929, 0.0106929, 0.0236504, 0.0559147<, 478, 820, 478, 20<< Show Less Show More Show Full Output Set Size Limit... Se obtiene una imagen similar a la anterior pero con más "contraste" miSextaImagen = Image@miSextaMatrizD LAD06.nb 9 "Posterizado" En la siguiente operación, cada elemento de la matriz se multiplica por 4, lo que se obtiene se redondea, y después se divide entre 4. Veamos en que se transforman algunos números cuando se hace esa operación: Si comenzamos con el número 0.2, lo multiplicamos por 4 y obtenemos 0.8, al redondearlo obtenemos 1, lo dividimos entre 4 y obtenemos 1/4 Si comenzamos con el número 0.3, lo multiplicamos por 4 y obtenemos 1.2, al redondearlo obtenemos 1, lo dividimos entre 4 y obtenemos 1/4 Si comenzamos con el número 0.7, lo multiplicamos por 4 y obtenemos 2.8, al redondearlo obtenemos 3, lo dividimos entre 4 y obtenemos 3/4 Si comenzamos con el número 0.8, lo multiplicamos por 4 y obtenemos 3.2, al redondearlo obtenemos 3, lo dividimos entre 4 y obtenemos 3/4 Como se puede ver con estos ejemplos, toda la variedad de números que hay en la matriz inicial se transforma con esta operación 1 2 3 4 4 4 en sólo algunos valores posibles: 0, , , , 1. La matriz es tan grande, que Mathematica tarda un poco, y finalmente decide no mostrarla completa. Si quieres ver más de la matriz, oprime el botón Show More, pero para evitar que la computadora quede trabada, No oprimas Show Full Outup. miSeptimaMatriz = Round@4 ∗ miCuartaMatrizD ê 4 A very large output was generated. Here is a sample of it: 3 3 4 1 4 1 99 , 2 1 2 1 2 , , , 2 1 2 1 2 , , , , 3 4 1 , 2 1 2 1 2 Show Less , , , 3 4 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , 3 4 3 4 1 2 1 2 Show More 3 , , , , 4 3 4 1 2 1 2 , , , , 3 4 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , 3 4 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , Show Full Output 3 4 3 4 1 2 1 2 , , , , 3 4 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , 1 2 3 4 1 2 1 2 , , , , 1 2 3 , 4 1 2 1 2 , , , 3 4 3 4 1 2 1 2 , , , , 3 4 3 4 1 2 3 4 , , , , 1 2 3 , 4 1 2 3 4 , 1 2 3 4 1 , 2 3 , 4 , , , , 1 2 3 4 1 2 3 4 , , , , 1 2 1 2 1 2 1 2 , 1 2 , 1 2 , 1 2 , , 375, , , 1 2 1 2 , 1 2 , 1 2 , 2 3 4 4 4 2 1 2 1 2 , 1 2 , , =, 479= Set Size Limit... 1 1 Esta es la imagen que se obtiene. Observa que sólo hay cinco tonos de gris (0, , , , 1) en toda la imagen: , 1 2 , 1 2 , LAD06.nb 10 miSeptimaImagen = Image@miSeptimaMatrizD Convolución: El nuevo valor de cada punto (pixel) depende de los valores anteriores de los puntos vecinos Primer ejemplo de convolución a mano Aquí hay algunos cálculos de "convolución" similares a los que se hicieron a mano en el salón de clases. LAD06.nb 11 "Imagen original" "Kernel" 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 1. 0.8 0. 0. 0.8 0. 0. 0. 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 0.8 0.8 0. 0. 0.8 0. 0. 0. 1 1 1 1 −8 1 1 1 1 "Convolución" "Imagen Final" −3. −4.8 −2.8 −6.4 0.31 0.15 0.33 0. 4.2 −3. 4.4 2.6 0.98 0.31 1. 0.83 4.2 −3. 4.2 2.4 0.98 0.31 0.98 0.81 −3. −4.8 −3. −4.8 0.31 0.15 0.31 0.15 Segundo ejemplo de convolución a mano Aquí hay algunos cálculos de "convolución" similares a los que se hicieron a mano en el salón de clases. "Imagen original" "Kernel" 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 1. 0.8 0. 0. 0.8 0. 0. 0. 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 0.8 0.8 0. 0. 0.8 0. 0. 0. −1 0 1 −1 0 1 −1 0 1 "Convolución" "Imagen Final" 1.8 0. −1.6 0. 1. 0.5 0.06 0.5 1.8 0. −1.6 0. 1. 0.5 0.06 0.5 1.8 0. −1.8 0. 1. 0.5 0. 0.5 1.8 0. −1.8 0. 1. 0.5 0. 0.5 Ejercicio: Realiza a mano los siguientes cálculos para obtener la "imagen final": "Imagen original" "Kernel" 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 1. 0.8 0. 0. 0.8 0. 0. 0. 0. 0. 0.8 0. 0. 0. 0.8 0.8 1. 0.8 0.8 0.8 0. 0. 0.8 0. 0. 0. 1 2 1 2 4 2 1 2 1 "Convolución" "Imagen Final" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " LAD06.nb 12 Convolución con un Kernel para detección de bordes El comando ImageConvolve hace los mismos cálculos que hiciste a mano. En este ejemplo, la imagen obtenida es clara donde hay cambios bruscos en la imagen original, y es obscura donde la imagen original cambia lentamente: miOctavaImagen = ImageConvolveBmiCuartaImagen, 1 1 1 1 −8 1 F 1 1 1 La matriz puede ser obtenida de la imagen con el comando ImageData. La matriz es tan grande, que Mathematica tarda un poco, y finalmente decide no mostrarla completa. Si quieres ver más de la matriz, oprime el botón Show More, pero para evitar que la computadora quede trabada, No oprimas Show Full Outup. LAD06.nb 13 miOctavaMatriz = ImageData@miOctavaImagenD A very large output was generated. Here is a sample of it: 994.44089 × 10−16 , −0.027451, −0.0392157, −0.0235294, 0.0235294, 0.0431373, 0.00392157, 466, −0.0666667, −0.223529, −0.0313725, −0.0470588, −0.235294, −0.0823529, 0.27451=, 478, 81<= Show Less Show More Show Full Output Set Size Limit... "Kernel" para detección de cambios horizontales Este otro "kernel" sirve para "detectar" cambios horizontales. Observa como la nariz está muy bien definida, mientras que los labios casi no se ven LAD06.nb 14 miNovenaImagen = ImageConvolveBmiCuartaImagen, −1 0 1 −1 0 1 F −1 0 1 "Kernel" para detección de cambios verticales Este otro "kernel" sirve para "detectar" cambios verticales. Observa que con la nariz y los labios pasa lo opuesto a la imagen anterior, ahora la nariz no está muy bien definida, mientras que los labios se ven muy claramente: LAD06.nb 15 miDecimaImagen = ImageConvolveBmiCuartaImagen, 1 1 1 0 0 0 F −1 − 1 − 1 "kernel" que duplica la imagen: Con este enorme kernel se enciman dos copias de la imagen (observa que sólo hay dos números distintos de cero, en dos esquinas de la matriz): LAD06.nb 16 miDecimaImagen = ImageConvolveBmiCuartaImagen, 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 F LAD06.nb 17 "Kernel" que suaviza la imagen Comparando con el ejemplo anterior, podemos pensar que este kernel genera 64 imágenes encimadas, lo cual terminamos viendo como una sola imagen suavizada, como "fuera de foco": LAD06.nb 18 miDecimaImagen = ImageConvolveBmiCuartaImagen, 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 1 ê 64 F 1 ê 64 1 ê 64 1 ê 64 1 ê 64 LAD06.nb 19 Otra forma de procesamiento: convirtiendo la imagen en una función contínua (interpolación) Convirtiendo en una función contínua Este comando convierte la matriz en una función contínua: miImagenInterpolada = ListInterpolation@miCuartaMatrizD InterpolatingFunction@881., 480.<, 81., 480.<<, <>D Reproduce la siguiente imagen y USA EL RATÓN PARA GIRAR LA IMAGEN. Plot3D@miImagenInterpolada@x, yD, 8x, 1, base<, 8y, 1, altura<, PlotPoints → 100, Mesh → False, ColorFunction → GrayLevel, Lighting → 88"Ambient", White<<, ViewPoint → 80, −0.6, 3< D LAD06.nb 20 DensityPlot permite ver la función contínua como imagen DensityPlot@miImagenInterpolada@x, yD, 8x, 1, base<, 8y, 1, altura<, PlotPoints → 200, Mesh → False, AspectRatio → Automatic, Frame → None, ColorFunction → GrayLevelD LAD06.nb 21 Modificando la función contínua DensityPlotBmiImagenInterpoladaAx2 , y2 E, :x, 1, :y, 1, base >, altura >, PlotPoints → 100, Mesh → False, AspectRatio → Automatic, Frame → None, ColorFunction → GrayLevelF LAD06.nb 22 Modificando la función contínua In[68]:= Out[68]= DensityPlot@miImagenInterpolada@Exp@xD, Exp@yDD, 8x, 1, Log@baseD<, 8y, 1, Log@alturaD<, PlotPoints → 100, Mesh → False, AspectRatio → Automatic, Frame → None, ColorFunction → GrayLevelD