(************** Content-type: application/mathematica **************
                     CreatedBy='Mathematica 5.2'

                    Mathematica-Compatible Notebook

This notebook can be used with any Mathematica-compatible
application, such as Mathematica, MathReader or Publicon. The data
for the notebook starts with the line containing stars above.

To get the notebook into a Mathematica-compatible application, do
one of the following:

* Save the data starting with the line of stars above into a file
  with a name ending in .nb, then open the file inside the
  application;

* Copy the data starting with the line of stars above to the
  clipboard, then use the Paste menu command inside the application.

Data for notebooks contains only printable 7-bit ASCII and can be
sent directly in email or through ftp in text mode.  Newlines can be
CR, LF or CRLF (Unix, Macintosh or MS-DOS style).

NOTE: If you modify the data for this notebook not in a Mathematica-
compatible application, you must delete the line below containing
the word CacheID, otherwise Mathematica-compatible applications may
try to use invalid cache data.

For more information on notebooks and Mathematica-compatible 
applications, contact Wolfram Research:
  web: http://www.wolfram.com
  email: info@wolfram.com
  phone: +1-217-398-0700 (U.S.)

Notebook reader applications are available free of charge from 
Wolfram Research.
*******************************************************************)

(*CacheID: 232*)


(*NotebookFileLineBreakTest
NotebookFileLineBreakTest*)
(*NotebookOptionsPosition[     69401,       1890]*)
(*NotebookOutlinePosition[     73989,       2006]*)
(*  CellTagsIndexPosition[     73758,       1996]*)
(*WindowFrame->Normal*)



Notebook[{
Cell["Trabajar con im\[AAcute]genes", "Title"],

Cell[TextData[StyleBox["F. Javier P\[EAcute]rez Gonz\[AAcute]lez\n\
Departamento de An\[AAcute]lisis Matem\[AAcute]tico\nUniversidad de Granada",
  FontSize->12]], "Author"],

Cell[CellGroupData[{

Cell["Inicializaci\[OAcute]n", "Section"],

Cell["\<\
Los siguientes comandos cargan todos los paquetes gr\[AAcute]ficos y \
establecen opciones por defecto para ListDensityPlot[ ].\
\>", "Text"],

Cell[BoxData[{
    \(\(<< Graphics`;\)\), "\[IndentingNewLine]", 
    \(\(SetOptions[ListDensityPlot, Mesh \[Rule] False, Frame \[Rule] False, 
        AspectRatio \[Rule] Automatic];\)\), "\[IndentingNewLine]", 
    \(\(Off[General::"\<spell1\>"];\)\)}], "Input",
  InitializationCell->True]
}, Closed]],

Cell[CellGroupData[{

Cell["Comandos b\[AAcute]sicos para trabajar con archivos de imagen", \
"Section"],

Cell[TextData[{
  "Una imagen es una funci\[OAcute]n de dos variables definida en una regi\
\[OAcute]n del plano que a cada punto de dicha regi\[OAcute]n asigna un valor \
de brillo o un color. Una imagen digital se obtiene muestreando una regi\
\[OAcute]n del plano y cuantificando los valores de brillo o de color. Para \
ello la regi\[OAcute]n muestreada se divide por medio de una \
cuadr\[IAcute]cula en  peque\[NTilde]os elementos de imagen llamados \
\"pixel\" (picture element). A cada uno de ellos se le asigna un valor de \
brillo o de color. El n\[UAcute]mero de filas y de columnas en que dividimos \
la regi\[OAcute]n muestreada proporciona la resoluci\[OAcute]n de la imagen. \
En las c\[AAcute]maras digitales son frecuentes las resoluciones de 640\
\[Times]480 pixels y de 1024\[Times]768 pixels. Naturalmente, cuanto mayor \
sea la resoluci\[OAcute]n de una imagen mejor se podr\[AAcute]n apreciar los \
detalles espaciales finos.\nEn las im\[AAcute]genes monocrom\[AAcute]ticas a \
cada pixel se le asocia un valor de luminosidad o brillo. En consecuencia una \
imagen monocrom\[AAcute]tica puede ser representada por una matriz ",
  Cell[BoxData[
      \(TraditionalForm\`M\[Times]N\)]],
  " en la que cada entrada es un n\[UAcute]mero que representa un valor de \
luminosidad. En las ",
  StyleBox["im\[AAcute]genes binarias",
    FontSlant->"Italic"],
  " cada pixel est\[AAcute] representado por un bit con los valores 0 (negro) \
o 1 (blanco). En las ",
  StyleBox["im\[AAcute]genes en escala de grises",
    FontSlant->"Italic"],
  " es frecuente representar los pixels por n\[UAcute]meros enteros \
comprendidos entree 0 y 255 que representan valores de luminosidad o brillo; \
dichos n\[UAcute]meros pueden ser eficazmente descritos por 8 d\[IAcute]gitos \
binarios (un byte). En las ",
  StyleBox["im\[AAcute]genes en color ",
    FontSlant->"Italic"],
  "cada pixel lleva asociado al menos tres valores que corresponden a los \
colores rojo, verde y azul."
}], "Text"],

Cell["Empezaremos con un ejemplo muy elemental.", "Text"],

Cell[BoxData[{
    \(\(img = 
        Table[10*k*j, {k, 1, 6}, {j, 1, 4}];\)\), "\[IndentingNewLine]", 
    \(% // MatrixForm\)}], "Input"],

Cell[TextData[{
  "Esta matriz la interpretamos como una imagen. Los valores que aparecen en \
ella corresponden a la luminosidad de cada uno de las ",
  Cell[BoxData[
      \(TraditionalForm\`6\[Times]4 = 24\)]],
  " pixels representados. Valores m\[AAcute]s altos de luminosidad \
corresponden a zonas m\[AAcute]s claras y los m\[AAcute]s bajos a las m\
\[AAcute]s oscuras. El 0 es el color negro y 255 es blanco."
}], "Text"],

Cell["El comando \"ListDensityPlot[MatrizNum\[EAcute]rica, opciones]\"", \
"Theorem"],

Cell[TextData[{
  "En ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " disponemos de varios comandos para representar gr\[AAcute]ficamente \
listas de datos organizadas en una matriz. Uno de ellos es \
ListDensityPlot[MatrizNum\[EAcute]rica, opciones]. Este comando admite \
bastantes opciones."
}], "Text"],

Cell[BoxData[
    \(Options[ListDensityPlot]\)], "Input"],

Cell[BoxData[
    \(\(ListDensityPlot[img, Frame \[Rule] True];\)\)], "Input"],

Cell[TextData[{
  "Observa c\[OAcute]mo",
  StyleBox[" las filas se invierten en la imagen",
    FontWeight->"Bold"],
  ": la fila primera (la m\[AAcute]s oscura) es la que se representa en el \
borde inferior. Las columnas, no obstante, conservan su orden. "
}], "Text"],

Cell["La primitiva gr\[AAcute]fica \"Raster[ListaRectangular, opciones]\"", \
"Theorem"],

Cell[TextData[{
  "Tambi\[EAcute]n disponemos de la primitiva gr\[AAcute]fica bidimensional \
Raster[Lista Rectangular,opciones], que se muestra con Show[Graphics[Raster[ \
] ] ]. \"Lista Rectangular\" puede ser una matriz num\[EAcute]rica o una \
matriz cuyos elementos sean vectores a los que pueda aplicarse una funci\
\[OAcute]n de color. Por defecto, este comando aplica la directiva \
gr\[AAcute]fica GrayLevel[ ] a cada valor de una matriz num\[EAcute]rica y \
representa una malla rectangular de celdas en escala de grises. Como la \
directiva gr\[AAcute]fica GreyLevel[ ] solamente admite valores \
num\[EAcute]ricos comprendidos entre 0 y 1, ",
  StyleBox["Mathematica ",
    FontSlant->"Italic"],
  "por defecto corta los valores que est\[AAcute]n fuera de este rango haci\
\[EAcute]ndolos igual a 0, si son menores que 0, o a 1, si son mayores que 1. \
Por ello, para usar Show[Graphics[Raster[ ] ] ] es obligado situar los \
valores de luminosidad en el intervalo [0,1]. Una forma de hacerlo es dividir \
los valores por el mayor de todos ellos."
}], "Text"],

Cell[BoxData[
    \(\(Show[
        Graphics[Raster[img/Max[img]], Frame \[Rule] True, 
          AspectRatio \[Rule] Automatic]];\)\)], "Input"],

Cell[TextData[{
  "Otra posibilidad es usar las opciones ",
  Cell[BoxData[
      \(TraditionalForm\`Raster[
        ListaRectangular, {{x\_min, y\_min}, {x\_max, y\_max}}, {a\_min, 
          a\_max}]\)]],
  " que indican que la gr\[AAcute]fica debe ocupar el rect\[AAcute]ngulo \
Rectangle[",
  Cell[BoxData[
      \(TraditionalForm\`{{x\_min, y\_min}, {x\_max, y\_max}}\)]],
  "] y deben escalarse los valores de forma que ",
  Cell[BoxData[
      \(TraditionalForm\`a\_min\)]],
  " se corresponda con 0 y ",
  Cell[BoxData[
      \(TraditionalForm\`a\_max\)]],
  " se corresponda con 1."
}], "Text"],

Cell[BoxData[
    \(\(Show[
        Graphics[Raster[img, {{0, 0}, {4, 6}}, {Min[img], Max[img]}], 
          Frame \[Rule] True, AspectRatio \[Rule] Automatic]];\)\)], "Input"],

Cell[TextData[{
  "Con ",
  Cell[BoxData[
      \(TraditionalForm\`Raster[ListaRectangular, opciones, 
        ColorFunction \[Rule] f]\)]],
  " podemos aplicar la funci\[OAcute]n de color ",
  StyleBox["f",
    FontSlant->"Italic"],
  " a los valores de \"Lista Rectangular\" que representan cada celda. Aqu\
\[IAcute] tienes un ejemplo."
}], "Text"],

Cell[BoxData[
    \(\(Show[
        Graphics[Raster[img/Max[img], ColorFunction \[Rule] Hue], 
          Frame \[Rule] True, AspectRatio \[Rule] Automatic]];\)\)], "Input"],

Cell[TextData[{
  "En el siguiente ejemplo representamos una imagen en color usando la funci\
\[OAcute]n \"RGBColor\". Observa que cada celda o pixel tiene ahora tres \
datos comprendidos entre 0 y 1 que corresponden a los valores de rojo, verde \
y azul respectivamente (suponemos que se usa el ",
  StyleBox["modelo de color",
    FontSlant->"Italic"],
  " RGB)."
}], "Text"],

Cell[BoxData[{
    \(Clear[img]\), "\[IndentingNewLine]", 
    \(\(img = 
        Table[{Random[], Random[], Random[]}, {i, 6}, {j, 
            4}];\)\), "\[IndentingNewLine]", 
    \(\(Show[
        Graphics[Raster[img, ColorFunction \[Rule] RGBColor], 
          AspectRatio \[Rule] Automatic, Frame \[Rule] True]];\)\)}], "Input"],

Cell["\<\
Al igual que antes, dependiendo de c\[OAcute]mo sean los datos puede ser \
necesario ajustarlos.\
\>", "Text"],

Cell[BoxData[{
    \(Clear[img]\), "\[IndentingNewLine]", 
    \(\(img = 
        Table[{Random[Integer, {1, 255}], Random[Integer, {1, 255}], 
            Random[Integer, {1, 255}]}, {i, 6}, {j, 
            4}];\)\), "\[IndentingNewLine]", 
    \(\(Show[
        Graphics[Raster[img/Max[img], ColorFunction \[Rule] RGBColor], 
          AspectRatio \[Rule] Automatic, Frame \[Rule] True]];\)\)}], "Input"],

Cell["\<\
Los comandos Import[\"archivo.ext\",opciones ] y \
Export[\"archivo\",expresion,formato]\
\>", "Theorem"],

Cell[TextData[{
  "El comando Import[\"archivo.ext\"] importa datos de un archivo cuyo \
formato se supone que corresponde al indicado por la extensi\[OAcute]n \
\"ext\" y los convierte en una expresi\[OAcute]n de ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  ". Este comando trabaja con archivos de datos, de im\[AAcute]genes y \
sonidos. Antes de usarlo es conveniente establecer nuestro directorio de \
trabajo (que t\[UAcute] deber\[AAcute]s modificar de forma apropiada). "
}], "Text"],

Cell[BoxData[
    \(\(SetDirectory["\<D:/Trabajo/02_Docencia \
Informatica/Ingenieria_Informatica/Curso2006_2007/Calculo \
Avanzado/practicas/06_imagenes/\>"];\)\)], "Input"],

Cell["\<\
Ahora podemos importar directamente cualquier imagen que est\[EAcute] en \
dicho directorio.\
\>", "Text"],

Cell[BoxData[
    \(\(lena = Import["\<lena.jpg\>"];\)\)], "Input"],

Cell["\<\
Casi siempre que usamos Import[ ] con un archivo de imagen obtenemos un \
objeto gr\[AAcute]fico de la forma Graphics[Raster[ ]].\
\>", "Text"],

Cell[BoxData[
    \(InputForm[lena] // Shallow\)], "Input"],

Cell["\<\
Esas reglas (Rule[ ])  que no vemos especifican determinadas opciones. De \
hecho, podemos verlas.\
\>", "Text"],

Cell[BoxData[
    \(\(\(Position[lena, Rule]\[IndentingNewLine]
    lena[\([2]\)]\  (*\ 
      especifica\ la\ opci\[OAcute]n\ ImageSize\ *) \[IndentingNewLine]
    lena[\([3]\)] (*\ 
      especifica\ la\ opci\[OAcute]n\ PlotRange\ *) \[IndentingNewLine]
    lena[\([4]\)]\  (*\ 
      especifica\ la\ opci\[OAcute]n\ AspectRatio\ *) \[IndentingNewLine]
    lena[\([1, 4]\)]\  (*\ 
      especifica\ la\ funci\[OAcute]n\ de\ color\ *) \[IndentingNewLine]
    lena[\([1, 2]\)] (*\ 
      especifica\ los\ v\[EAcute]rtices\ inferior\ y\ superior\ del\ rect\
\[AAcute]ngulo\ donde\ se\ representa\ la\ imagen\ *) \[IndentingNewLine]
    lena[\([1, 3]\)]\)\(\ \)\( (*\ 
      especifica\ la\ regla\ de\ escalado\ a\ grises\ 0 \[Rule] 0, \ 
      255 \[Rule] 1\ *) \)\)\)], "Input"],

Cell[TextData[{
  "Los datos que constituyen esta imagen est\[AAcute]n en lena[[1,1]]. Se \
trata de un archivo grande y debes evitar que ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " lo escriba en pantalla."
}], "Text"],

Cell[BoxData[
    \(\(\(\(lenadat = lena[\([1, 1]\)];\)\[IndentingNewLine]
    Dimensions[lenadat]\)\( (*\ 
      es\ una\ matriz\ de\ 256\ filas\ y\ 256\ columnas\ *) \)\)\)], "Input"],

Cell[TextData[{
  StyleBox["El n\[UAcute]mero de filas indica el alto de la imagen y el n\
\[UAcute]mero de columnas indica el ancho de la imagen",
    FontWeight->"Bold"],
  " medidos en pixels. Los valores de la matriz son n\[UAcute]meros enteros \
comprendidos entre 0 y 255. "
}], "Text"],

Cell[BoxData[
    \({{Min[lenadat], Max[lenadat]}, Head[lenadat[\([7, 19]\)]]}\)], "Input"],

Cell["Podemos mostrar \"lena\" de la forma usual.", "Text"],

Cell[BoxData[
    \(\(Show[lena, ImageSize \[Rule]  .7*{256, 256}];\)\)], "Input"],

Cell["\<\
Tambi\[EAcute]n podemos representar la imagen con ListDensityPlot[ ] como \
sigue.\
\>", "Text"],

Cell[BoxData[
    \(\(ListDensityPlot[lenadat, 
        ImageSize \[Rule]  .7*{256, 256}];\)\)], "Input"],

Cell["El siguiente comando representa l\[IAcute]neas de contorno.", "Text"],

Cell[BoxData[
    \(\(ListContourPlot[lenadat, ContourShading \[Rule] False, 
        Contours \[Rule] 4, Frame \[Rule] False, 
        ImageSize \[Rule]  .7*{256, 256}];\)\)], "Input"],

Cell[TextData[{
  "El comando Export[\"file.ext\",expresion] exporta datos a un archivo y los \
convierte a un formato correspondiente a la extensi\[OAcute]n del archivo \
\"ext\". Con este comando podemos exportar datos, im\[AAcute]genes o sonidos \
en una gran variedad de formatos. Algunos formatos tienen ",
  StyleBox["opciones de conversi\[OAcute]n",
    FontSlant->"Italic"],
  " espec\[IAcute]ficas que se explican en la ayuda del programa."
}], "Text"],

Cell[BoxData[
    \(\(\(Export["\<malena.tif\>", lena];\)\( (*\ 
      al\ ejecutar\ este\ comando\ se\ guarda\ el\ archivo\ en\ formato\ \
"\<tif\>"\ *) \)\)\)], "Input"],

Cell[CellGroupData[{

Cell["Seleccionar parte de una imagen", "Subsection"],

Cell[BoxData[
    \(\(Show[lena, ImageSize \[Rule]  .7*{256, 256}];\)\)], "Input"],

Cell["\<\
Para seleccionar una parte de esta imagen, por ejemplo la cara, seleccionamos \
la imagen con el rat\[OAcute]n y seguidamente mantenemos apretada la tecla \
Control. El rat\[OAcute]n se convertir\[AAcute] en una cruz. Situamos la cruz \
en el v\[EAcute]rtice inferior del trozo de imagen que queremos seleccionar y \
hacemos clic en \[EAcute]l. Seguidamente situamos la cruz en el \
v\[EAcute]rtice superior del trozo de imagen que queremos seleccionar y \
hacemos clic en \[EAcute]l. A continuaci\[OAcute]n hacemos clic en el bot\
\[OAcute]n derecho del rat\[OAcute]n y seleccionamos copiar. De esta forma \
hemos copiado en el portapapeles las coordenadas de los dos puntos \
seleccionados. Las pegamos en una celda de Imput. Ten en cuenta que las \
coordenadas obtenidas son de la forma {n\.bacolumna,n\.bafila}. Ahora les \
aplicamos los comandos Round[ ], Transpose[ ] y Reverse[ ] como sigue.\
\>", "Text"],

Cell[BoxData[
    \(\(\({{106.632, 64.407}, {188.616, 163.538}} // Round\) // Transpose\) // 
      Reverse\)], "Input"],

Cell["\<\
Esto nos dice que debemos seleccionar la submatriz formada por las filas de \
la 64 a la 164 y las columnas de la 107 a la 189. Esto se hace con el comando \
Take[ ].\
\>", "Text"],

Cell[BoxData[
    \(cara = Take[lenadat, {64, 164}, {107, 189}]; 
    ListDensityPlot[cara, ImageSize \[Rule]  .7*{83, 101}];\)], "Input"],

Cell["Vamos a trabajar ahora con una imagen en color.", "Text"],

Cell[BoxData[
    \(\(durero = Import["\<durero.jpg\>"];\)\)], "Input"],

Cell["Los datos num\[EAcute]ricos de \"durero\" est\[AAcute]n en \
durero[[1,1]].", "Text"],

Cell[BoxData[
    \(\(\(\(durerodat = durero[\([1, 1]\)];\)\[IndentingNewLine]
    Dimensions[durerodat]\[IndentingNewLine]
    durerodat[\([7, 5]\)]\)\( (*\ 
      el\ elemento\ que\ ocupa\ la\ fila\ 7\ columna\ 5\ *) \)\)\)], "Input"],

Cell[TextData[{
  "Observa que las dimensiones indican que durero[[1,1]] es una matriz de 347 \
filas y 251 columnas ",
  StyleBox["cuyos elementos son vectores de 3 elementos que corresponden a \
los datos de rojo, verde y azul que representan cada pixel",
    FontSlant->"Italic"],
  ". Veamos con m\[AAcute]s detalle la estructura de \"durero\"."
}], "Text"],

Cell[BoxData[
    \(\(\(InputForm[durero] // Shallow\[IndentingNewLine]
    Position[durero, Rule]\[IndentingNewLine]
    durero[\([1, 4]\)] (*\ 
      la\ funci\[OAcute]n\ de\ color\ que\ se\ usar\[AAcute]\ \
*) \[IndentingNewLine]
    durero[\([1, 3]\)]\  (*\ 
      especifica\ la\ regla\ de\ escalado\ a\ grises\ 0 \[Rule] 0, \ 
      255 \[Rule] 1\ *) \[IndentingNewLine]
    durero[\([1, 2]\)]\  (*\ 
      rect\[AAcute]ngulo\ donde\ se\ representar\[AAcute]\ la\ imagen\ \
*) \[IndentingNewLine]
    durero[\([2]\)] (*\ 
      tama\[NTilde]o\ de\ la\ imagen\ 251\[Times]347\ *) \[IndentingNewLine]
    durero[\([3]\)] (*\ 
      especifica\ la\ opci\[OAcute]n\ PlotRange\ *) \[IndentingNewLine]
    durero[\([4]\)]\)\( (*\ 
      especifica\ la\ opci\[OAcute]n\ AspectRatio\ *) \)\)\)], "Input"],

Cell[BoxData[
    \(\(Show[durero, ImageSize \[Rule]  .7*{251, 347}];\)\)], "Input"],

Cell["\<\
El siguiente comando hace una media podenrada de los valores de rojo, verde y \
azul y puede aplicarse a una imagen en color para convertirla a escala de \
grises.\
\>", "Text"],

Cell[BoxData[
    \(\(toGray[{r_, g_, b_}] := {r, g, b} . {0.3, 0.59, 0.11};\)\)], "Input"],

Cell["Pasamos a escala de grises el autorretrato de Durero.", "Text"],

Cell[BoxData[
    \(\(\(\(durerogris = Map[toGray, durerodat, {2}];\)\[IndentingNewLine]
    Dimensions[durerogris]\)\( (*\ 
      es\ una\ matriz\ de\ 347\ filas\ y\ 251\ columnas\ *) \)\)\)], "Input"],

Cell["Podemos representar esta imagen con ListDensityPlot[ ].", "Text"],

Cell[BoxData[
    \(\(ListDensityPlot[durerogris, 
        ImageSize \[Rule] 0.7*{251, 347}];\)\)], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Histogramas", "Subsection"],

Cell["\<\
Los siguientes comandos sirven (entre otras cosas) para obtener el histograma \
de una imagen monocrom\[AAcute]tica (n\[UAcute]mero de veces que se repite \
cada valor de luminosidad entre 0 y 255) y para representarlo \
gr\[AAcute]ficamente.\
\>", "Text"],

Cell[BoxData[{
    \(\(Codifica[x_List] := \({First[#], Length[#]} &\) /@ 
          Split[Sort[x]];\)\), "\[IndentingNewLine]", 
    \(\(Histograma[img_List] := 
        Module[{temp, lista}, 
          lista = Flatten[img]; \[IndentingNewLine]temp = 
            Codifica[lista]; \[IndentingNewLine]faltan = 
            Complement[Range[0, 255], 
              temp[\([All, 1]\)]]; \[IndentingNewLine]If[
            Length[faltan] > 
              0, \(Sort[
                Join[temp, 
                  Transpose[{faltan, Table[0, {Length[faltan]}]}]]]\)[\([All, 
                2]\)], temp[\([All, 2]\)]]];\)\), "\[IndentingNewLine]", 
    \(HistogramaPlot[histo_, opts___] := 
      Module[{puntos, segmentos}, puntos = Transpose[{Range[0, 255], histo}]; 
        segmentos = 
          puntos /. {x_?NumberQ, 
                y_?NumberQ} \[RuleDelayed] \ {{x, 0}, {x, 
                  y}}; \[IndentingNewLine]Show[
          Graphics[{{Hue[ .65], Thickness[ .001], 
                Map[Line, segmentos]}, {Hue[0], PointSize[ .007], 
                Map[Point, puntos]}}, Axes \[Rule] True, 
            opts]]\[IndentingNewLine]]\)}], "Input",
  CellTags->"Split"],

Cell["\<\
El comando Histograma[L], donde suponemos que L es una lista o una matriz \
cuyos elementos son n\[UAcute]meros enteros del 0 al 255,  proporciona como \
salida una lista con 256 elementos en la que el elemento que ocupa el lugar \
k-\[EAcute]simo es el n\[UAcute]mero de veces que el valor k-1 aparece en L. \
\
\>", "Text"],

Cell[BoxData[
    \(histolena = Histograma[lenadat]\)], "Input"],

Cell[BoxData[
    \(\(HistogramaPlot[histolena];\)\)], "Input"],

Cell["\<\
Para representar el histograma de \"durerogris\" hay que redondear los datos \
de esta matriz al valor entero m\[AAcute]s pr\[OAcute]ximo.\
\>", "Text"],

Cell[BoxData[
    \(\(HistogramaPlot[Histograma[Round[durerogris]]];\)\)], "Input"],

Cell["\<\
Podemos hacer los histogramas de rojos, verdes y azules de \"durero\" y \
representarlos juntos gr\[AAcute]ficamente como sigue.\
\>", "Text"],

Cell[BoxData[{
    \(histodurerored = 
      Histograma[
        durerodat\[LeftDoubleBracket]All, All, 1\[RightDoubleBracket]]; 
    histodurerogreen = 
      Histograma[
        durerodat\[LeftDoubleBracket]All, All, 2\[RightDoubleBracket]]; 
    histodureroblue = 
      Histograma[
        durerodat\[LeftDoubleBracket]All, All, 
          3\[RightDoubleBracket]];\), "\[IndentingNewLine]", 
    \(\(DisplayTogetherArray[{ListPlot[histodurerored, 
            PlotStyle \[Rule] RGBColor[1, 0, 0]], 
          ListPlot[histodurerogreen, PlotStyle \[Rule] RGBColor[0, 1, 0]], 
          ListPlot[histodureroblue, PlotStyle \[Rule] RGBColor[0, 0, 1]]}, 
        ImageSize \[Rule] {2*288, 178}];\)\)}], "Input"],

Cell[BoxData[
    \(Clear["\<@\>"]\)], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Ajuste del rango din\[AAcute]mico de una imagen", "Subsection"],

Cell["\<\
El intervalo de valores de brillo de una imagen suele llamarse rango din\
\[AAcute]mico de la imagen. En principio, cuanto mayor sea el rango din\
\[AAcute]mico m\[AAcute]s tonalidades pueden ser representadas, aunque si hay \
una gran concentraci\[OAcute]n de los valores en los extremos del rango din\
\[AAcute]mico esto da lugar a un excesivo contraste que puede ocultar los \
matices. El contraste de una imagen mide la separaci\[OAcute]n entre las \
distintas tonalidades de gris. Interesa que el contraste entre los distintos \
niveles de gris sea suficientemente grande para que puedan apreciarse los \
detalles de la imagen. 
El siguiente comando permite ajustar de forma lineal el rango \
din\[AAcute]mico de una imagen en un intervalo [a,b]. Por defecto tomamos \
a=0, b=255.\
\>", "Text"],

Cell[BoxData[
    \(\(ranGo[img_, a_:  0, b_:  255] := 
        a + \((b - a)\) \((img - Min[img])\)/\((Max[img] - Min[img])\) // 
          N;\)\)], "Input"],

Cell["Observa la siguiente imagen.", "Text"],

Cell[BoxData[{
    \(\(mujer = Import["\<mujer.jpg\>"];\)\), "\[IndentingNewLine]", 
    \(\(imag1 = Show[mujer, ImageSize \[Rule]  .65*{256, 256}];\)\)}], "Input"],

Cell["\<\
Es claro que esta imagen tiene muy poco contraste y que todos sus valores de \
luminosidad est\[AAcute]n concentrados en un peque\[NTilde]o intervalo, su \
rango din\[AAcute]mico es muy peque\[NTilde]o. Podemos comprobarlo \
representando su histograma.\
\>", "Text"],

Cell[BoxData[{
    \(\(mujerdat = mujer[\([1, 1]\)];\)\), "\[IndentingNewLine]", 
    \(\(HistogramaPlot[Histograma[mujerdat], 
        PlotRange \[Rule] {0, 3000}];\)\), "\[IndentingNewLine]", 
    \({Min[mujerdat], Max[mujerdat]}\)}], "Input"],

Cell["\<\
El histograma nos dice que los valores est\[AAcute]n concentrados en el \
intervalo [51,139] en torno al valor 100. Podemos intentar mejorar esta \
imagen ajustando su rango din\[AAcute]mico al intervalo [0,255].\
\>", "Text"],

Cell[BoxData[
    \(\(carita = ranGo[mujerdat];\)\)], "Input"],

Cell[BoxData[
    \(\(imag2 = 
        ListDensityPlot[carita, 
          ImageSize \[Rule]  .65*{256, 256}];\)\)], "Input"],

Cell["\<\
Representemos el nuevo histograma. Observa que debemos redondear a valores \
enteros los nuevos valores de brillo.\
\>", "Text"],

Cell[BoxData[
    \(\(HistogramaPlot[Histograma[Round[carita]], 
        PlotRange \[Rule] {0, 3000}];\)\)], "Input"],

Cell["\<\
Efectivamente, el rango din\[AAcute]mico de la imagen se ha incrementado \
notablemente. Lo que, en este caso, se traduce en un mayor contraste y en una \
gama mayor de tonalidades de gris.\
\>", "Text"],

Cell[TextData[{
  "Aparte de ampliar el rango din\[AAcute]mico, hay otras operaciones t\
\[IAcute]picas para aumentar el contraste que consisten en aplicar \
determinadas funciones a los valores de luminosidad. Las m\[AAcute]s usadas \
son ",
  Cell[BoxData[
      \(TraditionalForm\`\(\(f \((x)\) = x\^2\)\(,\)\)\)]],
  " ",
  Cell[BoxData[
      \(TraditionalForm\`f \((x)\) = x\^3\)]],
  ", ",
  Cell[BoxData[
      \(TraditionalForm\`f(x) = \@x\)]],
  ", ",
  Cell[BoxData[
      \(TraditionalForm\`f(x) = \@x\%3\)]],
  " pero t\[UAcute] puedes probar otras. Aqu\[IAcute] puedes ver unos \
ejemplos."
}], "Text"],

Cell[BoxData[
    \(\(DisplayTogetherArray[{ListDensityPlot[carita^2], 
          ListDensityPlot[Log[1.  + carita^3]], 
          imag3 = ListDensityPlot[\((carita)\)^\((3/2)\)]}, 
        ImageSize \[Rule]  .65*{768, 256}];\)\)], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Ecualizaci\[OAcute]n de una imagen", "Subsection"],

Cell["\<\
Ecualizar una imagen es convertirla en otra cuyo histograma sea horizontal, \
es decir, en la que todas las tonalidades de gris tengan el mismo \
n\[UAcute]mero de p\[IAcute]xeles. En la pr\[AAcute]ctica, esto puede \
lograrse de forma aproximada. Para ello precisamos el histograma de densidad \
y el histograma acumulativo.\
\>", "Text"],

Cell[BoxData[{
    \(HistoDensidad[img_List] := 
      N[Histograma[img]/Total[Histograma[img]]]\), "\[IndentingNewLine]", 
    \(\(HistoAcumulativo[img_List] := 
        FoldList[Plus, First[HistoDensidad[img]], 
          Rest[HistoDensidad[img]]];\)\)}], "Input"],

Cell["\<\
Observa que la salida de ambos comandos es una lista de 256 elementos. El \
histograma de densidad representa las frecuencias relativas de los distintos \
valores de luminosidad de la imagen. Puede interpretarse como una funci\
\[OAcute]n de probalidad. El elemento k-\[EAcute]simo del histograma de \
densidad es la probabilidad de que el valor de brillo de un pixel de la \
imagen sea igual a k-1. El histograma acumulativo puede interpretarse como la \
funci\[OAcute]n de distribuci\[OAcute]n correspondiente, el elemento k-\
\[EAcute]simo del histograma acumulativo es la probabilidad de que el valor \
de brillo de un pixel de la imagen sea menor o igual que k-1.\
\>", "Text"],

Cell[BoxData[
    \(\(HistogramaPlot[HistoAcumulativo[mujerdat]];\)\)], "Input"],

Cell["\<\
Podemos obtener una funci\[OAcute]n que interpola los valores del histograma \
acumulativo.\
\>", "Text"],

Cell[BoxData[{
    \(\(f = 
        ListInterpolation[
          HistoAcumulativo[
            mujerdat], {{0, 255}}];\)\), "\[IndentingNewLine]", 
    \(\(Plot[f[x], {x, 0, 255}];\)\)}], "Input"],

Cell["\<\
Ahora hacemos actuar esta funci\[OAcute]n sobre los valores de la imagen. \
Como esta funci\[OAcute]n tiene una gran pendiente vamos a logar aumentar la \
separaci\[OAcute]n entre niveles pr\[OAcute]ximos de gris en el rango \
[51,139]. Observa que todos los datos de la imagen obtenida estar\[AAcute]n \
en el intervalo [0,1].\
\>", "Text"],

Cell[BoxData[
    \(\(equmujer = Map[f, mujerdat, {2}];\)\)], "Input"],

Cell[BoxData[
    \(\(ListDensityPlot[equmujer, 
        ImageSize \[Rule]  .65*{256, 256}];\)\)], "Input"],

Cell["\<\
Hemos conseguido un mayor contraste pero la imagen obtenida parece muy \
artificial. Podemos intentar reducir el rango din\[AAcute]mico para no \
incrementar tanto el contraste. Para ello podemos seleccionar una parte de la \
imagen con una gama de grises apropiada (la cara de la chica). Y usamos su \
histograma acumulativo para construir una funci\[OAcute]n de interpolaci\
\[OAcute]n que despu\[EAcute]s aplicaremos a la totalidad de la imagen.\
\>", "Text"],

Cell[BoxData[{
    \(\(cara = 
        Take[mujerdat, {55, 187}, {63, 228}];\)\), "\[IndentingNewLine]", 
    \(\(ListDensityPlot[cara, 
        ImageSize \[Rule]  .65*{228 - 62, 187 - 54}];\)\)}], "Input"],

Cell[BoxData[{
    \(\(h = 
        ListInterpolation[HistoAcumulativo[cara], {{0, 255}}];\)\), "\n", 
    \(\(equmujercara = Map[h, mujerdat, {2}];\)\), "\[IndentingNewLine]", 
    \(\(imag4 = 
        ListDensityPlot[equmujercara, 
          ImageSize \[Rule]  .65*{256, 256}];\)\)}], "Input"],

Cell["\<\
De las im\[AAcute]genes obtenidas, \[EAcute]sta parece la mejor. Podemos \
verlas juntas.\
\>", "Text"],

Cell[BoxData[
    \(\(DisplayTogetherArray[{imag1, imag2, imag3, imag4}, 
        ImageSize \[Rule]  .5*{4*256, 256}];\)\)], "Input"],

Cell["\[DownQuestion]Y si combinamos las tres mejores?", "Text"],

Cell[BoxData[
    \(\(ListDensityPlot[
        0.433*imag2[\([1]\)] + 0.233*imag3[\([1]\)] + 0.333*imag4[\([1]\)], 
        ImageSize ->  .65*{256, 256}];\)\)], "Input"],

Cell[BoxData[
    \(Clear["\<@\>"]\)], "Input"]
}, Open  ]]
}, Open  ]],

Cell[CellGroupData[{

Cell["Filtrado digital de im\[AAcute]genes", "Section"],

Cell[TextData[{
  "Algunas de las operaciones m\[AAcute]s usuales que se realizan sobre im\
\[AAcute]genes como, por ejemplo, el suavizado para eliminar peque\[NTilde]as \
imperfecciones o la detecci\[OAcute]n de bordes o de l\[IAcute]neas de \
contorno para aumentar la definici\[OAcute]n de la imagen, pueden realizarse \
en el dominio espacial o en el dominio de la frecuencia. En el primer caso, \
la operaci\[OAcute]n matem\[AAcute]tica necesaria es una convoluci\[OAcute]n \
con un determinado ",
  StyleBox["n\[UAcute]cleo",
    FontSlant->"Italic"],
  ", mientras que en el segundo se requiere transformar la imagen, por medio \
de la Transformada de Fourier Discreta, al dominio de la frecuencia, \
multiplicar por un conveniente ",
  StyleBox["filtro de frecuencia",
    FontSlant->"Italic"],
  " y recuperar el resultado obtenido en el dominio espacial por medio de una \
DFT inversa."
}], "Text"],

Cell[CellGroupData[{

Cell["Filtrado en el dominio espacial", "Subsection"],

Cell[TextData[{
  "Representemos nuestra imagen por ",
  Cell[BoxData[
      \(TraditionalForm\`F = \((f(p, q))\)\_\(M\[Times]N\)\)]],
  ". Sea ",
  Cell[BoxData[
      \(TraditionalForm\`H = \((h(i, j))\)\_\(m\[Times]n\)\)]],
  " una matriz ",
  Cell[BoxData[
      \(TraditionalForm\`m\[Times]n\)]],
  " (el n\[UAcute]cleo de convoluci\[OAcute]n) cuyas caracter\[IAcute]sticas \
depender\[AAcute]n del resultado que queramos lograr en cada caso. Se supone, \
claro est\[AAcute], que las dimensiones de ",
  StyleBox["H",
    FontSlant->"Italic"],
  " son mucho m\[AAcute]s peque\[NTilde]as que las de ",
  StyleBox["F. ",
    FontSlant->"Italic"],
  "En la pr\[AAcute]ctica es ",
  Cell[BoxData[
      \(TraditionalForm\`m = \(n = 3\)\)]],
  ", 5, 7 o 9. Hay distintas implementaciones de la convoluci\[OAcute]n. En \
",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  ", la convoluci\[OAcute]n de dos matrices ",
  StyleBox["H ",
    FontSlant->"Italic"],
  "(el n\[UAcute]cleo)",
  StyleBox[" ",
    FontSlant->"Italic"],
  "y ",
  StyleBox["F",
    FontSlant->"Italic"],
  " se hace con el comando ListConvolve[",
  StyleBox["H,F",
    FontSlant->"Italic"],
  "] que proporciona como salida una matriz ",
  Cell[BoxData[
      \(TraditionalForm\`\(\(\ \)\(G = \((g(p, q))\)\_\(\((M - m + 1)\)\
\[Times]\((N - n + 1)\)\)\)\)\)]],
  " cuyos elementos se calculan como sigue.\n1 ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " revierte cada una de las filas de la matriz ",
  StyleBox["H",
    FontSlant->"Italic"],
  " y revierte las filas entre si. Seguiremos llamando ",
  StyleBox["H ",
    FontSlant->"Italic"],
  "al n\[UAcute]cleo de convoluci\[OAcute]n despu\[EAcute]s de realizada esta \
operaci\[OAcute]n. En la pr\[AAcute]ctica suelen usarse n\[UAcute]cleos de \
convoluci\[OAcute]n que permanecen invariantes por esta operaci\[OAcute]n. \n\
2 Tomamos las primeras m filas de ",
  StyleBox["F ",
    FontSlant->"Italic"],
  "y con ellas formamos matrices de orden m\[Times]n tomando sucesivamente \
bloques de n columnas ",
  StyleBox["consecutivas",
    FontSlant->"Italic"],
  " empezando por la primera columna hasta llegar a la columna j=N-n+1. \
Tendremos en total N-n+1 matrices de tama\[NTilde]o m\[Times]n. Cada una de \
ellas se multiplica ",
  StyleBox["elemento a elemento",
    FontSlant->"Italic"],
  " por ",
  StyleBox["H y se suman todos estos productos",
    FontSlant->"Italic"],
  ". De esta forma obtenemos la ",
  StyleBox["primera",
    FontSlant->"Italic"],
  " fila de la matriz ",
  StyleBox["G.",
    FontSlant->"Italic"],
  "\n3 El proceso descrito en el punto 2 se repite ahora con cada bloque de m \
filas ",
  StyleBox["consecutivas",
    FontSlant->"Italic"],
  " de ",
  StyleBox["F",
    FontSlant->"Italic"],
  " formado por las filas que van desde la fila i hasta la m+i-1 hasta llegar \
a la fila i=M-m+1."
}], "Text"],

Cell[TextData[{
  "Para el caso en que ",
  Cell[BoxData[
      \(TraditionalForm\`m = \(\(n\)\(=\)\(3\)\(\ \)\)\)]],
  " y ",
  StyleBox["suponiendo que la matriz",
    FontSlant->"Italic"],
  " ",
  StyleBox["H tiene las propiedades de simetr\[IAcute]a indicadas",
    FontSlant->"Italic"],
  ", el proceso descrito puede visualizarse como sigue. Se multiplican \
elemento a elemento las matrices"
}], "Text"],

Cell[BoxData[
    RowBox[{
      StyleBox[
        RowBox[{"(", GridBox[{
              {\(h \((1, 1)\)\), \(h \((1, 2)\)\), \(h \((1, 3)\)\)},
              {\(h \((2, 1)\)\), \(h \((2, 2)\)\), \(h \((2, 3)\)\)},
              {\(h \((3, 1)\)\), \(h \((3, 2)\)\), \(h \((3, 3)\)\)}
              },
            RowLines->True,
            ColumnLines->True], ")"}],
        FontFamily->"Times New Roman"], 
      StyleBox["   ",
        FontFamily->"Times New Roman"], 
      StyleBox["y",
        FontFamily->"Times New Roman"], 
      StyleBox["  ",
        FontFamily->"Times New Roman"], 
      StyleBox[
        RowBox[{"(", GridBox[{
              {\(f \((p - 1, q - 1)\)\), \(f \((p - 1, q)\)\), \(f \((p - 1, 
                    q + 1)\)\)},
              {\(f \((p, q - 1)\)\), \(f \((p, q)\)\), \(f \((p, q + 1)\)\)},
              {\(f \((p + 1, q - 1)\)\), \(f \((p + 1, q)\)\), \(f \((p + 1, 
                    q + 1)\)\)}
              },
            RowLines->True,
            ColumnLines->True], ")"}],
        FontFamily->"Times New Roman"]}]], "Text",
  TextAlignment->Center],

Cell["obtenemos as\[IAcute] la matriz", "Text"],

Cell[TextData[Cell[BoxData[
    RowBox[{"(", GridBox[{
          {\(h \((1, 1)\) f \((p - 1, q - 1)\)\), \(h \((1, 2)\) 
              f \((p - 1, q)\)\), \(h \((1, 3)\) f \((p - 1, q + 1)\)\)},
          {\(h \((2, 1)\) f \((p, q - 1)\)\), \(h \((2, 2)\) 
              f \((p, q)\)\), \(h \((2, 3)\) f \((p, q + 1)\)\)},
          {\(h \((3, 1)\) f \((p + 1, q - 1)\)\), \(h \((3, 2)\) 
              f \((p + 1, q)\)\), \(h \((3, 3)\) f \((p + 1, q + 1)\)\)}
          },
        RowLines->True,
        ColumnLines->True], ")"}]],
  FontFamily->"Times New Roman"]], "Text",
  TextAlignment->Center],

Cell[TextData[{
  "y sumamos sus elementos para obtener el elemento ",
  Cell[BoxData[
      \(TraditionalForm\`g(p - 1, q - 1)\)]],
  " de la matriz ",
  StyleBox["G",
    FontSlant->"Italic"],
  ". Y ese proceso se repite para todos los valores ",
  Cell[BoxData[
      \(TraditionalForm\`\(\(2 \[LessEqual] p \[LessEqual] 
        M - 1\)\(,\)\)\)]],
  " y ",
  Cell[BoxData[
      \(TraditionalForm\`2 \[LessEqual] \ q \[LessEqual] \ N - 1\)]],
  ". "
}], "Text"],

Cell[" El siguiente comando realiza las operaciones indicadas. ", "Text"],

Cell[BoxData[
    \(convoluciona[x_?MatrixQ, z_?MatrixQ] := 
      Module[{m, n, p, q, lista, temp, M, sumamatriz, prod}, 
        sumamatriz[u_?MatrixQ] := 
          Total[Flatten[u]]; \[IndentingNewLine]{m, n} = 
          Dimensions[x]; \[IndentingNewLine]{p, q} = 
          Dimensions[z]; \[IndentingNewLine]lista = 
          Partition[z, {m, n}, {1, 1}];  (*\ 
          dividimos\ la\ matriz\ z\ en\ submatrices\ con\ igual\ dimensi\
\[OAcute]n\ que\ la\ matriz\ x\ *) \[IndentingNewLine]M = 
          Reverse[Map[Reverse, x]];  (*\ 
          revertimos\ cada\ fila\ y\ revertimos\ las\ filas\ entre\ \
s\[IAcute]\ *) \[IndentingNewLine]prod[v_?MatrixQ, w_List] := 
          Module[{a = \((Dimensions[w])\)[\([1]\)], 
              b = \((Dimensions[w])\)[\([2]\)]}, 
            Table[v*w[\([j, k]\)], {j, a}, {k, b}]];  (*\ 
          w\ debe\ ser\ una\ matriz\ cuyos\ elementos\ sean\ matrices\ de\ \
iguales\ dimensiones\ que\ v\ y\ lo\ que\ hace\ el\ comando\ es\ multiplicar\ \
como\ listas, \ elemento\ a\ elemento, \ 
          la\ matriz\ v\ por\ todos\ los\ elementos\ de\ w\ \
*) \[IndentingNewLine]temp = prod[M, lista];  (*\ 
          multiplicamos\ por\ M\  - \ elemento\ a\ elemento\  - \ 
            todas\ las\ submatrices\ creadas\ en\ z\ y\ sumamos\ todos\ los\ \
elementos\ de\ cada\ matriz\ obtenida\ *) \[IndentingNewLine]MapAt[
          sumamatriz, temp, 
          Flatten[Table[{i, j}, {i, p - m + 1}, {j, q - n + 1}], 
            1]]]\)], "Input"],

Cell["Podemos comprobarlo con ListConvolve[ ].", "Text"],

Cell[BoxData[{
    \(\(c = Random[Integer, {1, 20}];\)\), "\[IndentingNewLine]", 
    \(\(d = Random[Integer, {1, 20}];\)\), "\[IndentingNewLine]", 
    \(\(a = Table[Random[], {i, c}, {j, d}];\)\), "\[IndentingNewLine]", 
    \(\(b = 
        Table[Random[], {i, 10 + c}, {j, 
            10 + d}];\)\), "\[IndentingNewLine]", 
    \(convoluciona[a, b] == ListConvolve[a, b]\), "\[IndentingNewLine]", 
    \(Clear["\<@\>"]\)}], "Input"],

Cell["\<\
Naturalmente, ListConvolve[ ] es extraordinariamente m\[AAcute]s \
r\[AAcute]pido que cualquier comando que podamos definir nosotros porque usa \
la Transformada de Fourier Discreta.\
\>", "Text"],

Cell["\<\
Para realizar algunas operaciones espec\[IAcute]ficas se han definido varios \
n\[UAcute]cleos est\[AAcute]ndar. Los m\[AAcute]s importantes son los \
siguientes.\
\>", "Text"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Filtrado en media", "Subsection"],

Cell["\<\
Se trata de filtros que sustituyen cada pixel por el valor promedio de los p\
\[IAcute]xeles que le rodean inclu\[IAcute]do el propio p\[IAcute]xel. De \
esta forma se suaviza la imagen y se aten\[UAcute]an algunas imperfecciones \
que pueda tener. Los siguentes n\[UAcute]cleos realizan esta \
operaci\[OAcute]n. El primero realiza una media aritm\[EAcute]tica y el \
segundo una media ponderada.\
\>", "Text"],

Cell[BoxData[
    StyleBox[
      RowBox[{
        RowBox[{\(1\/9\), " ", 
          RowBox[{"(", GridBox[{
                {"1", "1", "1"},
                {"1", "1", "1"},
                {"1", "1", "1"}
                }], ")"}]}], ",", "                         ", 
        RowBox[{\(1\/16\), " ", 
          RowBox[{"(", GridBox[{
                {"1", "2", "1"},
                {"2", "4", "2"},
                {"1", "2", "1"}
                }], ")"}]}]}],
      FontFamily->"Times New Roman"]], "Text",
  TextAlignment->Center],

Cell[TextData[{
  "Aqu\[IAcute] puedes ver tres im\[AAcute]genes de un gatito. En la primera \
de ellas se aprecia claramente que la imagen est\[AAcute] contaminada con un \
",
  StyleBox["ruido",
    FontSlant->"Italic"],
  " en forma de ",
  StyleBox["sal y pimienta.",
    FontSlant->"Italic"],
  " En la segunda imagen este ruido se ha atenuado bastante aplicando un \
filtro en media de tama\[NTilde]o 3\[Times]3. En la tercera imagen se ha \
aumentado el tama\[NTilde]o del filtro a 5\[Times]5 y el ruido inicial casi \
no se aprecia pero la imagen resultante es muy borrosa. "
}], "Text"],

Cell[BoxData[{
    \(\(gatito = Import["\<gatito_rdo.jpg\>"];\)\), "\[IndentingNewLine]", 
    \(\(DisplayTogetherArray[{ListDensityPlot[gatito[\([1, 1]\)]], 
          ListDensityPlot[
            ListConvolve[\(1\/9. \) Table[1, {3}, {3}], gatito[\([1, 1]\)]]], 
          ListDensityPlot[
            ListConvolve[\(1\/25. \) Table[1, {5}, {5}], 
              gatito[\([1, 1]\)]]]}, 
        ImageSize \[Rule]  .6*{3*316, 256}];\)\)}], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Filtrado gausiano", "Subsection"],

Cell[TextData[{
  "Es otro tipo de filtro que tambi\[EAcute]n se utiliza para suavizar y \
eliminar ",
  StyleBox["ruido",
    FontSlant->"Italic"],
  " en una imagen. Se diferencia del anterior en el tipo de n\[UAcute]cleo \
que utiliza cuyos coeficientes viene dados por una funci\[OAcute]n de \
densidad gausiana de media cero"
}], "Text"],

Cell[TextData[{
  "\t",
  Cell[BoxData[
      \(TraditionalForm\`f(x, y)\  = \ 
        1\/\(2  \[Pi]\ \[Sigma]\^2\)\ \[ExponentialE]\^\(-\ \(\(x\^2 + y\^2\)\
\/\(2  \[Sigma]\^2\)\)\)\)]]
}], "Text",
  TextAlignment->Center],

Cell[TextData[{
  "donde el par\[AAcute]metro \[Sigma] es la desviaci\[OAcute]n \
t\[IAcute]pica. Naturalmente, hay que obtener una aproximaci\[OAcute]n \
discreta de la gausiana que pueda usarse como n\[UAcute]cleo de convoluci\
\[OAcute]n con una imagen. El valor del par\[AAcute]metro \[Sigma] se \
determina por la condici\[OAcute]n de que ",
  Cell[BoxData[
      \(TraditionalForm\`6  \[Sigma]\)]],
  " sea igual al tama\[NTilde]o del n\[UAcute]cleo que se va a usar.  Aqu\
\[IAcute] puedes ver los efectos de aplicar un filtro gausiano a nuestro \
gatito."
}], "Text"],

Cell[BoxData[{
    \(\(gaus1 = 
        Table[\(1\/\(2  \[Pi]\ \[Sigma]\^2\)\) 
              Exp[\(-\(\(i\^2 + 
                        j\^2\)\/\(2\ \[Sigma]\^2\)\)\)] /. \[Sigma] \[Rule] 
              5. /6, {i, \(-2\), 2}, {j, \(-2\), 2}];\)\), "\n", 
    \(\(gaus2 = 
        Table[\(1\/\(2  \[Pi]\ \[Sigma]\^2\)\) 
              Exp[\(-\(\(i\^2 + 
                        j\^2\)\/\(2\ \[Sigma]\^2\)\)\)] /. \[Sigma] \[Rule] 
              7. /6, {i, \(-3\), 3}, {j, \(-3\), 
            3}];\)\), "\[IndentingNewLine]", 
    \(\(DisplayTogetherArray[{ListDensityPlot[gatito[\([1, 1]\)]], 
          ListDensityPlot[ListConvolve[gaus1, gatito[\([1, 1]\)]]], 
          ListDensityPlot[ListConvolve[gaus2, gatito[\([1, 1]\)]]]}, 
        ImageSize \[Rule]  .6*{3*316, 256}];\)\)}], "Input"],

Cell[BoxData[
    \(Clear[gatito, gaus1, gaus2]\)], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Filtrado laplaciano", "Subsection"],

Cell[TextData[{
  "La laplaciana de una imagen ",
  Cell[BoxData[
      \(TraditionalForm\`f(x, y)\)]],
  " viene dada por ",
  Cell[BoxData[
      \(TraditionalForm\`L(x, 
          y) = \(\[PartialD]\^2 f\/\[PartialD]x\^2\) \((x, 
              y)\) + \(\[PartialD]\^2 f\/\[PartialD]y\^2\) \((x, y)\)\)]],
  ". Este operador se usa para detectar las regiones de una imagen en las que \
hay cambios bruscos de luminosidad y, por tanto, puede usarse para detectar \
perfiles. Naturalmente, ya que cada pixel est\[AAcute] representado por un \
conjunto discreto de valores, para aplicar este operador se usan \
n\[UAcute]cleos de convoluci\[OAcute]n que aproximan los valores de las \
derivadas parciales de segundo orden del operador de Laplace. Suelen usarse \
los siguientes n\[UAcute]cleos."
}], "Text"],

Cell[BoxData[
    StyleBox[
      RowBox[{
        RowBox[{"(", GridBox[{
              {"0", "1", "0"},
              {"1", \(-4\), "1"},
              {"0", "1", "0"}
              }], ")"}], "           ", 
        RowBox[{"(", GridBox[{
              {"1", "1", "1"},
              {"1", \(-8\), "1"},
              {"1", "1", "1"}
              }], ")"}], "          "}],
      FontFamily->"Times New Roman"]], "Text",
  TextAlignment->Center],

Cell["\<\
Observa que estos n\[UAcute]cleos son de suma cero, lo que implica que el \
filtro tiene respuesta nula en una regi\[OAcute]n de brillo uniforme. Su \
efecto solamente se aprecia en regiones en las que hay cambios \
s\[UAcute]bitos de luminosidad, es decir, en regiones que se corresponden con \
perfiles los cuales se muestran de forma destacada.  \
\>", "Text"],

Cell[BoxData[{
    \(\(lapl1 = {{0, 1, 0}, {1, \(-4\), 1}, {0, 1, 
            0}};\)\), "\[IndentingNewLine]", 
    \(\(lapl2 = {{1, 1, 1}, {1, \(-8\), 1}, {1, 1, 
            1}};\)\), "\[IndentingNewLine]", 
    \(\(libros = Import["\<libros.jpg\>"];\)\), "\n", 
    \(\(DisplayTogetherArray[{ListDensityPlot[libros[\([1, 1]\)]], 
          ListDensityPlot[ListConvolve[lapl1, libros[\([1, 1]\)]]], 
          ListDensityPlot[ListConvolve[lapl2, libros[\([1, 1]\)]]]}, 
        ImageSize \[Rule]  .7*{3*164, 256}];\)\)}], "Input"],

Cell[TextData[{
  "En general, si ",
  Cell[BoxData[
      \(TraditionalForm\`\((h \((i, j)\))\)\_\(\((2  n - 1)\)\[Times]\((2  n \
- 1)\)\)\)]],
  " es un filtro cuyo efecto es suavizar perfiles, el ",
  StyleBox["filtro inverso",
    FontSlant->"Italic"],
  ", ",
  Cell[BoxData[
      \(TraditionalForm\`\[Delta](i - n, j - n) - \((h(i, j))\)\)]],
  ", donde \[Delta] es la funci\[OAcute]n DiscreteDelta[ ] que vale siempre 0 \
excepto ",
  Cell[BoxData[
      \(TraditionalForm\`\[Delta](0, 0) = 1\)]],
  ", tiene como efecto destactar perfiles."
}], "Text"],

Cell[BoxData[{
    \(\(bajo = Table[1, {3}, {3}]/9. ;\)\), "\n", 
    \(\(alto = 
        Table[DiscreteDelta[i - 2, j - 2] - bajo[\([i, j]\)], {i, 3}, {j, 
            3}];\)\), "\[IndentingNewLine]", 
    \(\(DisplayTogetherArray[{ListDensityPlot[libros[\([1, 1]\)]], 
          ListDensityPlot[ListConvolve[alto, libros[\([1, 1]\)]]]}, 
        ImageSize \[Rule]  .8*{2*164, 256}];\)\)}], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Filtros para mejorar la nitidez", "Subsection"],

Cell["\<\
Estos filtros consisten en suavizar la imagen y seguidamente restar a la \
imagen original una fracci\[OAcute]n de la imagen suavizada. Los siguientes n\
\[UAcute]cleos sirven a tal efecto.\
\>", "Text"],

Cell[TextData[{
  Cell[BoxData[
      FormBox[
        TagBox[
          RowBox[{\(1\/9\), 
            RowBox[{"(", "\[NoBreak]", GridBox[{
                  {\(-1\), \(-1\), \(-1\)},
                  {\(-1\), \(\(-1\) + 9\ a\), \(-1\)},
                  {\(-1\), \(-1\), \(-1\)}
                  }], "\[NoBreak]", ")"}]}],
          (MatrixForm[ #]&)], TraditionalForm]]],
  ",   ",
  Cell[BoxData[
      FormBox[
        RowBox[{"(", GridBox[{
              {"1", \(-2\), "1"},
              {\(-2\), "5", \(-2\)},
              {"1", \(-2\), "1"}
              }], ")"}], TraditionalForm]]],
  ",   ",
  Cell[BoxData[
      FormBox[
        RowBox[{\(\(\(\ \)\(1\)\)\/7\), 
          RowBox[{"(", GridBox[{
                {\(-1\), \(-2\), \(-1\)},
                {\(-2\), "19", \(-2\)},
                {\(-1\), \(-2\), \(-1\)}
                }], ")"}]}], TraditionalForm]]]
}], "Text",
  TextAlignment->Center],

Cell[BoxData[{
    \(\(nucleo = 
        ReplacePart[\(-Table[1, {5}, {5}]\)/25. , 
          2.  - 1/25. , {3, 3}];\)\), "\[IndentingNewLine]", 
    \(\(libros = Import["\<librosb.jpg\>"];\)\), "\[IndentingNewLine]", 
    \(\(DisplayTogetherArray[{ListDensityPlot[libros[\([1, 1]\)]], 
          ListDensityPlot[
            ListConvolve[nucleo, libros[\([1, 1]\)]]]}];\)\)}], "Input"]
}, Open  ]]
}, Open  ]],

Cell[CellGroupData[{

Cell["Mejora de la nitidez por \"deconvoluci\[OAcute]n\"", "Section"],

Cell["\<\
El tratamiento de im\[AAcute]genes se ocupa muy especialmente de la eliminaci\
\[OAcute]n de \"ruido\". Por el t\[EAcute]rmino \"ruido\" quiero indicar \
cualquier circunstacia que disminuya la calidad de una imagen. Puede ser, \
como hemos considerado ya anteriormente, falta de contraste o un rango din\
\[AAcute]mico pobre y tambi\[EAcute]n algo bastante frecuente, a saber, falta \
de nitidez y definici\[OAcute]n, lo que se traduce en una imagen borrosa. Un \
motivo que da lugar a im\[AAcute]genes borrosas es cuando el \
fot\[OAcute]grafo no tiene buen pulso y mueve inadvertidamente la \
c\[AAcute]mara en el momento de tomar la foto. Realmente lo que ocurre en \
este caso es que cada pixel en la imagen se est\[AAcute] promediando con sus \
vecinos. Matem\[AAcute]ticamente, se est\[AAcute] haciendo una cierta \
convoluci\[OAcute]n. A veces es posible deshacer dicha convoluci\[OAcute]n y \
mejorar considerablemente la nitidez de la imagen. Vamos a ver un ejemplo de \
esto. Empezamos por importar una imagen.\
\>", "Text"],

Cell[BoxData[
    \(\(fotomovida = Import["\<borrosa.dat\>"];\)\)], "Input"],

Cell["\<\
Se trata de un archivo de imagen consituido por una matriz \
num\[EAcute]rica.\
\>", "Text"],

Cell[BoxData[
    \({Head[fotomovida], Dimensions[fotomovida]}\)], "Input"],

Cell["Podemos visualizarlo de la forma conocida.", "Text"],

Cell[BoxData[
    \(\(ListDensityPlot[fotomovida, Mesh \[Rule] False, 
        AspectRatio \[Rule] Automatic, PlotRange \[Rule] All];\)\)], "Input",
  AspectRatioFixed->True],

Cell["\<\
Se trata de una foto borrosa de una comadreja. Se sabe que el \
fot\[OAcute]grafo, al tomar la foto, mov\[IAcute]o la c\[AAcute]mara \
horizontalmente (pero no verticalmente) de forma que cada pixel sali\[OAcute] \
corrido transform\[AAcute]ndose en una l\[IAcute]nea horizontal de longitud \
igual a 25 pixels. Matem\[AAcute]ticamente, esto quiere decir que cada fila \
de la matriz de \"fotomovida\" es el resultado de convolucionar \
c\[IAcute]clicamente la correspondiente fila de la matriz de \"fotobuena\" \
con la siguiente se\[NTilde]al.\
\>", "Text"],

Cell[BoxData[
    \(\(nucleo = 
        Table[If[\(-12\) \[LessEqual] k \[LessEqual] 12, 1/25. , 
            0.0], {k, \(-128\), 127}];\)\)], "Input"],

Cell[TextData[{
  "La lista \"nucleo\" tiene 256 elementos (igual que cada fila de la matriz \
de la imagen) y es sim\[EAcute]trica respecto al lugar ",
  Cell[BoxData[
      \(TraditionalForm\`256\/2 + 1 = 129\)]],
  ". Podemos comprobar estas afirmaciones."
}], "Text"],

Cell[BoxData[
    \(Length[nucleo]\)], "Input"],

Cell[BoxData[{
    \(\(k = 0;\)\), "\[IndentingNewLine]", 
    \(\(While[
        k \[LessEqual] 127 && 
          nucleo[\([k + 129]\)] \[Equal] 
            nucleo[\([129 - k]\)], \(k++\)];\)\), "\[IndentingNewLine]", 
    \(k - 1\), "\[IndentingNewLine]", 
    \(Clear[k]\)}], "Input"],

Cell["\<\
La operaci\[OAcute]n de convoluci\[OAcute]n c\[IAcute]clica de una fila de la \
matriz de \"fotobuena\" con la lista \"nucleo\" lo que hace es calcular \
promedios. Concretamente, la convoluci\[OAcute]n de la fila i-\[EAcute]sima, \
\"fotobuena[[i]]\", con \"nucleo\" es una lista con 256 elementos cuyo \
elemento k-\[EAcute]simo es igual al promedio de los 25 elementos cosecutivos \
de dicha fila empezando en el lugar 116+k, esto es:\
\>", "Text"],

Cell[BoxData[
    \(TraditionalForm\`fotomovida[\([i, 
          k]\)] = \[Sum]\+\(j = k\)\%\(k + 24\)\(1\/25\) 
          fotobuena[\([i, 116 + j]\)]\)], "Text",
  TextAlignment->Center],

Cell["\<\
Donde se entiende que si 116+j es mayor que 256 entonces debe reducirse m\
\[OAcute]dulo 256, es decir, se sustituye por el resto de su divisi\[OAcute]n \
por 256. El n\[UAcute]mero 116 no tiene nada de extra\[NTilde]o: los primeros \
116 lugares de \"nucleo\" son ceros.\
\>", "Text"],

Cell[BoxData[
    \(\(\(Map[Length, Split[nucleo]]\)\( (*\ 116\ ceros, \ 
      seguidos\ de\ 25\ elementos\ iguales\ a\ 0.004, \ 
      seguidos\ de\ 115\ ceros\ *) \)\)\)], "Input"],

Cell["\<\
Para mejorar la nitidez de la imagen sometemos cada fila de la matriz a una \
\"deconvoluci\[OAcute]n\". Hay que tener en cuenta que para cada fila se \
tiene que\
\>", "Text"],

Cell[BoxData[
    \(TraditionalForm\`fotomovida[\([i]\)] = \(fotobuena[\([i]\)] \
\[SixPointedStar]nucleo\[DoubleLongRightArrow]DFT[fotomovida[\([i]\)]] = 
        DFT[fotobuena[\([i]\)]]\ DFT[nucleo]\)\)], "Text",
  TextAlignment->Center],

Cell["de donde se sigue que", "Text"],

Cell[BoxData[
    FormBox[
      RowBox[{\(fotobuena[\([i]\)]\), "=", 
        RowBox[{"InversaDFT", "[", 
          FormBox[\(DFT[fotomovida[\([i]\)]]\/DFT[nucleo]\),
            "TraditionalForm"], "]"}]}], TraditionalForm]], "Text",
  TextAlignment->Center],

Cell["\<\
En t\[EAcute]rminos de matrices esto es lo que se hace en la siguiente celda. \
\
\>", "Text"],

Cell[BoxData[
    \(\(fotobuena = 
        Re[Map[InverseFourier, 
              Chop[Map[Fourier, fotomovida]]\/Chop[Table[Fourier[nucleo], \
{128}]]]] // Chop;\)\)], "Input"],

Cell[BoxData[
    \(\(ListDensityPlot[fotobuena, Mesh \[Rule] False, 
        AspectRatio \[Rule] Automatic, 
        ColorFunctionScaling \[Rule] False];\)\)], "Input"],

Cell["\<\
Para que la representaci\[OAcute]n sea correcta debemos girar la \
gr\[AAcute]fica (doblarla por la mitad).\
\>", "Text"],

Cell[BoxData[{
    \(\(comadreja = 
        RotateLeft[fotobuena, {128, 127}];\)\), "\[IndentingNewLine]", 
    \(\(ListDensityPlot[RotateLeft[fotobuena, {128, 127}], 
        Mesh \[Rule] False, AspectRatio \[Rule] Automatic, 
        ColorFunctionScaling \[Rule] False];\)\), "\[IndentingNewLine]", 
    \({Min[comadreja], Max[comadreja]} // Round\)}], "Input"],

Cell["\<\
Los valores de la imagen est\[AAcute]n en el rango de 0 a 367200. Podemos \
mejorar mucho el resultado situando los valores en el rango 0 a 255.\
\>", "Text"],

Cell[BoxData[
    \(\(ListDensityPlot[Round[ranGo[comadreja]], Mesh \[Rule] False, 
        AspectRatio \[Rule] Automatic];\)\)], "Input"],

Cell["\<\
Popemos comprobar que si desahcemos los cambios recuperamos la imagen borrosa \
de partida.\
\>", "Text"],

Cell[BoxData[{
    \(\(ker = Fourier[nucleo] // Chop;\)\), "\[IndentingNewLine]", 
    \(\(newfotomovida = 
        Map[InverseFourier, Map[Fourier, fotobuena]*Table[ker, {128}]] // 
          Chop;\)\)}], "Input"],

Cell[BoxData[
    \(\(ListDensityPlot[newfotomovida, Mesh \[Rule] False, 
        AspectRatio \[Rule] Automatic, PlotRange \[Rule] All];\)\)], "Input",
  AspectRatioFixed->True],

Cell[BoxData[
    \(Table[
      Simplify[newfotomovida[\([k]\)] == fotomovida[\([k]\)]], {k, 1, 
        Length[fotomovida]}]\)], "Input"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Transformaciones continuas de imagen", "Section",
  CellTags->{"Image manipulation", "Image processing"}],

Cell[TextData[{
  "Lo que sigue est\[AAcute] basado en el cap\[IAcute]tulo 10 del libro The \
Beginner's Guide to ",
  StyleBox["Mathematica ",
    FontSlant->"Italic"],
  "(",
  "v4) de Jerry Glynn y Theodore W. Gray, Cambridge University Press (1999). \
\n",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " proporciona herramientas que permiten convertir f\[AAcute]cilmente una \
imagen en una funci\[OAcute]n continua de dos variables que puede ser \
manipulada matem\[AAcute]ticamente para conseguir llamativos efectos. Para \
ello usaremos el comando ",
  StyleBox["ListInterpolation", "InlineInput"],
  "[matriz] que act\[UAcute]a sobre una matriznum\[EAcute]rica y devuelve un \
objeto ",
  StyleBox["InterpolatingFunction", "InlineInput"],
  "[ ] que es una funci\[OAcute]n que interpola los valores de la matriz y \
que se comporta como una funci\[OAcute]n usual de dos variables."
}], "Text",
  CellTags->{"Image manipulation", "Image processing"}],

Cell[BoxData[{
    \(\(dogy = Import["\<dogy.jpg\>"];\)\), "\[IndentingNewLine]", 
    \(\(dogydat = N[dogy[\([1, 1]\)]/255];\)\), "\[IndentingNewLine]", 
    \(Dimensions[dogydat]\), "\[IndentingNewLine]", 
    \(\(Show[dogy, ImageSize \[Rule]  .7*{302, 256}];\)\)}], "Input"],

Cell["\<\
Hay que transponer las filas y columnas para que en la funci\[OAcute]n de \
interpolaci\[OAcute]n resultante se respeten las dimensiones de la imagen en \
el eje de abscisas y de ordenadas.\
\>", "Text"],

Cell[BoxData[
    \(dogyFunction = ListInterpolation[Transpose[dogydat]]\)], "Input",
  CellTags->{"Image manipulation", "Image processing"}],

Cell[TextData[{
  "Podemos evaluar la funci\[OAcute]n obtenida sin salirnos del rango de \
valores (x,y)\[Element] [1,256]\[Times][1,302] (si lo hacemos ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " nos dar\[AAcute] un aviso para advertir que calcula esos valores usando \
",
  StyleBox["extrapolaci\[OAcute]n",
    FontSlant->"Italic"],
  ")."
}], "Text"],

Cell[BoxData[
    \({dogyFunction[38, 105], dogydat[\([105, 38]\)]}\)], "Input"],

Cell["\<\
Lo interesante es que podemos evaluar la funci\[OAcute]n dogyFunction[ ] en \
valores reales no necesariamente enteros.\
\>", "Text"],

Cell[BoxData[
    \(dogyFunction[38.7, 105.2]\)], "Input"],

Cell[TextData[{
  "Naturalmente, podemos representar dogyFunction[ ] gr\[AAcute]ficamente con \
cualquiera de los comandos que se usan en ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " para representar funciones de dos variables."
}], "Text"],

Cell[BoxData[
    \(\(Plot3D[dogyFunction[x, y], {x, 1, 256}, {y, 1, 302}, 
        PlotPoints \[Rule] 100, ColorFunction \[Rule] GrayLevel, 
        Mesh \[Rule] False];\)\)], "Input"],

Cell["\<\
Parece que hemos perdido a dogy. Pero basta con cambiar el punto de vista \
para recuperarlo.\
\>", "Text"],

Cell[BoxData[
    \(\(\(Show[%, ViewPoint \[Rule] {0.0, \ 0, 0, \ 2}, 
      Axes \[Rule] False]\)\(;\)\(\ \)\( (*\ 
      vemos\ la\ gr\[AAcute]fica\ desde\ arriba\ *) \)\)\)], "Input"],

Cell["\<\
Podemos reducir un poco el tama\[NTilde]o de la imagen y ajustar la opci\
\[OAcute]n BoxRatios.\
\>", "Text"],

Cell[BoxData[{
    \(\(Show[%, 
        ImageSize \[Rule]  .7*{288, 283.625}];\)\), "\[IndentingNewLine]", 
    \(\(Show[%, BoxRatios \[Rule] Automatic, 
        Boxed \[Rule] False];\)\)}], "Input"],

Cell["\<\
Esta \[UAcute]ltima imagen ya ni siquiera parece una imagen 3D. Observa que \
al variar de forma continua el valor de luminosidad la imagen obtenida es m\
\[AAcute]s borrosa que la original. Pero no hemos perdido la imagen original.\
\
\>", "Text"],

Cell[BoxData[
    \(\(Show[
        Graphics[
          Raster[Transpose[
              Apply[dogyFunction, 
                Table[{i, j}, {i, 1, 256}, {j, 1, 302}], {2}]]]], 
        AspectRatio \[Rule] Automatic, 
        ImageSize \[Rule]  .7*{302, 256}];\)\)], "Input"],

Cell["Otra posibilidad es usar DensityPlot[ ] o ContourPlot[ ].", "Text"],

Cell[BoxData[
    \(\(DensityPlot[
        dogyFunction[x, y], {x, 1, 256}, {y, 1, 
          302}, \[IndentingNewLine]PlotPoints \[Rule] 200, 
        Mesh \[Rule] False, AspectRatio \[Rule] Automatic, 
        Frame \[Rule] None, ImageSize \[Rule]  .7*{302, 256}];\)\)], "Input",
  CellTags->{"Image manipulation", "Image processing", "Image distortions"}],

Cell[BoxData[
    \(\(ContourPlot[dogyFunction[x, y], {x, 1, 256}, {y, 1, 302}, 
        Contours \[Rule] 6, ContourShading \[Rule] False, 
        PlotPoints \[Rule] 250, AspectRatio \[Rule] Automatic, 
        ImageSize \[Rule] {302, 256}];\)\)], "Input"],

Cell["\<\
Podemos manipular matem\[AAcute]ticamente la funci\[OAcute]n dogyFunction[ ] \
componi\[EAcute]ndola con otras.\
\>", "Text"],

Cell[BoxData[
    \(\(DensityPlot[
        dogyFunction[x\^2, y\^2], {x, 1, \@256}, {y, 
          1, \@302}, \[IndentingNewLine]PlotPoints \[Rule] 200, 
        Mesh \[Rule] False, AspectRatio \[Rule] Automatic, 
        Frame \[Rule] None];\)\)], "Input",
  CellTags->{"Image manipulation", "Image processing", "Image distortions"}],

Cell["\<\
Podemos derivar la funcic\[OAcute]n dogy Function[ ]. Definamos su la \
laplaciana.\
\>", "Text"],

Cell[BoxData[
    \(\(lplace[x_, y_] = 
        D[dogyFunction[x, y], {x, 2}] + 
          D[dogyFunction[x, y], {y, 2}];\)\)], "Input"],

Cell["\<\
Veamos que, como se ha afirmado m\[AAcute]s arriba, la laplaciana detecta \
perfiles en la imagen.\
\>", "Text"],

Cell[BoxData[
    \(\(Plot3D[lplace[x, y], {x, 1, 256}, {y, 1, 302}, 
        PlotPoints \[Rule] 300, ViewPoint \[Rule] {0.0, \ 0.0, \ 2}, 
        ColorFunction \[Rule] GrayLevel, BoxRatios \[Rule] Automatic, 
        Mesh \[Rule] False, Axes \[Rule] False, Boxed \[Rule] False, 
        ImageSize \[Rule] {302, 256}];\)\)], "Input",
  CellTags->{"Image manipulation", "Image processing"}],

Cell["\<\
Para efectuar algunas transformaciones es conveniente ajustar previamente el \
rango de valores de la funci\[OAcute]n de interpolaci\[OAcute]n. Esto puede \
hacerse como sigue.\
\>", "Text"],

Cell[BoxData[
    \(\(newdogyFunction = 
        ListInterpolation[
          Transpose[dogydat], {{\(-1\), 1}, 
            N[{\(-302\)/256, 302/256}]}];\)\)], "Input"],

Cell[BoxData[
    \(\(DensityPlot[
        newdogyFunction[Sign[x] x\^2, Sign[y] y\^2], {x, \(-1\), 
          1}, {y, \(-\@1.17\), \@1.17}, \[IndentingNewLine]PlotPoints \[Rule] 
          200, Mesh \[Rule] False, AspectRatio \[Rule] Automatic, 
        Frame \[Rule] None];\)\)], "Input"],

Cell[BoxData[
    \(\(DensityPlot[
        Apply[newdogyFunction, {x, 
              y}*\((x\^2 + y\^2)\)\^\(\(( .6 - 1)\)/2\)], {x, \(-1\), 
          1}, {y, \(-1.17\), 1.17}, \[IndentingNewLine]PlotPoints \[Rule] 
          200, Mesh \[Rule] False, AspectRatio \[Rule] Automatic, 
        Frame \[Rule] None, PlotRange \[Rule] {0, 1}];\)\)], "Input"],

Cell[CellGroupData[{

Cell["Manipulaci\[OAcute]n de im\[AAcute]genes en color", "Subsection"],

Cell["Importemos una imagen en color.", "Text"],

Cell[BoxData[{
    \(\(pupy = Import["\<pupy_color.jpg\>"];\)\), "\[IndentingNewLine]", 
    \(\(pupycolordat = pupy[\([1, 1]\)];\)\), "\[IndentingNewLine]", 
    \(Dimensions[pupycolordat]\), "\[IndentingNewLine]", 
    \(\(Show[pupy];\)\)}], "Input"],

Cell[TextData[{
  "No es dif\[IAcute]cil hacer manipulaciones parecidas a las anteriores con \
im\[AAcute]genes en color. De hecho, el comando ListInterpolation[ ] puede \
trabajar sobre matrices cuyos elementos son vectores y una imagen en color no \
es m\[AAcute]s que eso: una matriz cuyos elementos son vectores de la forma \
{r,g,b} que contienen los valores de rojo, verde y azul de cada pixel. Al \
aplicar ListInterpolation[ ] a una matriz de este tipo, como \
\"pupycolordat\",  obtenemos un objeto InterpolatingFunction[ ] que es una \
funci\[OAcute]n de tres variables {x,y,z} donde las dos primeras{x,y} son \
variables espaciales y la tercera, z, puede usarse para obtener el color que \
corresponde a un valor fijado de {x,y} de la forma siguiente ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0, 1}\)]],
  " es el valor de rojo que corresponde a ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0}\)]],
  ",  ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0, 2}\)]],
  " es el valor de verde que corresponde a ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0}\)]],
  ", ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0, 3}\)]],
  " es el valor de azul que corresponde a ",
  Cell[BoxData[
      \(TraditionalForm\`{x\_0, y\_0}\)]],
  ". Como no hay suficientes datos en la direcci\[OAcute]n z para hacer una \
aproximaci\[OAcute]n c\[UAcute]bica (la que se hace por defecto en cada \
variable), ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " nos avisa de que ha reducido el orden de aproximaci\[OAcute]n en la \
tercera variable (a aproximaci\[OAcute]n cuadr\[AAcute]tica o de orden 2)."
}], "Text"],

Cell[BoxData[
    \(Clear[newpupyFunction]\)], "Input"],

Cell[BoxData[
    \(\(pupyFunction = 
        ListInterpolation[Transpose[pupycolordat]];\)\)], "Input",
  CellTags->{
  "Image manipulation", "Image processing", "Image distortions", 
    "Color image manipulation"}],

Cell["\<\
La funci\[OAcute]n obtenida coindide con \"pupycolordat\" en los puntos {x,y}\
\[Element][1,256]\[Times][1,302]. Concretamente, se verifica que \
pupyFunction[x,y,k]=pupycolordat[y,x][[k]] para k=1,2,3 y para {x,y} enteros \
con {x,y}\[Element][1,256]\[Times][1,302].\
\>", "Text"],

Cell[BoxData[{
    \(Table[pupyFunction[57, 126, k], {k, 1, 3}] == 
      pupycolordat[\([126, 57]\)]\), "\[IndentingNewLine]", 
    \(Table[pupyFunction[256, 302, k], {k, 1, 3}] == 
      pupycolordat[\([302, 256]\)]\)}], "Input"],

Cell[TextData[{
  "Pero \"pupyFunction[ ]\" puede ser evaluada en cualquier punto ",
  Cell[BoxData[
      \(TraditionalForm\`{x, y, 
          z} \[Element] \([1, 256]\)\[Times]\([1, 302]\)\[Times]\([1, 
            3]\)\)]],
  " aunque sus coordenadas no sean n\[UAcute]meros enteros. "
}], "Text"],

Cell[BoxData[
    \(pupyFunction[57.59, 126.38, 1.75]\)], "Input"],

Cell["\<\
Podemos representar por separado cada valor de color con Plot3D[ ].\
\>", "Text"],

Cell[BoxData[
    \(\(\(Plot3D[pupyFunction[x, y, 1], {x, 1, 256}, {y, 1, 302}, 
      PlotPoints \[Rule] 200, Axes \[Rule] False, Mesh \[Rule] False, 
      ViewPoint \[Rule] {0.0, \ 0.0, \ 2}]\)\(;\)\( (*\ 
      estamos\ viendo\ la\ gr\[AAcute]fica\ desde\ arriba\ *) \)\)\)], "Input",\

  CellTags->{"Image manipulation", "Image processing"}],

Cell["\<\
Podemos ajustar los datos a un rango m\[AAcute]s apropiado para realizar \
ciertas transformaciones.\
\>", "Text"],

Cell[BoxData[
    \(\(newpupyFunction = 
        ListInterpolation[
          Transpose[
            pupycolordat/255. ], {{\(-1\), 1}, {\(-1.18\), 1.18}, {1, 3}}, 
          InterpolationOrder \[Rule] {3, 3, 2}];\)\)], "Input",
  CellTags->{
  "Image manipulation", "Image processing", "Image distortions", 
    "Color image manipulation"}],

Cell["\<\
La funci\[OAcute]n obtenida es esencialmente la misma pero con los valores \
situados en [-1,1]\[Times][1.18,1.18]\[Times][1,3].\
\>", "Text"],

Cell[BoxData[
    \(\(Plot3D[
        newpupyFunction[x, y, 1], {x, \(-1\), 1}, {y, \(-1.18\), 1.18}, 
        PlotPoints \[Rule] 200, Axes \[Rule] False, Mesh \[Rule] False, 
        ViewPoint \[Rule] {0.0, \ 0.0, \ 2}];\)\)], "Input",
  CellTags->{"Image manipulation", "Image processing"}],

Cell["\<\
Podemos obtener una funci\[OAcute]n de color para \"pupy\" de la siguiente \
forma.\
\>", "Text"],

Cell[BoxData[
    \(\(colorpupyFunction[x_, y_] = 
        Table[newpupyFunction[x, y, j], {j, 1, 3}];\)\)], "Input"],

Cell["\<\
No es podible usar DensityPlot[ ] ni Plot3D[ ] para representar esta funci\
\[OAcute]n de color pero podemos usar Raster[ ] como sigue.\
\>", "Text"],

Cell[BoxData[
    \(\(Show[
        Graphics[
          Raster[Transpose[
              Table[colorpupyFunction[x, y], {x, \(-1.0\), 1.0, 
                  1/100. }, {y, \(-1.18\), 1.18, 
                  1/100. }]], {{\(-1\), \(-1.18\)}, {1, 1.18}}, 
            ColorFunction \[Rule] RGBColor], AspectRatio -> Automatic, 
          PlotRange \[Rule] {{\(-1\), 1}, {\(-1.18\), 1.18}}]];\)\)], "Input"],

Cell[TextData[{
  "Podemos definir una funci\[OAcute]n que haga esto que admita una opci\
\[OAcute]n \[UAcute]nica de la forma ",
  Cell[BoxData[
      \(TraditionalForm\`PlotPoints \[Rule] {nx, ny}\)]],
  " a la que por defecto damos el valor ",
  Cell[BoxData[
      \(TraditionalForm\`nx = \(ny = 30\)\)]],
  "."
}], "Text"],

Cell[BoxData[
    \(imagencolorPlot[func_, {x_, xmin_, xmax_}, \ {y_, ymin_, ymax_}, 
        opts___] := 
      Module[{plotpuntos}, \[IndentingNewLine]plotpuntos = 
          If[{opts} \[Equal] {}, {30, 30}, 
            PlotPoints /. {opts}]; \[IndentingNewLine]If[
          Head[plotpuntos] =!= 
            List, \[IndentingNewLine]plotpuntos = {plotpuntos, 
              plotpuntos}]; \[IndentingNewLine]\[IndentingNewLine]Show[
          Graphics[
            Raster[Table[
                func[x, y], {y, ymin, 
                  ymax, \(ymax - ymin\)\/plotpuntos[\([2]\)]}, {x, xmin, 
                  xmax, \(xmax - xmin\)\/plotpuntos[\([1]\)]}], {{xmin, 
                  ymin}, {xmax, ymax}}, ColorFunction \[Rule] RGBColor], 
            AspectRatio -> Automatic, 
            PlotRange \[Rule] {{xmin, xmax}, {ymin, 
                  ymax}}]];\[IndentingNewLine]]\)], "Input"],

Cell["Comprobemos el funcionamiento de este comando.", "Text"],

Cell[BoxData[
    \(imagencolorPlot[
      colorpupyFunction, {x, \(-1\), 1}, {y, \(-1.18\), 1.18}, 
      PlotPoints \[Rule] 200]\)], "Input"],

Cell[TextData[{
  "Ahora es f\[AAcute]cil hacer transformaciones de la imagen en color. Pero \
antes impedimos que ",
  StyleBox["Mathematica",
    FontSlant->"Italic"],
  " d\[EAcute] avisos de error porque las variables han salido del rango de \
la funci\[OAcute]n de interpolaci\[OAcute]n."
}], "Text"],

Cell[BoxData[{
    \(Off[InterpolatingFunction::"\<dmval\>"]\), "\[IndentingNewLine]", 
    \(\(pupywave[x_, y_] = 
        colorpupyFunction[x, y + Sin[30  x]/20];\)\), "\[IndentingNewLine]", 
    \(imagencolorPlot[pupywave, {x, \(-1\), 1}, {y, \(-1.18\), 1.18}, 
      PlotPoints \[Rule] 200]\)}], "Input"],

Cell["Podemos girar la imagen como sigue.", "Text"],

Cell[BoxData[{
    \(\(G[\[Theta]_] = {{Cos[\[Theta]], Sin[\[Theta]]}, {\(-Sin[\[Theta]]\), 
            Cos[\[Theta]]}};\)\), "\[IndentingNewLine]", 
    \(\(\(giropupy[\[Theta]_]\)[x_, y_] = 
        colorpupyFunction[First[G[\[Theta]] . {x, y}], 
          Last[G[\[Theta]] . {x, y}]];\)\), "\[IndentingNewLine]", 
    \(imagencolorPlot[
      giropupy[N[Pi]/2], {x, \(-1.18\), 1.18}, {y, \(-1. \), 1. }, 
      PlotPoints \[Rule] 200]\)}], "Input"],

Cell["\<\
Podemos hacer que el \[AAcute]ngulo de giro dependa de la distancia al origen \
como sigue.\
\>", "Text"],

Cell[BoxData[
    \(imagencolorPlot[
      giropupy[\@\(x\^2 + y\^2\)], {x, \(-1\), 1}, {y, \(-1.18\), 1.18}, 
      PlotPoints \[Rule] 200]\)], "Input"],

Cell[BoxData[
    \(imagencolorPlot[
      giropupy[x\^2 + y\^2], {x, \(-1\), 1}, {y, \(-1.18\), 1.18}, 
      PlotPoints \[Rule] 200]\)], "Input"],

Cell[CellGroupData[{

Cell["Ejercicio ", "Exercise"],

Cell[TextData[{
  "Usa ",
  StyleBox["Raster", "MR"],
  " para representar las banderas nacionales de los siguientes \
pa\[IAcute]ses: Francia, Alemania, Holanda, Espa\[NTilde]a, Dinamarca, \
Finlandia y Suecia. "
}], "ExerciseText"]
}, Open  ]]
}, Open  ]]
}, Open  ]]
},
FrontEndVersion->"5.2 for Microsoft Windows",
ScreenRectangle->{{0, 1024}, {0, 685}},
AutoGeneratedPackage->None,
WindowSize->{1016, 651},
WindowMargins->{{0, Automatic}, {Automatic, 0}},
PrintingCopies->1,
PrintingPageRange->{1, 1},
ShowSelection->True,
Magnification->1.5,
StyleDefinitions -> "Classroom.nb"
]

(*******************************************************************
Cached data follows.  If you edit this Notebook file directly, not
using Mathematica, you must remove the line containing CacheID at
the top of  the file.  The cache data will then be recreated when
you save this file from within Mathematica.
*******************************************************************)

(*CellTagsOutline
CellTagsIndex->{
  "Split"->{
    Cell[18497, 495, 1176, 24, 410, "Input",
      CellTags->"Split"]},
  "Image manipulation"->{
    Cell[53714, 1454, 111, 1, 93, "Section",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[53828, 1457, 966, 21, 184, "Text",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[55293, 1492, 141, 2, 72, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[57790, 1571, 358, 6, 124, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[58549, 1590, 334, 6, 108, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[59260, 1613, 390, 6, 124, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[62799, 1700, 217, 5, 72, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64013, 1736, 346, 6, 124, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[64489, 1749, 341, 8, 98, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64988, 1764, 292, 5, 98, "Input",
      CellTags->{"Image manipulation", "Image processing"}]},
  "Image processing"->{
    Cell[53714, 1454, 111, 1, 93, "Section",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[53828, 1457, 966, 21, 184, "Text",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[55293, 1492, 141, 2, 72, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[57790, 1571, 358, 6, 124, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[58549, 1590, 334, 6, 108, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[59260, 1613, 390, 6, 124, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[62799, 1700, 217, 5, 72, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64013, 1736, 346, 6, 124, "Input",
      CellTags->{"Image manipulation", "Image processing"}],
    Cell[64489, 1749, 341, 8, 98, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64988, 1764, 292, 5, 98, "Input",
      CellTags->{"Image manipulation", "Image processing"}]},
  "Image distortions"->{
    Cell[57790, 1571, 358, 6, 124, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[58549, 1590, 334, 6, 108, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions"}],
    Cell[62799, 1700, 217, 5, 72, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64489, 1749, 341, 8, 98, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}]},
  "Color image manipulation"->{
    Cell[62799, 1700, 217, 5, 72, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}],
    Cell[64489, 1749, 341, 8, 98, "Input",
      CellTags->{
      "Image manipulation", "Image processing", "Image distortions", 
        "Color image manipulation"}]}
  }
*)

(*CellTagsIndex
CellTagsIndex->{
  {"Split", 70142, 1911},
  {"Image manipulation", 70240, 1914},
  {"Image processing", 71498, 1941},
  {"Image distortions", 72757, 1968},
  {"Color image manipulation", 73394, 1983}
  }
*)

(*NotebookFileOutline
Notebook[{
Cell[1754, 51, 46, 0, 99, "Title"],
Cell[1803, 53, 173, 2, 102, "Author"],

Cell[CellGroupData[{
Cell[2001, 59, 41, 0, 93, "Section"],
Cell[2045, 61, 151, 3, 41, "Text"],
Cell[2199, 66, 292, 5, 150, "Input",
  InitializationCell->True]
}, Closed]],

Cell[CellGroupData[{
Cell[2528, 76, 82, 1, 61, "Section"],
Cell[2613, 79, 1996, 34, 365, "Text"],
Cell[4612, 115, 57, 0, 41, "Text"],
Cell[4672, 117, 139, 3, 98, "Input"],
Cell[4814, 122, 428, 8, 93, "Text"],
Cell[5245, 132, 85, 1, 71, "Theorem"],
Cell[5333, 135, 317, 8, 67, "Text"],
Cell[5653, 145, 57, 1, 72, "Input"],
Cell[5713, 148, 78, 1, 72, "Input"],
Cell[5794, 151, 271, 6, 67, "Text"],
Cell[6068, 159, 88, 1, 71, "Theorem"],
Cell[6159, 162, 1071, 17, 223, "Text"],
Cell[7233, 181, 145, 3, 72, "Input"],
Cell[7381, 186, 603, 17, 93, "Text"],
Cell[7987, 205, 176, 3, 98, "Input"],
Cell[8166, 210, 351, 10, 67, "Text"],
Cell[8520, 222, 172, 3, 98, "Input"],
Cell[8695, 227, 377, 8, 93, "Text"],
Cell[9075, 237, 334, 7, 150, "Input"],
Cell[9412, 246, 120, 3, 41, "Text"],
Cell[9535, 251, 407, 8, 176, "Input"],
Cell[9945, 261, 115, 3, 71, "Theorem"],
Cell[10063, 266, 501, 9, 93, "Text"],
Cell[10567, 277, 174, 3, 124, "Input"],
Cell[10744, 282, 116, 3, 41, "Text"],
Cell[10863, 287, 67, 1, 72, "Input"],
Cell[10933, 290, 153, 3, 41, "Text"],
Cell[11089, 295, 59, 1, 72, "Input"],
Cell[11151, 298, 122, 3, 41, "Text"],
Cell[11276, 303, 778, 15, 280, "Input"],
Cell[12057, 320, 233, 6, 67, "Text"],
Cell[12293, 328, 185, 3, 98, "Input"],
Cell[12481, 333, 292, 6, 67, "Text"],
Cell[12776, 341, 91, 1, 72, "Input"],
Cell[12870, 344, 59, 0, 41, "Text"],
Cell[12932, 346, 82, 1, 72, "Input"],
Cell[13017, 349, 106, 3, 41, "Text"],
Cell[13126, 354, 105, 2, 72, "Input"],
Cell[13234, 358, 75, 0, 41, "Text"],
Cell[13312, 360, 185, 3, 98, "Input"],
Cell[13500, 365, 461, 8, 93, "Text"],
Cell[13964, 375, 171, 3, 98, "Input"],

Cell[CellGroupData[{
Cell[14160, 382, 53, 0, 78, "Subsection"],
Cell[14216, 384, 82, 1, 72, "Input"],
Cell[14301, 387, 922, 13, 197, "Text"],
Cell[15226, 402, 120, 2, 72, "Input"],
Cell[15349, 406, 190, 4, 67, "Text"],
Cell[15542, 412, 138, 2, 98, "Input"],
Cell[15683, 416, 63, 0, 41, "Text"],
Cell[15749, 418, 71, 1, 72, "Input"],
Cell[15823, 421, 91, 1, 41, "Text"],
Cell[15917, 424, 236, 4, 124, "Input"],
Cell[16156, 430, 361, 7, 93, "Text"],
Cell[16520, 439, 802, 17, 254, "Input"],
Cell[17325, 458, 84, 1, 72, "Input"],
Cell[17412, 461, 187, 4, 67, "Text"],
Cell[17602, 467, 91, 1, 72, "Input"],
Cell[17696, 470, 69, 0, 41, "Text"],
Cell[17768, 472, 202, 3, 98, "Input"],
Cell[17973, 477, 71, 0, 41, "Text"],
Cell[18047, 479, 108, 2, 72, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[18192, 486, 33, 0, 78, "Subsection"],
Cell[18228, 488, 266, 5, 67, "Text"],
Cell[18497, 495, 1176, 24, 410, "Input",
  CellTags->"Split"],
Cell[19676, 521, 335, 6, 93, "Text"],
Cell[20014, 529, 64, 1, 72, "Input"],
Cell[20081, 532, 63, 1, 72, "Input"],
Cell[20147, 535, 162, 3, 41, "Text"],
Cell[20312, 540, 83, 1, 72, "Input"],
Cell[20398, 543, 152, 3, 41, "Text"],
Cell[20553, 548, 711, 15, 228, "Input"],
Cell[21267, 565, 47, 1, 72, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[21351, 571, 69, 0, 78, "Subsection"],
Cell[21423, 573, 809, 13, 209, "Text"],
Cell[22235, 588, 158, 3, 98, "Input"],
Cell[22396, 593, 44, 0, 41, "Text"],
Cell[22443, 595, 164, 2, 98, "Input"],
Cell[22610, 599, 277, 5, 67, "Text"],
Cell[22890, 606, 245, 4, 124, "Input"],
Cell[23138, 612, 236, 4, 67, "Text"],
Cell[23377, 618, 62, 1, 72, "Input"],
Cell[23442, 621, 124, 3, 72, "Input"],
Cell[23569, 626, 138, 3, 41, "Text"],
Cell[23710, 631, 117, 2, 72, "Input"],
Cell[23830, 635, 213, 4, 67, "Text"],
Cell[24046, 641, 616, 18, 97, "Text"],
Cell[24665, 661, 240, 4, 124, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[24942, 670, 56, 0, 78, "Subsection"],
Cell[25001, 672, 349, 6, 93, "Text"],
Cell[25353, 680, 266, 5, 124, "Input"],
Cell[25622, 687, 692, 10, 145, "Text"],
Cell[26317, 699, 80, 1, 72, "Input"],
Cell[26400, 702, 115, 3, 41, "Text"],
Cell[26518, 707, 196, 5, 98, "Input"],
Cell[26717, 714, 351, 6, 93, "Text"],
Cell[27071, 722, 70, 1, 72, "Input"],
Cell[27144, 725, 107, 2, 72, "Input"],
Cell[27254, 729, 472, 7, 119, "Text"],
Cell[27729, 738, 206, 4, 98, "Input"],
Cell[27938, 744, 295, 6, 124, "Input"],
Cell[28236, 752, 113, 3, 41, "Text"],
Cell[28352, 757, 133, 2, 72, "Input"],
Cell[28488, 761, 64, 0, 41, "Text"],
Cell[28555, 763, 169, 3, 98, "Input"],
Cell[28727, 768, 47, 1, 72, "Input"]
}, Open  ]]
}, Open  ]],

Cell[CellGroupData[{
Cell[28823, 775, 55, 0, 93, "Section"],
Cell[28881, 777, 908, 17, 171, "Text"],

Cell[CellGroupData[{
Cell[29814, 798, 53, 0, 78, "Subsection"],
Cell[29870, 800, 2884, 83, 416, "Text"],
Cell[32757, 885, 411, 12, 67, "Text"],
Cell[33171, 899, 1099, 28, 87, "Text"],
Cell[34273, 929, 47, 0, 41, "Text"],
Cell[34323, 931, 602, 12, 84, "Text"],
Cell[34928, 945, 467, 15, 67, "Text"],
Cell[35398, 962, 73, 0, 41, "Text"],
Cell[35474, 964, 1489, 26, 592, "Input"],
Cell[36966, 992, 56, 0, 41, "Text"],
Cell[37025, 994, 437, 8, 202, "Input"],
Cell[37465, 1004, 206, 4, 67, "Text"],
Cell[37674, 1010, 186, 4, 41, "Text"]
}, Open  ]],

Cell[CellGroupData[{
Cell[37897, 1019, 39, 0, 78, "Subsection"],
Cell[37939, 1021, 421, 7, 93, "Text"],
Cell[38363, 1030, 536, 16, 85, "Text"],
Cell[38902, 1048, 595, 13, 119, "Text"],
Cell[39500, 1063, 448, 8, 238, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[39985, 1076, 39, 0, 78, "Subsection"],
Cell[40027, 1078, 342, 8, 67, "Text"],
Cell[40372, 1088, 224, 7, 67, "Text"],
Cell[40599, 1097, 575, 11, 93, "Text"],
Cell[41177, 1110, 794, 15, 267, "Input"],
Cell[41974, 1127, 60, 1, 72, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[42071, 1133, 41, 0, 78, "Subsection"],
Cell[42115, 1135, 806, 16, 159, "Text"],
Cell[42924, 1153, 448, 14, 85, "Text"],
Cell[43375, 1169, 373, 6, 93, "Text"],
Cell[43751, 1177, 533, 9, 228, "Input"],
Cell[44287, 1188, 562, 16, 68, "Text"],
Cell[44852, 1206, 400, 7, 176, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[45289, 1218, 53, 0, 78, "Subsection"],
Cell[45345, 1220, 213, 4, 67, "Text"],
Cell[45561, 1226, 921, 29, 82, "Text"],
Cell[46485, 1257, 386, 7, 150, "Input"]
}, Open  ]]
}, Open  ]],

Cell[CellGroupData[{
Cell[46920, 1270, 69, 0, 93, "Section"],
Cell[46992, 1272, 1045, 15, 223, "Text"],
Cell[48040, 1289, 76, 1, 72, "Input"],
Cell[48119, 1292, 102, 3, 41, "Text"],
Cell[48224, 1297, 75, 1, 94, "Input"],
Cell[48302, 1300, 58, 0, 41, "Text"],
Cell[48363, 1302, 174, 3, 120, "Input"],
Cell[48540, 1307, 569, 9, 119, "Text"],
Cell[49112, 1318, 151, 3, 94, "Input"],
Cell[49266, 1323, 271, 6, 72, "Text"],
Cell[49540, 1331, 47, 1, 94, "Input"],
Cell[49590, 1334, 288, 7, 150, "Input"],
Cell[49881, 1343, 461, 7, 93, "Text"],
Cell[50345, 1352, 187, 4, 80, "Text"],
Cell[50535, 1358, 295, 5, 67, "Text"],
Cell[50833, 1365, 183, 3, 98, "Input"],
Cell[51019, 1370, 186, 4, 67, "Text"],
Cell[51208, 1376, 239, 4, 38, "Text"],
Cell[51450, 1382, 37, 0, 41, "Text"],
Cell[51490, 1384, 260, 6, 62, "Text"],
Cell[51753, 1392, 104, 3, 41, "Text"],
Cell[51860, 1397, 176, 4, 148, "Input"],
Cell[52039, 1403, 169, 3, 120, "Input"],
Cell[52211, 1408, 131, 3, 41, "Text"],
Cell[52345, 1413, 363, 6, 172, "Input"],
Cell[52711, 1421, 168, 3, 67, "Text"],
Cell[52882, 1426, 138, 2, 94, "Input"],
Cell[53023, 1430, 115, 3, 41, "Text"],
Cell[53141, 1435, 214, 4, 146, "Input"],
Cell[53358, 1441, 177, 3, 120, "Input"],
Cell[53538, 1446, 139, 3, 120, "Input"]
}, Open  ]],

Cell[CellGroupData[{
Cell[53714, 1454, 111, 1, 93, "Section",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[53828, 1457, 966, 21, 184, "Text",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[54797, 1480, 277, 4, 150, "Input"],
Cell[55077, 1486, 213, 4, 67, "Text"],
Cell[55293, 1492, 141, 2, 72, "Input",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[55437, 1496, 369, 10, 67, "Text"],
Cell[55809, 1508, 80, 1, 72, "Input"],
Cell[55892, 1511, 143, 3, 41, "Text"],
Cell[56038, 1516, 58, 1, 72, "Input"],
Cell[56099, 1519, 254, 6, 67, "Text"],
Cell[56356, 1527, 185, 3, 98, "Input"],
Cell[56544, 1532, 117, 3, 41, "Text"],
Cell[56664, 1537, 186, 3, 98, "Input"],
Cell[56853, 1542, 119, 3, 41, "Text"],
Cell[56975, 1547, 199, 4, 98, "Input"],
Cell[57177, 1553, 258, 5, 67, "Text"],
Cell[57438, 1560, 273, 7, 150, "Input"],
Cell[57714, 1569, 73, 0, 41, "Text"],
Cell[57790, 1571, 358, 6, 124, "Input",
  CellTags->{"Image manipulation", "Image processing", "Image distortions"}],
Cell[58151, 1579, 257, 4, 124, "Input"],
Cell[58411, 1585, 135, 3, 41, "Text"],
Cell[58549, 1590, 334, 6, 108, "Input",
  CellTags->{"Image manipulation", "Image processing", "Image distortions"}],
Cell[58886, 1598, 107, 3, 41, "Text"],
Cell[58996, 1603, 136, 3, 72, "Input"],
Cell[59135, 1608, 122, 3, 41, "Text"],
Cell[59260, 1613, 390, 6, 124, "Input",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[59653, 1621, 200, 4, 67, "Text"],
Cell[59856, 1627, 169, 4, 98, "Input"],
Cell[60028, 1633, 290, 5, 138, "Input"],
Cell[60321, 1640, 353, 6, 158, "Input"],

Cell[CellGroupData[{
Cell[60699, 1650, 71, 0, 78, "Subsection"],
Cell[60773, 1652, 47, 0, 41, "Text"],
Cell[60823, 1654, 252, 4, 150, "Input"],
Cell[61078, 1660, 1660, 35, 275, "Text"],
Cell[62741, 1697, 55, 1, 72, "Input"],
Cell[62799, 1700, 217, 5, 72, "Input",
  CellTags->{
  "Image manipulation", "Image processing", "Image distortions", 
    "Color image manipulation"}],
Cell[63019, 1707, 291, 5, 67, "Text"],
Cell[63313, 1714, 231, 4, 98, "Input"],
Cell[63547, 1720, 300, 7, 67, "Text"],
Cell[63850, 1729, 66, 1, 72, "Input"],
Cell[63919, 1732, 91, 2, 41, "Text"],
Cell[64013, 1736, 346, 6, 124, "Input",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[64362, 1744, 124, 3, 41, "Text"],
Cell[64489, 1749, 341, 8, 98, "Input",
  CellTags->{
  "Image manipulation", "Image processing", "Image distortions", 
    "Color image manipulation"}],
Cell[64833, 1759, 152, 3, 41, "Text"],
Cell[64988, 1764, 292, 5, 98, "Input",
  CellTags->{"Image manipulation", "Image processing"}],
Cell[65283, 1771, 107, 3, 41, "Text"],
Cell[65393, 1776, 117, 2, 72, "Input"],
Cell[65513, 1780, 159, 3, 41, "Text"],
Cell[65675, 1785, 404, 8, 202, "Input"],
Cell[66082, 1795, 327, 9, 67, "Text"],
Cell[66412, 1806, 895, 17, 435, "Input"],
Cell[67310, 1825, 62, 0, 41, "Text"],
Cell[67375, 1827, 143, 3, 98, "Input"],
Cell[67521, 1832, 305, 7, 67, "Text"],
Cell[67829, 1841, 308, 5, 124, "Input"],
Cell[68140, 1848, 51, 0, 41, "Text"],
Cell[68194, 1850, 452, 8, 176, "Input"],
Cell[68649, 1860, 115, 3, 41, "Text"],
Cell[68767, 1865, 153, 3, 115, "Input"],
Cell[68923, 1870, 147, 3, 99, "Input"],

Cell[CellGroupData[{
Cell[69095, 1877, 30, 0, 68, "Exercise"],
Cell[69128, 1879, 233, 6, 68, "ExerciseText"]
}, Open  ]]
}, Open  ]]
}, Open  ]]
}
]
*)



(*******************************************************************
End of Mathematica Notebook file.
*******************************************************************)

