A. Configurar EmguCV en VS2010 (o un frame en caso de vídeo), pudiendo indicarse el tipo de imagen...
-
Upload
dangnguyet -
Category
Documents
-
view
224 -
download
0
Transcript of A. Configurar EmguCV en VS2010 (o un frame en caso de vídeo), pudiendo indicarse el tipo de imagen...
Visión Artificial con OpenCV: Un Enfoque Práctico Sesión Práctica 1: Instalación y Configuración del entorno;
tratamiento de imágenes
A. Configurar EmguCV en VS2010
Nota: Compruebe que posee instalada la extensión de C#. En caso contrario, introduzca el
DVD de Visual Studio 2010, seleccione la opción de “Agregar o quitar componentes” y
seleccione la extensión de C#.
Configurar Visual Studio 2010 para poder trabajar con la librería EmguCV se reduce a hacer
uso de una serie de inclusiones de librerías y referencias específicas de ella.
Para llevar a cabo este proceso, seguiremos los siguientes pasos:
1. Acceda a la web de EmguCV (http://www.emgu.com/wiki/index.php/Main_Page)
2. En la sección “Latest News” aparecerá un listado de las últimas versiones con sus
enlaces correspondientes. Sobre cualquiera de ellas, cliqueamos en el enlace
representado por la palabra “sourceforge”.
3. Accedemos al enlace indicado en la siguiente sección.
4. En la página de SourceForge nos aparecerá para descargar la última versión de la
librería. Debido a su continua actualización, la última versión suele presentar
numerosos bugs. Por ello nos descargaremos una versión testeada y en
funcionamiento desde hace varios años (para los objetivos del presente curso no se
necesitará mas). La versión a descargar es la 2.2.
5. Para ello, accedemos a la pestaña “Files”.
6. Dentro de la carpeta “emgucv” aparecerá un listado de todas las versiones hasta la
fecha. Nos introducimos en la carpeta de la versión “2.2.0.0” y encontraremos lo
siguiente:
7. Debido a varios errores (algunos sin explicación por parte de los desarrolladores de la
librería) para el caso de la versión de 64 bits, haremos uso de la versión de 32 bits. Esto
no restringe que el equipo deba ser de 32 bits para su funcionamiento, solo restringe
el tipo de proyecto a crear desde el Visual Studio.
8. Una vez descargado el archiv, lo descomprimiremos en una ruta conocida y a elección
nuestra. Por simplicidad se ha escogido la ruta C:\Emgu. Tras esto, se puede pasar a
configurar el proyecto de Visual Studio.
9. Arrancamos el Visual Studio 2010 y creamos un proyecto nuevo de Windows Forms.
10. En primer lugar, añadiremos las referencias necesarias del wrapper. Para ello,
presionamos con el click derecho sobre la carpeta “References” o, sobre el nombre del
proyecto, click derecho a “Agregar referencia”. Dentro de la pestaña “Examinar”
navegamos hasta la ruta donde se instaló EmguCV. En ella, dentro de la carpeta “bin”,
seleccionamos las siguientes librerías dinámicas: “Emgu.CV.dll”, “Emgu.CV.UI.dll” y
“Emgu.Util.dll”. Tras ello, le damos a aceptar.
11. En segundo lugar, tendremos que añadir las
referencias pertenecientes a la librería OpenCV
nativa. Al no encontrarse en el lenguaje referencia
del proyecto (C#), sino en C++, no se podrán añadir
de igual forma. Para ello, tendremos que
introducirlas directamente a nuestro proyecto
como archivos externos (al igual que cualquier
elemento adicional). Hacemos click con el botón
derecho sobre el nombre del proyecto y accedemos
a la opción “Agregar” ”Elemento existente”.
Tras ello, navegamos hasta la carpeta de instalación
de la librería y, dentro de la subcarpeta “bin”,
seleccionamos todas las dlls relacionadas con
openCV. Estas son: “cvextern.dll”,
“opencv_calib3d220.dll”, “opencv_contrib220.dll”,
“opencv_core220.dll”, “opencv_deatures2d220.dll”,
“opencv_ffmpeg220.dll”, “opencv_flann220.dll”,
“opencv_gpu220.dll”, “opencv_highgui220.dll”,
“opencv_imgproc220.dll”, “opencv_legacy220.dll”,
“opencv_ml220.dll”, “opencv_objdetect220.dll”,
“opencv_video220.dll” y “ZedGraph.dll”. Quedando
finalmente algo similar a lo mostrado a la derecha.
12. Como podemos recordar, estamos haciendo uso de la versión de 32 bits de la librería.
Por ello, para que funcione correctamente, debemos especificar a nuestro proyecto
que genere la solución para un dispositivo x86. Hay que indicarlo en dos lugares
diferentes:
a. Botón secundario sobre el archivo de la solución (el de más arriba)
Propiedades. Propiedades de Configuración Plataforma x86.
b. Botón secundario sobre el proyecto (justo debajo de la solución)
Propiedades. Generar Destino de la Plataforma x86.
13. Como programa de ejemplo, crearemos una ventana que muestre una imagen de
fondo negro y con un texto en el centro.
14. Hacemos doble click en el archivo “Form1.cs” y nos aparecerá el editor gráfico del
formulario en cuestión. Haremos uso de un elemento de tipo “PictureBox”, de forma
que lo arrastraremos al formulario. De entre sus propiedades, le daremos un tamaño
de 400x400 píxeles, quedando algo similar a:
15. En el código del formulario (sobre “Form1.cs”, click derechoVer código), crearemos
dos variables de tipos propios de EmguCV:
- Image<tipo, profundidad>: almacén básico que contiene la información de una
imagen (o un frame en caso de vídeo), pudiendo indicarse el tipo de imagen y la
profundidad del color al crearla.
- MCvFont: tipo de fuente; utilizada para especificar las características de la fuente a
dibujar.
La imagen a crear será a color RGB de un byte por componente. Además, la crearemos
del mismo tamaño que el recipiente utilizado en el formulario para presentarla
(400x400) y le indicaremos que inicialmente todos sus píxeles serán negros: Image<Bgr, Byte> im = new Image<Bgr, Byte>(400, 400, new Bgr(0, 0, 0));
A la fuente le especificaremos el tipo y las escalas (tanto horizontal como vertical): MCvFont f = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 1, 1);
16. Para que reconozcan los tipos específicos de esta librería, hay que añadir en la parte
superior del fichero las referencias que se están utilizando: using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
17. Se puede apreciar que, aparte de los atributos que acabamos de añadir a la clase, solo
se encuentra visible el constructor, cuyo único contenido es una llamada a la función
InitializeComponent(). Tras dicha llamada, dibujaremos un determinado texto a
nuestra imagen para, posteriormente, mostrarla en el pictureBox creado.
18. El método “Draw” perteneciente a la clase “Image” se encuentra sobrecargado.
Haremos uso de la opción que nos permite dibujar una cadena de texto en la imagen.
Le indicaremos al método el texto a dibujar, la fuente a utilizar (nótese que se indica
con la palabra “ref” delante, para denotar que se le pasa una referencia o un puntero),
el lugar donde dibujar (como un punto con coordenadas x e y) y, por último, el color
con el que se pintará (en nuestro caso, verde). im.Draw("EMGUcv", ref f, new System.Drawing.Point(140, 200), new Bgr(0, 255, 0));
19. Por ultimo, se mostrará el contenido de nuestra imagen sobre el pictureBox creado.
Para ello, el atributo “Image” del pictureBox se modifica con el contenido de nuestra
imagen. Como el pictureBox solo admite bitmaps, hacemos uso del método interno a
la clase “Image” que nos la convierte a bitmaps. Quedaría: pictureBox1.Image = im.ToBitmap();
20. Finalmente, quedaría lo siguiente:
21. Puede compilar y ejecutar el proyecto para comprobar que funciona correctamente.
B. Plantilla de proyecto de EmguCV
Partiremos del proyecto que se ha creado como ejemplo, de forma que crearemos un
template a partir de dicho proyecto y lo instalaremos entre las plantillas predeterminadas de
Visual Studio.
Así, se podrá partir del programa creado de ejemplo, sin necesidad de realizar todos los
pasos indicados anteriormente. Los pasos a seguir son los siguientes:
1. Con el proyecto abierto, seleccionamos la opción “Archivo” ”Exportar plantilla”. En
el asistente, seleccionaremos la opción “Plantilla de proyecto”.
2. A continuación, introducimos la información del proyecto. Excepto el nombre, las
demás opciones son opcionales.
3. IMPORTANTE desmarcar la opción “Importar la plantilla automáticamente en Visual
Studio”.
4. Finalizamos. Se guardará la plantilla en un archivo .zip.
5. Creamos un nuevo proyecto de Visual Studio. En este caso será un proyecto VSIX.
6. El proyecto se creará y nos aparecerá el manifiesto del proyecto para rellenarlo.
7. En primer lugar, rellenaremos los campos informativos: Nombre, descripción, autor,
etc.
8. Posteriormente, en la opción “Supported VS Editions”, seleccionaremos las ediciones
compatibles con nuestro template. Seleccionaremos:
9. Se añadirá el archivo zip (template) creado anteriormente. Dentro de la opción “Add
content”, seleccionamos el tipo “Project Template” y cargamos desde un archivo el
template originado en el proyecto anterior. Opcionalmente, se podrá seleccionar una
subcarpeta para dicho template, que se corresponderá con una subcategoría dentro
de las plantillas del Visual Studio. Para nuestro ejemplo:
10. Quedará finalmente:
11. Por último, se generará la solución del proyecto VSIX (“Generar” “Generar
solución”, o “F7”).
12. Ya se encuentra creado el complemento para añadir al Visual Studio. Cerramos el
entorno y nos dirigimos a la ruta donde se ha generado la solución del proyecto VSIX.
Hacemos doble click en el archivo “.vsix”, que instalará el complemento en el Visual
Studio.
13. Tras ello, ya se puede crear un nuevo proyecto en Visual Studio partiendo de la
plantilla creada:
C. Herramientas gráficas de EmguCV
Como se ha podido comprobar con el ejemplo
detallado, EmguCV hace uso de una serie de clases
propias para definir, almacenar y operar con imágenes.
Es por ello que EmguCV contempla una serie de
herramientas propias (del cuadro de herramientas de
Diseño) para poder mostrar la información en un
formulario.
Si bien, en el proyecto de ejemplo, se hacía uso de un
“pictureBox” para mostrar el contenido de una imagen,
se pudo apreciar que había que realizar una conversión
a bitmap para poder mostrar el contenido de dicha
imagen. Es por esto, y por otros ejemplos similares, que
EmguCV aporta una serie de herramientas para facilitar
el trabajar con dicha librería.
A continuación se detallan los pasos a seguir para
añadir esas herramientas a las predeterminadas de
Visual Studio para poder trabajar con ellas.
1. Nos dirigimos a la pestaña de diseño del formulario. En el cuadro de herramientas
(derecha), cliqueamos con el botón derecho y seleccionamos la opción “Elegir
Elementos”.
2. En la ventana que aparece, dentro de la pestaña “Componentes de .NET Framework”,
cliqueamos en el botón de “Examinar”.
3. Dentro de la ubicación de EmguCV, dentro de la carpeta “bin”, seleccionamos la
librería “Emgu.CV.UI.dll”.
4. Cargará automáticamente las herramientas de EmguCV y aparecerán en la pestaña
“General” del cuadro de herramientas de diseño.
D. Primer proyecto con EmguCV
Haremos uso de la plantilla creada para comenzar nuestro proyecto.
A partir de él, haremos uso de las utilidades para cargar imágenes, mostrarlas y aplicarles
ciertos tratamientos simples.
1. Cargar Imágenes: se realizará de dos formas diferentes.
a. Haciendo uso de una ruta estática, se puede cargar una imagen en la propia
inicialización del objeto “Image”:
Image<Bgr,Byte> im = new Image<Bgr, Byte>(“ruta_de_la_imagen.jpg”);
b. Haciendo uso de los diálogos de apertura de archivos que posee C#:
//Creamos el objeto
OpenFileDialog op = new OpenFileDialog();
//Seleccionamos el filtro utilizado (tipo de archivo)
op.Filter = "Imágenes JPEG (.jpg)|*.jpg";
op.FilterIndex = 0; //Con más de uno, así se seleccionaría la posición
//Abrimos el cuadro de diálogo
if (op.ShowDialog() == DialogResult.OK)
{
//Inicializamos la Imagen con la ruta obtenida del diálogo
im = new Image<Bgr, Byte>(op.FileName);
//Aquí se mostraría la imagen cargada (en el pictureBox)
}
2. Mostrar Imágenes:
Ya se ha visto en el proyecto de ejemplo cómo mostrar una imagen en un pictureBox, de
forma que en el formulario pueda apreciarse el contenido de dicha imagen.
De igual forma, podría mostrarse si se hace uso de la herramienta “ImageBox”, que es una
de las herramientas que nos proporciona EmguCV.
Esta herramienta, al estar pensada para trabajar con objetos de la clase “Image”, no
necesita de conversiones previas. Así pues, para mostrar el contenido de “im” en un
ImageBox, se haría lo siguiente:
imageBox1.Image = im;
3. Tratamientos sobre imágenes
En este apartado se expondrán una serie de tratamientos (simples y complejos) sobre
imágenes, haciendo uso de las funcionalidades que aporta EmguCV.
Para hacer la sesión más interactiva y entretenida, los siguientes apartados se aportan
a modo de “ejercicios” a realizar por el alumnado, con una breve explicación al respecto.
Ante cualquier duda puede consultar la web de EmguCV o, en última instancia, al
profesor.
a. Modifique el diseño del formulario, para mostrar 2 imageBox (elimine el pictureBox)
de 512x512 de tamaño, cada uno. Incluya un botón, que mostrará un cuadro de
diálogo y, de esa forma, poder seleccionar la imagen correspondiente. Incluya otro
botón, que servirá para activar la funcionalidad correspondiente que se pida en cada
apartado.
Puede probar con cargar cualquier imagen que quiera pero, por motivos
históricos, sería muy emotivo trabajar con la imagen clásica de visión artificial
(rostro de Lena Söderberg): puede encontrarla en google imágenes, o en
http://www.kitware.com/blog/files/128_1232259669.jpg.
b. Redimensionar la imagen: cómo ha podido comprobar, utilizar una dimensión de
512x512 abarca buena parte de la pantalla. Intente redimensionar los dos imageBox a
256x256. Al cargar la imagen de Lena, puede apreciar que solo muestra una cuarta
parte de la imagen. Haga uso del método “Resize” de la clase Image para
redimensionar la imagen a un tamaño de 256x256 píxeles. Para ello tendrá que
indicarle como primer y segundo parámetro el ancho y alto, respectivamente, al que se
redimensionará y, como último parámetro, la interpolación utilizada para ello (lineal,
cúbica, etc): se encuentran redefinidas dentro del enumerado “INTER”, de forma que
podrá indicar el tercer parámetro como INTER.CV_INTER_LINEAR (para interpolación
lineal). Pruebe con las otras interpolaciones, por si observa algún cambio
c. Acceso directo a los píxeles de una imagen: como atributo de la clase “Image” se
encuentra un array tridimensional denominado “Data”, al que se puede acceder de
forma pública y modificar el valor de las componentes de color de un determinado
píxel. Pruebe a pintar de color rojo (BGR a 0,0,255) un recuadro de la imagen y aprecie
el resultado.
d. Extraer sub-imagen: Haga uso del método “GetSubRect”, pasándole por parámetros un
rectángulo (clase Rectangle), inicializado con cuatro parámetros: posición ‘x’ inicial,
posición ‘y’ inicial, ancho y alto.
e. Convertir la imagen a escala de grises. Para ello utilice el método “Convert” de la clase
Image.
f. Aplique un filtro tipo “blur” sobre la imagen. Este tipo de filtros lineales, calcula el
nuevo valor de un píxel con respecto al de sus vecinos, de forma que se suelen utilizar
para eliminar el ruido de sal y pimienta. Para ello, haga uso de los métodos:
i. Blur de media: media aritmética del valor de un píxel con el de sus vecinos. Haga
uso del método “MedianBlur” y pasándole por parámetro el tamaño del kernel de
convolución a aplicar.
ii. Blur Gausiano: haga uso de la función “SmoothGaussian” y pasándole por
parámetro el tamaño del kernel de convolución a aplicar. Este no realiza la media
aritmética, sino una ponderada de forma que la participación del píxel depende
de la distancia con el central.
g. Binarizar la imagen: convertirla en una imagen en blanco y negro. Debe partir de la
imagen en escala de grises (si parte desde la imagen a color, lo que obtendrá es una
binarización en cada canal del color). En ambos casos deberá indicar un valor umbral
de binarización. Haga uso del método “ThresholdBinary”, pasándole por parámetro el
umbral y el valor máximo a utilizar en caso de superar dicho umbral.
i. Inserte un control de tipo “ScrollBar” en su aplicación (con un valor entre 0 y 255)
y utilice el valor devuelto para binarizar la imagen con dicho valor. Utilice el
evento generado por la barra de desplazamiento para aplicar la conversión en el
mismo momento. De esa forma, podrá apreciar cómo se modifica la imagen a
medida que mueve la barra de desplazamiento.
h. Transformaciones afines: giros, traslaciones, etc.
i. Dar la vuelta: hacer uso del método “Flip”, al que se le podrá pasar dos
parámetros: FLIP.HORIZONTAL o FLIP.VERTICAL; para efectuar el cambio
horizontal o verticalmente.
ii. Rotación: hacer uso de la función “Rotate”, a la que se le pasa el ángulo de
rotación y un color (el que se utilizará para rellenar el fondo en caso de que
ningún píxel coincida en una posición concreta).
iii. Inserte un control de tipo “ScrollBar” en su aplicación (con un valor entre 0 y 360)
y utilice el valor devuelto para utilizarlo como ángulo giro de la imagen. Utilice el
evento generado por la barra de desplazamiento para aplicar el giro en el mismo
momento. De esta forma, podrá apreciar los cambios mientras mueve la barra.
i. Operadores morfológicos comunes:
i. Erosionar una imagen: obtención del esqueleto de la imagen. Reduce aquellos
patrones gruesos de la imagen. Hacer uso del método “Erode”, pasándole por
parámetros el número de iteraciones utilizadas para erosionar la imagen.
ii. Dilatar la imagen: justamente lo opuesto a la anterior. Hacer uso de la función
“Dilate”, e indicándole por parámetros el número de iteraciones a realizar.
j. Filtros derivativos: utilizados para detectar cambios en una imagen.
i. Operador de Sobel: operador discreto que calcula, aproximadamente, el gradiente
de la intensidad de la imagen. Hay que partir de la imagen monocromática para
obtener buenos resultados. Aplica el gradiente horizontal y el vertical
(dependiendo de los parámetros). Puede utilizarlo, haciendo uso del método
“Sobel”, pasándole por parámetros: un entero (0 o 1) que indica si se realizará la
derivada respecto a X, otro entero (0 o 1) que indica si se realizará la derivada
respecto a Y, y un último entero que indica el tamaño del kernel. Para aplicar uno,
pruebe a llamar al método con los parámetros “1, 0, 3”. Pruebe con otras
combinaciones. Este filtro detecta variaciones significativas en la intensidad de los
píxeles y las acentúa.
ii. Operador Laplaciano: uso de la transformada discreta de Laplace. Derivada de la
intensidad de segundo orden. Se correspondería con aplicar la derivada al
resultado aportado por el operador de Sobel (internamente lo llama). A las
variaciones acentuadas tras aplicar Sobel, este filtro las detecta y se queda
únicamente con estas variaciones para mostrar los bordes de la imagen. Haga uso
de ella con el método “Laplace” y pasándole como argumento el tamaño del
kernel.
iii. Detector de bordes “Canny”: detector óptimo de bordes. Aplica filtro Gaussiano,
Sobel y Laplace con unos kérneles concretos, y de forma iterativa, para obtener de
forma óptima los bordes. Se hace uso de él llamando al método “Canny”, con dos
parámetros que especificarán el mínimo y máximo umbral de binarización,
respectivamente, entre los cuales el método buscará el óptimo.
iv. Modifique su aplicación para que, en el detector “Canny”, los dos parámetros
umbrales vengan aportados por dos barras de desplazamiento (así podrá apreciar
los resultados de hacer las modificaciones en tiempo real).
k. Redimensionar utilizando pirámides: En un comienzo se ha indicado un mecanismo
muy simple para redimensionar imágenes. El problema de dicho mecanismo era que se
basaba en multiplicar la información (al aumentar el tamaño) o en eliminar
información (al disminuir el tamaño). El resultado de este redimensionamiento puede
ocasionar pérdidas graves en el contenido de la imagen o una visualización muy
artificial. Para ello, hay un mecanismo de redimensionamiento de la imagen que hace
uso de las transformadas gaussianas y laplacianas para extrapolar el contenido de los
píxeles con respecto a sus vecinos; obteniendo así un resultado mucho más óptimo al
redimensionar. Haga uso del método “PyrDown” para reducir la imagen de forma
piramidal y “PyrUp” para ampliar la imagen de forma piramidal. ¿Observa algo
interesante?
l. Detección de líneas rectas: para detectar las líneas, se hace uso de un sistema de
coordenadas polares, de forma que un punto viene definido por dos valores (rho y
theta). Para un punto concreto con coordenadas cartesianas, al representarlo con
coordenadas polares (variando ambas), se mostraría una representación sinusoidal.
Esto que quiere decir: que nuestro algoritmo aplicará estas transformaciones a polares
con todos los puntos y, aquellos cuyos senos coincidan en un punto son propensos a
encontrarse en la misma línea. Obviamente, mientras más puntos coincidan se
obtendrá una mayor precisión. Así pues, pasando a la práctica, el método encargado
de buscar líneas rectas es “HoughLines”, al que se le pasa por parámetros: el mínimo y
máximo umbral de binarización (para utilizarlos con “Canny”), la resolución de rho (en
píxeles) y de theta (en grados) en las representaciones sinusoidales (cuantización de
dichos valores), un umbral que denotará el número de puntos cartesianos cuyas
representaciones polares deben converger en un punto (mínimo para denotarlo como
línea), el tamaño mínimo de la línea y la distancia mínima entre puntos para ser
considerados como línea.
Trabajando con la imagen en escala de grises, devuelve un “LineSegment2D[][]”, de
forma que la primera coordenada solo posee un posible valor (0), mientras que la
segunda contiene todas las líneas (una por posición y de tipo Segment2D). Para
pintarlas, podemos hacer uso del método “Draw” de la clase Image.
m. Detección de círculos: para detectar un círculo, se lleva a cabo un proceso análogo al
de detección de líneas. En este caso, un círculo vendrá descrito por dos coordenadas
(punto central) y el radio. Para los círculos, se implementa un método más eficaz y
simple que el de las líneas. Haga uso del método “HoughCircles”, que recibe por
parámetros: el umbral mayor de “Canny”, el umbral para la detección del centro del
círculo, la resolución con la que trabajar (1: 100% de la imagen), mínima distancia
entre círculos, radio mínimo y radio máximo (ambos radios puedes ser 0, y se
encargaría el método de buscar todas las posibilidades). El método devuelve un
“CircleF[][]” que, al igual que pasaba en el apartado anterior, tiene una sola fila (por
ser una imagen en escala de grises) y las columnas indican los diversos círculos.
Igualmente podrá usar el método “Draw” de Image.
n. Operaciones con histogramas: un histograma es una representación gráfica de una
variable, en forma de barras, donde la superficie de la barra es proporcional a la
frecuencia de los valores representados. En visión artificial, se suele utilizar para
denotar la distribución de la luminosidad en una imagen monocromática (frecuencia
de cada posible valor de la escala de grises). Esta información es muy útil para extraer
determinadas características de la imagen, así como para aplicar diversos tratamientos
sobre ella.
i. Ecualizar el histograma: expande homogéneamente las “barras” del
histograma, de forma que amplia el rango de valores de la escala de
grises que aparecen en la imagen, permitiendo aumentar el contraste
de la misma. Haga uso del método “_EqualizeHist()”.
ii. Calcular y mostrar el histograma: Para ello, en primer lugar, hay que
crear un objeto de tipo “DenseHistogram”, e indicarle el valor máximo
y el rango de valores en su inicialización: DenseHistogram Histo = new DenseHistogram(255, new RangeF(0, 255));
Con la imagen en escala de grises, se puede calcular su histograma
hacienda uso del método “Calculate”, que recibe por parámetros: un
vector de Image (por si se quiere mostrar más de un histograma a la
vez – en nuestro caso: new Image<Gray, Byte>[] {im}), el segundo y
tercer parámetros se utilizan para opciones específicas a la hora de
mostrar varios histogramas (en nuestro caso, valdrán “false” y “null”,
respectivamente).
Por último, ¿cómo lo mostramos en nuestra aplicación?... ¿te acuerdas
del HistogramBox del cuadro de herramientas? Tendrás que crear uno
y hacer uso de su método “AddHistogram” (al que se le pasa el
nombre, el color y el histograma) y, por último, utilizar el método
“Refresh” para refrescar el histograma.
o. Correspondencia de patrones: buscar un determinado patrón en la imagen o, lo que es
lo mismo: dada una imagen, detectar las apariciones de ella en otra imagen.
Aparentemente, el uso del método “MatchTemplate” puede parecer simple (debido a
que solo recibe por parámetros la imagen plantilla y el método de normalización de los
coeficientes –que utilizaremos el TM_TYPE.CV_TM_CCOEFF_NORMED-) pero, tras su
ejecución hay que realizar otras tareas. Nos devuelve una imagen, pero cada posición
de esta imagen representa la probabilidad de que ese punto (x e y) sea el punto de
comienzo de la plantilla pasada. Así pues, lo que habrá que hacer a continuación es
buscar sobre todos ellos (con un porcentaje estipulado por nosotros -normalmente
mayor al 70%-) y mostrar un recuadro sobre aquellos que superen nuestro umbral.
Para facilitar la tarea de buscar sobre los elementos de una imagen, la convertiremos a
un array de elementos tipo float haciendo uso de “float[,,] porcentajes = im.Data;”.
Tras ello, haremos una búsqueda secuencial por todas las filas y columnas de este
array (dos primeras componentes), con la tercera componente a 0 (es una imagen en
escala de grises). Para cada valor que supere 0.75 (por ejemplo) lo pintaremos. Puede
hacer uso del método “Draw” de Image o, incluso, crear un “Rectangle” con punto de
inicio en la posición actual y con un ancho y alto igual al de la plantilla.