Informe - Escuela de Ingeniería Eléctrica

Anuncio
Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
IE – 0502 Proyecto Eléctrico
Determinación de la posición de un objeto
utilizando una cámara Web
Por:
Juan Antonio Lara Flores
Julio del 2004
IE-0502
ii
Determinación de la posición de un objeto utilizando una cámara Web
Determinación de la posición de un objeto
utilizando una cámara Web
Por:
Juan Antonio Lara Flores
Sometido a la Escuela de Ingeniería Eléctrica
de la Facultad de Ingeniería
de la Universidad de Costa Rica
como requisito parcial para optar por el grado de:
BACHILLER EN INGENIERÍA ELÉCTRICA
Aprobado por el Tribunal:
___________________
Ing. Federico Ruiz
Profesor Guía
___________________
___________________
Ing. Lucky Lochi Yu
Dr. Jaime Fornaguera
Profesor Lector
Profesor Lector
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
iii
DEDICATORIA
A toda mi familia, en especial a mis padres y a mi novia, por
todo el apoyo que me dieron para lograr vencer los retos
impuestos y llegar a esta etapa de mi vida que gracias a Dios esta
culminando satisfactoriamente, muchas gracias a todos...
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
iv
RECONOCIMIENTOS
Llegando a esta etapa de la vida, donde se culmina con gran
esfuerzo una labor iniciada cinco años atrás, se debe reconocer a mis
padres los cuales me han facilitado todo lo necesario para que
obtenga los conocimientos que hoy tengo, gracias a todos los
profesores que me han enseñado todo lo necesario para poder ser un
profesional útil a los demás y versátil en el campo laboral.
Muchas gracias a todos los profesores, en especial a Alexis
Maldonado el cual me brindó su apoyo durante la elaboración de
este proyecto hoy terminado exitosamente, aportando las ideas
necesarias para su elaboración.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
v
ÍNDICE GENERAL
ÍNDICE GENERAL.................................................................................. v
ÍNDICE DE FIGURAS ........................................................................... vii
ÍNDICE DE TABLAS ............................................................................ viii
NOMENCLATURA................................................................................. ix
RESUMEN ................................................................................................ x
CAPÍTULO 1: Introducción ..................................................................... 1
1.1
1.2
1.3
1.4
Objetivos ..........................................................................................................................1
Problema a resolver .........................................................................................................2
Justificación del tema ......................................................................................................3
Metodología .....................................................................................................................5
CAPÍTULO 2: Desarrollo teórico ............................................................. 6
2.1 Imágenes digitales .....................................................................................................................6
2.1.1
Concepto de imagen digital ............................................................................6
2.1.2
Muestreo espacial y niveles de gris ................................................................6
2.1.3
Relaciones entre píxeles: Vecindad y Conectividad.......................................8
2.1.4
Color ...............................................................................................................9
2.1.5
Espacio RGB ................................................................................................10
2.1.6
Reconocimiento de objetos ...........................................................................11
2.1.7
Determinación del centroide del objeto determinado...................................12
2.2
Preprocesamiento de imágenes digitales .......................................................................13
2.2.1
Definición.....................................................................................................13
2.2.2
Eliminación de Ruido ...................................................................................13
2.2.3
Filtros pasobajos lineales espaciales.............................................................14
CAPÍTULO 3: Análisis del programa..................................................... 16
3.1
Estructuración del programa ..........................................................................................16
3.1.1
Archivo interfaz.h.........................................................................................16
3.1.2
Archivo interfaz.cpp .....................................................................................17
3.1.3
Programas para abrir las imágenes tomadas .................................................19
3.1.4
Programas makefile para la compilación de los archivos.............................20
3.2
Resultados de las pruebas realizadas al programa .........................................................22
3.2.1
Primera prueba ..............................................................................................22
3.2.2
Segunda prueba.............................................................................................25
3.2.3
Tercera prueba ..............................................................................................30
3.2.4
Tiempos de ejecución del programa .............................................................34
CAPÍTULO 4: Conclusiones y recomendaciones .................................... 37
Agosto del 2004
IE-0502
4.1
4.2
Determinación de la posición de un objeto utilizando una cámara Web
vi
Conclusiones ..................................................................................................................37
Recomendaciones ..........................................................................................................39
BIBLIOGRAFÍA..................................................................................... 40
ANEXOS ................................................................................................. 41
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
vii
ÍNDICE DE FIGURAS
Figura 2.1 Vecinos en el plano vertical y horizontal de un píxel.......................................8
Figura 2.2 Vecinos asociados a las diagonales de un píxel................................................9
Figura 2.3 Espacio RGB ..................................................................................................11
Figura 2.4 Máscara utilizada en el filtro ..........................................................................15
Figura 3.1 Fotografía de la posición de un objeto ............................................................22
Figura 3.2 Fotografías de algunas de las posiciones del objeto durante la prueba ..........23
Figura 3.3 Fotografía de una posición del objeto ............................................................24
Figura 3.4 Fotografía de los centroides obtenidos durante la prueba ..............................24
Figura 3.5 Fotografías de algunas de las posiciones del objeto durante la prueba ..........25
Figura 3.6 Fotografía de una posición tomada durante la prueba....................................26
Figura 3.7 Fotografía en escala de grises del objeto durante la prueba ...........................27
Figura 3.8 Fotografía de los centroides del objeto durante la prueba..............................27
Figura 3.9 Fotografía de algunas posiciones del objeto durante la prueba......................31
Figura 3.10 Fotografía en escala de grises del objeto ......................................................31
Figura 3.11 Fotografía de los centroides del objeto durante la prueba............................32
Figura 3.12 Fotografía en escala de grises del fondo dividido en zonas .........................33
Figura 3.13 Fotografía de una posición del objeto ..........................................................33
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
viii
ÍNDICE DE TABLAS
Tabla 2.1 Tiempos de ejecución del programa .................................................................34
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
ix
NOMENCLATURA
X
Distancia desde el origen a un punto en el eje de las abscisas
Y
Distancia desde el origen a un punto en el eje de las ordenadas
F(x,y) Función que describe la imagen por posición
I(x,y) Función de iluminación de la imagen por posición
R(x,y) Función de reflexión de la imagen por posición
N
Número de píxeles en el eje de las abscisas
M
Número de píxeles en el eje de las ordenadas
b
Número de total de bits de la imagen
G
Número que determina el número de bits por píxel de la imagen
N4(p) Representación de los vecinos verticales y horizontales de un píxel
ND(p) Representación de los vecinos en las diagonales de un píxel
N8(p) Representación de los ocho píxeles que rodean a un píxel
Qy
Distancia de un punto del objeto a el origen en el eje y
Qx
Distancia de un punto del objeto a el origen en el eje x
A
Área del objeto
x
Posición del centroide de un objeto en el eje x
y
Posición del centroide de un objeto en el eje y
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
x
RESUMEN
Para resolver el problema de determinar las posiciones en las cuales se movió un
ratón dentro de un laberinto se buscó solucionar el problema utilizando una cámara Web,
esto debido a la velocidad con la que pueden tomar fotos y a la facilidad que se tiene en el
sistema operativo Linux, para poder manejarla. En la captura de imágenes se utilizó un
programa escrito en el lenguaje de programación C encontrado en la red, el cual se
modificó para adaptarlo a las necesidades del programa que va a determinar las posiciones.
Inicialmente se debe tomar la foto del fondo, la cual se va a utilizar de base de comparación
para las otras fotos tomadas con el ratón en el laberinto. Con el objetivo de facilitar el uso
del programa se va a tener la opción de ejecutar el programa por un tiempo determinado, el
cual lo ordena el usuario, este va a tener un rango de uno a diez minutos para escoger y con
la opción de variar el tiempo de ejecución en minutos únicamente.
Durante las pruebas del programa, se observó como los resultados se veían alterados
luego de haber tomado fotos por un tiempo, esto cuando se ejecutaba el programa por
primera vez luego de haber cargado el sistema operativo. Luego de varias pruebas se llegó
a la conclusión de que el motivo es un ajuste que realiza la cámara durante este tiempo, por
lo que para prevenir que esto afecte los resultados se hizo una opción que toma fotos
durante dos minutos para darle el tiempo requerido a la cámara para que ajuste la
iluminación.
Además se hicieron pruebas de tiempo para determinar el tiempo que dura la
cámara tomando una foto, donde este tiempo depende de la máquina en la cual se esté
corriendo el programa, por lo que para instalar el programa en una computadora diferente
se debe determinar este tiempo y cambiar los datos dentro del programa, para obtener la
precisión requerida por el usuario.
Debido al proceso utilizado para determinar la posición del objeto, durante la
ejecución del programa se debe contar con una iluminación constante y evitar que se mueva
la cámara durante la toma de fotos, ya que estas dos situaciones varian los valores de cada
píxel en las fotografías del fondo y de la posición del objeto, lo cua l va a provocar
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
xi
diferencias en píxeles que no forman parte del objeto, con lo que se darán errores en los
resultados.
Tomando en cuenta lo anterior y una vez realizadas una gran cantidad de pruebas al
programa, corrigiendo las posibles fuentes de error, se concluye que si se toman en
consideración las recomendaciones dadas, este programa que utiliza una cámara Web, es
una solución viable para solucionar el problema planteado, ya que con él se han obtenido
resultados satisfactorios siempre y cuando se ejecute correctamente.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
1
CAPÍTULO 1: Introducción
1.1 Objetivos
1.1.1 Diseñar un programa utilizando el lenguaje C++ para que se puedan obtener las
posiciones de un ratón que se mueve en un laberinto, tomando fotografías con una
frecuencia adecuada, determinándose las posiciones en que se encontró el animal.
1.1.1.1 Montar una plataforma de Linux en la versión brindada por Debian para contar con
los módulos necesarios para la cámara Web que se utiliza y de video for linux para
su manejo.
1.1.1.2 Conocer las principales herramientas del lenguaje de programación C++,
lográndose con ello la mayor eficiencia en el diseño del programa que se
implemente.
1.1.1.3 Utilizar un método de programación estructurado, que permita un desarrollo del
programa adecuado y fácil de comprender.
1.1.1.4 Utilizar óptimamente el programa mvc, el cual se va a aprovechar para tomar las
fotografías del laberinto en el cual se esta moviendo el ratón.
1.1.1.5 Brindar al usuario la zona y la posición en coordenadas donde se encontró el ratón,
mediante el cálculo de su centro de masa, para que se determine con exactitud la
posición en donde se detectó.
1.1.1.6 Construir una imagen dividida en zonas donde se muestran puntos en las
coordenadas donde se encontró el ratón, y además de imprimirse las fotografías de
cada posición que se determinó, en el cual se brinde al usuario un medio para
corroborar la validez de cada uno de los datos obtenidos.
1.1.1.7 Crear un archivo en el cual se tenga una lista de las posiciones obtenidas, mostrando
la posición y la zona a la cual pertenece esa coordenada que se averiguó.
1.1.1.8 Diseñar una interfaz gráfica para el programa, que brinde al usuario herramientas
visuales fáciles de manejar, donde se le indiquen los pasos a seguir y los cuidados
que debe tener cuando ejecuta el programa.
Agosto del 2004
IE-0502
1.2
Determinación de la posición de un objeto utilizando una cámara Web
2
Problema a resolver
El presente proyecto busca resolver la necesidad de la escuela de medicina de la
Universidad de Costa Rica para realizar análisis del comportamiento de un ratón
moviéndose en un laberinto. Lo que se busca es un sistema para determinar las posiciones
en las cuales se encontró el ratón durante la prueba en el laboratorio, esto utilizando una
cámara web manejada por una computadora que procese las fotografías tomadas e imprima
los resultados obtenidos.
Agosto del 2004
IE-0502
1.3
Determinación de la posición de un objeto utilizando una cámara Web
3
Justificación del tema
La escogencia del tema de este proyecto se dio debido a la necesidad que se tiene en
la escuela de medicina de la Universidad de Costa Rica de una herramienta adecuada para
realizar experimentos en los que se estudie el comportamiento de un ratón moviéndose en
un laberinto, determinando las zonas en las que éste se mueve.
Dado que para obtener las posiciones en las que se encuentra el ratón en cada
instante del experimento se hacía una tarea muy tediosa y poco exacta, es que surge como
solución a éste problema se va a ins talar una cámara Web en el sistema operativo Debian
GNU/Linux, debido a que este sistema operativo brinda una mayor flexibilidad para que se
manipule la cámara con un programa utilizando el lenguaje de programación C++. Éste
cuenta con librerías para poder procesar adecuadamente las fotografías obtenidas y utilizar
una serie de técnicas que permitan determinar la posición exacta del ratón y la zona en la
que está.
La solución propuesta brinda una muy buena herramienta si se cumple con una serie
de requisitos para que la mayoría de los resultados tengan la posición exacta en la que se
encontraba el ratón en el momento de tomar la fotografía. Es importante que se tome en
cuenta que cualquier pequeña variación durante el tiempo de ejecución del programa,
pueden afectar radicalmente los resultados, por lo cual es de vital importancia que se cuiden
la iluminación y la posición de la cámara, para poder garantizar una alta confiabilidad en
los datos del programa.
Este proyecto brinda una óptima solución a un problema utilizando todas las
ventajas que brinda la tecnología actual, donde se está dando un aprovechamiento de
algunas herramientas que brinda actualmente el sistema operativo Linux, dado al fácil
acceso que brinda hacia las partes estructurales del computador utilizado, además de la
facilidad con la que se puede ejecutar en éste el programa que se va a diseñar. Además de
esto, es importante mencionar que los conocimientos necesarios para que se lleve a cabo el
proyecto se encuentran en libros y direcciones en la red donde se pueden adquirir todas las
herramientas que puedan hacer el programa más eficiente y se aumente la confianza en los
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
4
datos que se obtengan. Para poder corroborar cuales posiciones calculadas son incorrectas
se añade la fotografía del objeto en cada una de las posiciones determinadas, para que se
verifique rápidamente cuales son los datos confiables y cuales sufrieron de variaciones que
afectaron los resultados al instante en que se tomó la fotografía del objeto.
Agosto del 2004
IE-0502
1.4
Determinación de la posición de un objeto utilizando una cámara Web
5
Metodología
La metodología a seguir para solucionar el problema propuesto tiene como primer
paso montar la platarforma a utilizar en Linux , inicialmente para poder utilizar la cámara
Web se debe recompilar el Kernel, donde se incluyen en él los módulos necesarios para
manejar los dispositivos de la computadora utilizada, el de la cámara que se tiene y el de
Video for Linux, el cual es el módulo que brinda las herramientas necesarias para poder
controlar los dispositivos de video.
Una vez que se tenga instalado Linux, se debe de conseguir una manera para tomar
las fotografías necesarias para que se pueda determinar la posición del ratón en el laberinto.
Las fotos se necesitan tomar con una frecuencia mínima de una foto por segundo y se van a
almacenar en la carpeta donde se encuentran los archivos del programa.
Luego de que se tienen las fotos en la carpeta del programa, se procesan primero
para cambiarlas de imágenes en colores a imágenes en niveles de grises. Teniendo la foto
del fondo en gris, se va a comparar con las fotos en gris del objeto moviéndose. El
resultado de esta comparación será una imagen de una figura en negro con la forma del
objeto en la posición en que se encontraba en ese instante, después de obtenerla, ésta se
almacena en la carpeta del programa junto con las demás fotografías.
Las imágenes resultantes de la comparación se utilizan para calcular el centro de
masa del objeto y saber el punto exacto en que se encontraba. Una vez que se tiene el
centroide en los ejes horizontal y vertical se imprimen en un archivo, en el cual se
encuentran las demás posiciones determinadas y el instante en el cual el objeto se
encontraba en esta posición.
Por último se implementa una interfaz gráfica para el programa, la cual va a brindar
al usuario las herramientas para ejecutar el programa y luego poder observar fácilmente los
resultados obtenidos.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
6
CAPÍTULO 2: Desarrollo teórico
2.1 Imágenes digitales
2.1.1 Concepto de imagen digital
El concepto de imagen digital esta asociado a una función de dos dimensiones
f(x,y), en donde cada coordenada contiene una amplitud, la cual determina el grado de
iluminación de la imagen en ese punto, esto tomando como punto de referencia un lugar
específico de la imagen. Dado a que esta magnitud la determina la iluminación, es por ello
que se da una dependencia de la de la cantidad de luz que incide sobre la escena vista en la
imagen, así como de la parte que sea reflejada por los objetos que componen dicha imagen.
Estos componentes son llamados iluminación definida como i(x,y) y reflexión definida
como r(x,y) respectivamente; con lo que si se multiplican ambas cantidades en una
coordenada específica, se obtiene como resultado la amplitud de la función f(x,y), teniendo
entonces:
f ( x, y) = i ( x, y )r ( x, y)
(1)
teniendo como intervalos de definición:
0 < i ( x, y ) < ∞
0 < r ( x, y) < 1
(2)
0 < f ( x, y ) < ∞
(3)
por lo que se tiene:
La naturaleza de la iluminación viene determinada por la fuente de luz, mientras
que la reflexión depende de las características del objeto en escena, dado a esto es que se
tiene que ambas cantidades siempre son positivas, pero para la iluminación se tiene un
rango infinito, mientras que para la reflexión se tiene limitado por 1.
2.1.2 M uestreo espacial y niveles de gris
Las imágenes dependiendo del número de variables puede ser unidimensional o
bidimensional, al igual que dependiendo de las dimensiones de la función pueden ser
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
7
escalares, como es el caso de las imágenes en blanco y negro, o vectoriales, como las
imágenes en color, que cuentan con tres componentes. Las imágenes tienen un dominio y
un rango discretos, dado a que se determinan como señales digitales; donde se tiene una
imagen definida por la función f(x,y) y esta se puede digitalizar en la memoria del
computador, dando la posición en coordenadas y la magnitud en dicha posición,
obteniéndose como resultado una matriz de valores de NxM elementos, donde N determina
los espacios en x y M los espacios en y, obteniendo como resultado:
f(0,0) ................... f(N - 1,0)
 .
.
f ( x, y) = 
 .
.

f(0, M - 1) ................ f(N - 1, M - 1)






(4)
esto teniendo como origen la esquina superior izquierda de la imagen.
Debido a que las imágenes son originalmente señales analógicas, se debe de darse
un muestreo de las dos dimensiones espaciales para convertirlas a señales digitales, por lo
que como se muestra en la fórmula anterior lo que se almacena en el computador en cada
una de los elementos de la matriz es una cantidad que dependiendo de su amplitud así será
el nivel de gris de la imagen es dicha posición, dándose una cuantificación de la señal
analógica, de donde proviene el concepto de nivel de gris o intensidad. Cada una de las
posiciones que determina cada uno de los elementos de la matriz anterior reciben el nombre
de pixeles. Para el caso en que se tienen 256 niveles de gris, la magnitud de cada píxel va a
encontrarse dentro del rango de 0 a 255, donde 0 corresponde a negro, o sea, donde no hay
iluminación o se absorbe todos los rayos que inciden sobre el objeto y 1 corresponde a
blanco, o sea, donde se esta dando una iluminación máxima del objeto.
Para el proceso de digitalización de una imagen se debe precisar el tamaño de la
imagen, dando valores determinados a N y M, así como los niveles de gris que se le asignen
a cada píxel. En la práctica, es común que los niveles vengan determinados por números
potencias de 2, donde se tiene entonces que el número de bits requeridos para almacenar
una imagen digitalizada es:
b = NMg
(5)
Agosto del 2004
IE-0502
8
Determinación de la posición de un objeto utilizando una cámara Web
donde los niveles de gris vienen determinados por 2g .
Otro concepto importante que surge en el procesamie nto de imágenes es la
resolución, el cual viene asociado al número de muestras y niveles de gris necesarios para
tener una buena aproximación de la imagen. Estos conceptos definidos anteriormente se
encuentran muy ligados y de ellos depende la calidad de la imagen.
Una vez que se tienen definidas las resoluciones, surge el concepto de histograma,
el cual es un gráfico muy conocido en la estadística. Para el caso de las imágenes, el
histograma va a contener el número de píxeles que tienen el mismo nivel de gris, por lo que
este puede entenderse como la probabilidad de que un valor de gris determinado se tenga en
la imagen, pero éste tiene el inconveniente de que no aporta las posiciones en las que se
están dando estos niveles de gris, sólo el número de veces que se dieron.
Ahora bien, es importante que se profundice más en los bits; ya que ellos dan origen
a un último elemento presente en la imagen, los planos de bits. Para comprenderse mejor
esto, es necesario que se observe cual es la potencia de dos utilizada, ya que si por ejemplo
se tiene g=3, cada píxel de la imagen va a contar con 8 bits, dando origen a un byte. Cada
plano de bits, es una imagen formada por un determinado bit de cada píxel. La importancia
de estos es que revelan muy bien la influencia del ruido en la imagen.
2.1.3 Relaciones entre píxeles: Vecindad y Conectividad
Un píxel p con coordenadas (x,y) tiene un total de cuatro vecinos en dos
dimensiones, estos en forma vertical y horizontal, como se observa en la siguiente figura:
x,y-1
x-1,y
x,y
x+1,y
x,y+1
Figura 2.1 Vecinos en el plano vertical y horizontal de un píxel
Este conjunto de píxeles mostrados en la figura 2.1 se denomina vecindad de tipo 4
del píxel p, representada por N4(p). Además se puede considerar la existencia de otros
cuatro vecinos asociados a las diagonales, como se ilustra en la siguiente figura:
Agosto del 2004
IE-0502
9
Determinación de la posición de un objeto utilizando una cámara Web
x-1,y-1
x+1,y-1
x,y
x-1,y+1
x+1,y+1
Figura 2.2 Vecinos asociados a las diagonales de un píxel
Y estos píxeles que se encuentran en las diagonales del pixel de la posición (x,y) se
representa como ND(p) y sumandos a los vecinos que se muestran en la figura 2.1 dan
origen a la representación N8(p), donde se tienen 8 vecinos para el píxel en (x,y).
Otro concepto importante es el de conectividad, el cual se utiliza para expresar
cuando dos píxeles vecinos pertenecen al mismo objeto, esto se determina por algún
criterio de especificación, si por ejemplo ambos píxeles poseen el mismo nivel de gris y son
vecinos.
Para la conectividad se tienen tres tipos:
1. Conectividad-4. Dos píxeles p y q presentan una conectividad-4 si q pertenece a
N4(p).
2. Conectividad-8. Dos píxeles p y q presentan una conectividad-8 si q pertenece a
N8(p).
3. Conectividad-m. Dos píxeles p y q presenta conectividad mixta si:
a) q pertenece a N4(p), o
b) q pertenece a Nd(p) y el conjunto N4(p)∩N4(q) es el conjunto vacío.
La conectividad mixta es una modificación de la conectividad-8 cuya utilidad es
eliminar las conexiones múltiples que en ocasiones aparecen cuando la conectividad-8 es
utilizada. La conectividad tipo 8 es utilizada para determinar cuando dos píxeles pertenecen
al mismo objeto.
2.1.4 Color
El color en una imagen, es un concepto hasta hace poco utilizado para las imágenes,
dado a que se tiene un alto costo en cuanto a la memoria necesaria para procesar las
imágenes a colores; lo cual a cambiado debido a los avances tecnológicas en la industria de
la informática, donde se mejora a un paso acelerado el hardware de las computadoras.
Agosto del 2004
IE-0502
10
Determinación de la posición de un objeto utilizando una cámara Web
Para el color de una imagen, se deben toma r en cuenta algunas definiciones para
comprender mejor los espacios de colores, teniendo entonces las siguientes definiciones:
2
Brillo: sensación que indica si un área está más o menos iluminada.
3
Tono: sensación que indica si un área parece similar al rojo, amarillo, verde o azul o a
una proporción de dos de ellos.
4
Coloración: sensación por la que un área tiene un mayor o menor tono.
5
Luminosidad: brillo de una zona respecto a otra blanca en la imagen.
6
Croma: la coloridad de un área respecto al brillo de una blanco de referencia.
7
Saturación: la relación entre la coloridad y el brillo.
Un espacio de color es un método por el cual se puede especificar, crear o visualizar
cualquier color. Dependiendo del tipo de sensor y aplicación se han desarrollado diversos
espacios de colores. Así se tienen espacios de colores que se utilizan para la adquisición, la
transmisión de señales y la impresión o los espacios que tratan de imitar la percepción
humana.
2.1.5 Espacio RGB
El espacio RGB se basa en la combinación de tres señales de iluminancia cromática
distinta: el rojo, el verde y el azul (red, green, blue). La manera más sencilla de conseguir
un color concreto es determinar la cantidad de color rojo, verde y azul que se necesita para
combinar, por lo que se realiza una suma de las componentes:
X = R+G + B
(6)
Esto se puede representar gráficamente como un cubo, donde en la recta que une el
valor máximo se hayan los grises, ya que las tres componentes son iguales; como se
observa en la siguiente figura:
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
11
Figura 2.3 Espacio RGB
Lo importante cuando se tiene una fotografía a color es tomarse en cuenta que para
cada píxel en color se tienen en realidad tres, uno para cada componente; la ganancia
máxima de cada uno de ellos corresponde a la longitud de onda de los tres colores básicos
(rojo, verde y azul). Este espacio es el utilizado para las cámaras, dado a que es el más
intuitivo, aunque presenta un inconveniente, ya que en sus tres valores mezcla la
información del color (tono y saturación) y la intensidad.
2.1.6 Reconocimiento de objetos
El reconocimiento de objetos es la principal herramienta del programa utilizado, ya
que por medio de esta técnica es que se va ha determinar en que posición es que se
encuentra el ratón dentro del laberinto.
La herramienta que se va a utilizar es muy sencilla, los pasos a seguirse son muy
sencillos y efectivos si se cuentan con condiciones idóneas.
Primero se realiza un
reconocimiento de la imagen base, en este caso el laberinto, donde se toma la fotografía sin
el objeto que se quiere observar. Esta fotografía se tiene a colores y aplicando los valores
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
12
para transformar la imagen en niveles de grises, procedimiento que se repite con la imagen
que se tome con el objeto dentro de la imagen base. Entonces finalmente se hace una
comparación de las imágenes realizando una resta píxel por píxel, donde si no se da una
diferencia en las condiciones en que se tomó la foto base y la foto con el objeto, entonces
sólo se va a dar una diferencia en los píxeles donde se encuentra el objeto, donde se
examina el resultado y se toma un valor límite, previniendo que se de también la presencia
de ruido.
De lo explicado anteriormente, es que se evidencia claramente como los cambios en
la iluminación van a afectar los resultados obtenidos, así como si se da un movimiento de la
cámara, ya que se va a tener una diferencia en cada píxel, al darse un desplazamiento de las
magnitudes de cada posición. Si se tiene la precaución de no tener ninguna de las dos
variaciones anteriores, es muy probable que los resultados del programa van a ser muy
buenos. Seguidamente se va a explicar como se encuentra el punto exacto en que se
encontró el objeto, esto se hace encontrando el centroide del objeto, mediante los principios
físicos, aplicados a la imagen.
2.1.7 Determinación del centroide del objeto determinado
Para la determinación del centroide del objeto encontrado, se utilizan las fórmulas:
Qy = X ∑ A = ∑ xA
(7)
Qx = Y ∑ A = ∑ yA
Teniendo estas fórmulas en cuenta, se realiza un barrido de los píxeles determinados
donde se encuentra el objeto y se realiza una sumatoria de todos los píxeles que conforman
al objeto encontrado, tomando esto como el área A del objeto. El punto donde se encuentra
el centroide en las fórmulas se denomina como x y y en los ejes, por lo que se debe de
realizar una sumatoria de las distancias de cada píxel del objeto con referencia a la esquina
superior izquierda que es el punto (0,0), entonces aplicando las fórmulas:
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
x =∑
13
Qy
A
Q
y=∑ x
A
(8)
en donde se tiene que el centroide del objeto encontrado es ( x , y ).
2.2
Preprocesamiento de imágenes digitales
2.2.1 Definición
El preprocesamiento de imágenes comprende aquellos algorit mos cuya finalidad es
conseguir una mejora en la apariencia de la imagen original. Dependiendo de la aplicación
que se le vaya a dar a la imagen, se hace un aumento en las características que se desean
resaltar de la imagen a procesar o eliminar lo que dificulta que la imagen resultante sea
como se espera. Es importante tomar en cuenta que para el preprocesamiento de imágenes,
el objetivo de esta etapa es hacer de la imagen más clara para el computador, por lo cual no
siempre se tiene va a tener un resultado que sea visible para el usuario, ya que si se desea
realizar una comparación entre dos imágenes, lo importante es eliminar lo más que se
puede las variaciones que se tengan en cuanto a la iluminación principalmente, por lo que
se hace necesario aplicar filtros para evitar en la mayoría de lo posible este inconveniente.
2.2.2 Eliminación de Ruido
Todas las imágenes poseen ruido, este ruido se manifiesta en la imagen como
píxeles aislados que toman un valor distinto al de sus vecinos. Existen varios tipos de
filtros que se mencionan a continuación y se basan en esta característica. El ruido se puede
clasificar en cuatro tipos:
•
Gausiano : Produce pequeñas variaciones en la imagen. Es debido, por ejemplo, a
las diferentes ganancias en el sensor, ruido en los digitadores, perturbaciones en la
transmisión, etc. En los filtros de este tipo se tiene que el valor final del píxel sería
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
14
el ideal más una cantidad correspondiente al error, que puede describirse como una
variable gausiana.
•
Impulsional: El valor que toma el píxel no tiene relación con el valor ideal sino
con el valor del ruido que toma valores altos o bajos. Se caracteriza entonces
porque el píxel toma un valor máximo, causado por una saturación del sensor, o
mínimo, si se ha perdido su señal. También puede encontrarse si se trabaja con
objetos a altas temperaturas, ya que las cámaras tienen una ganancia en el infrarrojo
de la que no dispone el ojo humano. Por ello las partes muy calientes de un objeto
pueden llegar a saturar el píxel.
•
Frecuenc ial: La imagen obtenida es la suma entre la imagen ideal y otra señal, la
interferencia, caracterizada por ser una senoide de frecuencia determinada.
•
Multiplicativo : La imagen obtenida es fruto de la multiplicación de dos señales,
donde la iluminación no es constante, de modo que se dan zonas más oscuras que
otras.
2.2.3 Filtros pasobajos lineales espaciales
Al ser el ruido variaciones sobre los niveles de gris, estos entonces tienen altas
frecuencias, por ello es que se aplican filtros pasobajos para la eliminación del ruido que se
encuentra en su mayoría en las altas frecuencias.
En el presente proyecto, ya que lo que más afecta al programa son los cambios de
iluminación, se va a eliminar las altas frecuencias tomando en cuenta rangos de variación,
dependiendo de la magnitud que se tenga en el píxel examinado, aplicando una máscara
que modifica los píxeles vecinos horizontales y verticales, por lo que se tiene un filtro con
conectividad tipo 4, y lo que se pretende con él es eliminar las variaciones que se den si se
da un pico de iluminación, donde cuando se determine un píxel que pase del rango
estipulado, este va a ser eliminado suavemente, modificando sus vecinos más suavemente,
para no ocasionar cambios bruscos de iluminación en la imagen preprocesada.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
15
En la figura 2.4 se observa la máscara aplicada para cada píxel en que se de un alto
valor, teniendo en cuenta que la imagen tiene valores en el rango [0,1], por lo que se
pretende disminuir los píxeles en los cuales se encuentren valores mayores de 0.9
principalmente, y esto se hace paulatinamente, disminuyendo también la magnitud de los
píxeles vecinos.
(x,y-1)(0.9)
(x-1,y)(0.9)
(x,y)(0.85)
(x+1,y)(0.9)
(x,y+1)(0.9)
Figura 2.4 Máscara utilizada en el filtro
Agosto del 2004
IE-0502
16
Determinación de la posición de un objeto utilizando una cámara Web
CAPÍTULO 3: Análisis del programa
3.1
Estructuración del programa
3.1.1 Archivo interfaz.h
Este archivo cuenta con las definiciones de clases utilizadas en el programa, en él se
implementan también las funciones utilizadas para el procesamiento de las imágenes
tomadas, esto se realiza así, para no mezclarlas con las funciones que se utilizan para la
construcción de la interfaz gráfica, para mayor comprensión del programa.
Los
comentarios específicos de cada función se encuentran en el programa, el cual se incluye
en los anexos del presente documento.
Para el programa se tiene una clase llamada C_matriz, la cual construye una matriz
de 320x240, dado a que las fotos tomadas tienen estas dimensiones de píxeles. Esta clase
cuenta con dos funciones, la función get(x,y) que se utiliza para obtener los valores
almacenados en la matriz y la función set(x,y,elemento) que se utiliza para insertar datos en
la matriz, donde elemento es la cantidad que se quiere almacenar. Para estas funciones se
crea un puntero que va a almacenar los valores, este se crea en el constructor de la clase y
se elimina en el destructor.
Una vez que se tiene esta clase, se implementan las funciones para procesar la
imagen, para ello se tiene que incluir las herramientas presentes en la librería <magick++>,
donde se utiliza una función para obtener las dimensiones de la imagen, esto
implementando un objeto de tipo Image. La primera función que se implementa es la
utilizada para imprimir en la carpeta la imagen que se envíe a dicha función, luego de ella
se encuentra la función iluminancia, la cual recibe la foto a transformar en escala de grises,
en esta se utilizan las funciones de la librería <magick++> para dividir cada píxel en sus
tres elementos (rojo, verde y azul), teniendo entonces que iluminancia va a unificar estos
tres valores en uno sólo, multiplicando cada uno de ellos por un valor estipulado y
devolviendo por último la matriz resultante en niveles de grises.
Agosto del 2004
IE-0502
17
Determinación de la posición de un objeto utilizando una cámara Web
A la matriz que resulta de esta función iluminancia se le aplica un filtro para
eliminar los píxeles en los cuales se encuentran picos de iluminación, esto para evitar que
los cambios de iluminación puedan afectar en mayor medida los datos del programa.
Luego se crea la función que finalmente va a determinar los píxeles en que se
encuentra el objeto, en ésta se recibe la imagen de la fotografía base y las fotos del objeto
moviéndose, en donde, lo que se hace es restar las imágenes píxel por píxel y a esa
diferencia obtenerle el valor absoluto. Luego se toma un valor límite de diferencia para
eliminar valores en los que se puede dar diferencia por ruido, dando una mayor precisión en
la determinación de la posición del objeto.
Por último, se tienen las dos funciones que se utilizan para determinar el centroide
del eje x y el eje y, en ellas se aplica la fórmula explicada en el apartado 2.1.6 del capítulo
dos, donde básicamente se hace una suma de los píxeles totales del objeto, determinando su
área. También se realiza una suma de las distancias que se tienen desde la posición (0,0)
hasta el píxel que forma parte del objeto y luego se devuelve la división de ambas
cantidades para determinar con ello la posición exacta del centroide.
También en este archivo se tienen las definiciones de la clase MyFrame, la cual
utiliza las librerias de wxwindows para implementar la ventana del programa y los menus
que se utilizan, donde en el archivo interfaz.cpp se va a observar más claramente como se
implementa esta clase.
3.1.2 Archivo interfaz.cpp
En el archivo interfaz.cpp se tiene la implementación del programa base, donde se
escriben las funciones para la interfaz. En el constructor de la función MyFrame, se
construye la ventana y el menú de funciones que realiza el programa, además de las
funciones que reciben el nombre para cada opción que se tiene en el menú. Es importante
tomar en cuenta que la principal función es la llamada Posiciones, esta se utiliza cuando se
selecciona la opción Obtener posiciones. En esta se tiene básicamente la utilización de
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
18
todas las funciones para el procesamiento de las imágenes, las cuales se explicaron
anteriormente, dado que están en el archivo interfaz.h.
Las demás funciones que se tienen es para abrir las fotos que se tomaron una vez
ejecutado el programa, para ello se tiene una llamada a un programa, utilizando la función
system. Esto se hace así dado que lo que se quiere es abrir las fotos recién tomadas, lo cual
no sucede si se implementan estas opciones como las demás, ya que se abren las fotos que
se tenían en el momento de cargar el programa general, lo cual no es deseado, debido a lo
anteriormente explicado.
Dado a los ajustes que realiza la cámara cuando se utiliza por primera vez desde que
se inicia el sistema operativo, se incluyó una variación del programa mvc que se ejecuta por
2 minutos, para que durante este tiempo la cámara realice todos los ajustes. Para dar el
tiempo necesario para evitar que la cámara varíe las intensidades de iluminación durante la
ejecución entonces se realizará una función de calibración que llame a la variación de mvc
antes mencionada al inicio de este párrafo. Además para evitar algún inconveniente con
esto, para capturar la imagen de fondo se van a tomar antes 25 fotos y para empezar a
procesar las imágenes con el objeto moviéndose se van a desechar las primeras 25 fotos y
se empezará a procesar a partir de la posición número 25 para así tener un programa más
robusto.
La función principal para correr el programa primero toma la fotografía sin el objeto
y una vez obtenida la imagen base, pregunta al usuario cuantos minutos desea tomar
fotografías del objeto. Con este dato toma en cuenta dado por minuto debe tomar 110
fotos, con lo que se tiene un pequeño error de ejecución de tiempo de ±0.02s
aproximadamente, según las pruebas realizadas; por lo cual se tiene una buena precisión en
cuanto al tiempo en que se van a tomar fotografías. Una vez que al programa se le indica el
tiempo, toma las fotografías y las archiva en la carpeta del programa para luego entrar a un
ciclo que se ejecuta 110 veces por el número de minutos que se pidió.
Lo primero que se hace con cada foto es aplicarle el mismo filtro que a la imagen
base, luego de mandar la imagen a la función iluminancia para ponerla en escala de grises.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
19
Una vez que se tiene esto, se compara la imagen recién procesada con la imagen base para
determinar los píxeles en donde se encuentra el objeto, para luego determinarle el centroide
al objeto en los dos ejes y se almacenan en dos arreglos dinámicos.
Además estos datos van a irse almacenando en el archivo Posiciones.txt donde
evalúa en que zona esta el objeto y se imprime en el archivo la posición, la zona y el
tiempo, ya que se tiene que por posición se va sumando continuamente 0.547s, brindando al
usuario los datos principales para determinar la trayectoria que siguió el ratón, en este caso.
Después se crea la imagen con los puntos donde se determinó que estaba el objeto,
para que el usuario tenga una vista rápida de los datos que se determinaron en el tiempo en
que se ejecutó el programa; finalizando con esto la ejecución principal del programa base y
tomando en cuenta que una vez terminado este proceso, puede observar las fotografías que
da como opción el menú Acciones, presente en la parte superior.
El programa en general brinda la mayor cantidad de datos al usuario durante su
ejecución, pa ra que éste no sienta dudas. Para ello se agregó una ventana de texto, la cual
va diciendo al usuario el paso que se ejecutó y el que debe seguir, además de los tiempos en
que se procesó cada imagen, tratando de brindar la mayor claridad posible, como se explica
más claramente en el manual de uso que se encuentra en los anexos de éste trabajo.
3.1.3 Programas para abrir las imágenes tomadas
Dado a que el programa cuenta con las funciones en la barra de menú para abrir las
fotos que se obtuvieron luego de obtener las posiciones del objeto, se implementaron cuatro
programas con un archivo .h y otro .cpp para tal objetivo. En los archivos .h se tienen
definidas las clases MyFrame y MyCanvas. En lo que es el archivo .cpp la clase MyFrame
se implementa para crear la ventana y la barra de menú con las funciones necesarias,
aunque para el caso de las ventanas que se abren con la foto, no se necesita ninguna acción;
solamente se crea una barra de menú llamada Archivo con la opción para obtener ayuda y
otra para cerrar la ventana.
Agosto del 2004
IE-0502
20
Determinación de la posición de un objeto utilizando una cámara Web
Luego se tiene la clase MyCanvas la cual es utilizada para crear el mapa de bits para
la imagen a abrir, donde se crea un puntero de tipo wxImage para tener acceso a la imagen
en la clase MyFrame mediante el puntero tipo MyCanvas llamado m_canvas. Esta última
clase tiene como única función a OnPaint la cual es la que convierte al mapa de bits en
imagen, y en la cual se informa al programa la dirección en la cual se encuentra la foto a
abrir y en que coordenadas se quiere colocar el título de la imagen y la imagen a abrir.
Estos dos archivos son cortos, dado a que la única función que cumplen es abrir una
imagen en especificó, por lo que los cuatro programas para abrir cada una de las fotos
deseadas solamente tiene como diferencia el nombre del puntero del mapa de bits creado
para la imagen y la dirección en la cual se encuentra la imagen que se quiere abrir.
Dichos programas se hicieron para tener mayor manejo de las ventanas que se abren
con las imágenes y para que cuando el usuario seleccione la opción en la interfaz principal
del programa general para abrir una imagen específica, se muestre la última imagen creada,
debido a que el objetivo de estas opciones en la barra de menú es que el usuario pueda
observar rápidamente los resultados obtenidos por el programa.
3.1.4 Programas makefile para la compilación de los archivos
En general para la compilación de todos los programas que se juntan para cumplir
con el objetivo principal de este proyecto, existen tres tipos de makefile, uno para compilar
la interface del programa principal, otro para compilar los programas para abrir las fotos y
por último el makefile del programa mvc-0.8.8.
Los makefile para compilar los programas que constan de interfaz gráfica, se tienen
tres archivos más que cuentan con las librerías necesarias para contar con todas las
funciones utilizadas por el wxwindows, pero dado a que la interfaz del programa principal
utiliza además la librería <magick++> la cual, como se dijo anteriormente, cuenta con las
funciones necesarias para procesar las fotos tomadas.
Debido a que los makefile tienen tres archivos bases, el archivo makeprog.env, el
make.env y el libmake.env los cuales se van llamando por jerarquía para ir nivel por nivel
cumpliendo con los pasos de la compilación, para realizar la compilación del programa
Agosto del 2004
IE-0502
21
Determinación de la posición de un objeto utilizando una cámara Web
principal se necesitó modificar el makefile utilizado para compilar los programas para abrir
las fotos resultantes, básicamente lo que se cambió fue las direcciones de llamado de los
archivos entre sí, dado a que se necesita agregar la librería magick++ y cambiar las
direcciones
de
llamado
de
cada
uno
de
root/wxwindows/wxGTK-2.4.2/demos/proyecto_nuevo
los
archivos
para
llamar
para
los
la
carpeta
archivos
makeprog.env y make.env para incluir en ellos la librería magick++.
En cuanto al makefile del programa mvc, no se cambió nada en él, debido a que no
era necesario, ya que éste no usa ninguna librería especial, este makefile tiene una jerarquía
de archivos al igual que los otros dos makefile para la interfaz gráfica, pero en este caso se
llaman depend.sh y depend.inc en los cuales se encuentran el llamado a las librerías de
video4linux y apertura de la carpeta /dev/video0 donde se encuentra la cámara.
En sí, los makefile usados tienen una estructura parecida en su archivo makefile,
donde se tiene el nombre del archivo .cpp ó .c para crear el ejecutable, y el archivo .h con el
mismo nombre del archivo. Lo que cambia entre ellos son los archivos que se llaman
dentro del makefile, donde se incluyen las librerías necesarias para la compilación
dependiendo del tipo de programa que se tiene y además de otro archivo que es opcional,
dado a que se puede escoger crear un archivo o incluirlo en el makefile, en éste archivo o
en el makefile se imcluyen las banderas de compilación del archivo, dependiendo de las
restricciones que se quieren antes de crear el ejecutable del programa.
Agosto del 2004
IE-0502
22
Determinación de la posición de un objeto utilizando una cámara Web
3.2 Resultados de las pruebas realizadas al programa
Para las siguientes pruebas se debe de tomar en cuenta que la máquina utilizada
contaba con un procesador Intel Pentium IV con 384 MB de memoria RAM, una tarjeta de
video Nvidia GeForce II de 32 MB y una cámara web IBM VGA.
3.2.1 Primera prueba
En esta prueba se movió el mango de un desatornillador en condiciones de
iluminación constantes, pe ro con superficies que reflejan luz, por lo que se nota la
presencia de ruido en la posiciones determinadas, como se muestra en la siguiente foto:
Figura 3.1 Fotografía de la posición de un objeto
En la figura anterior realmente el objeto es el mayor grupo de píxeles negros, pero
dada la reflexión de algunas superficies y el poco contraste del objeto utilizado, la
determinación de la posición no es exacta, aunque aún con estos grupos de ruido, dado que
el mayor grupo se encuentra donde esta el objeto, se tendrá un error pero siempre se dará
una noción de la posición del objeto en el momento en que se tomó la foto.
Agosto del 2004
IE-0502
23
Determinación de la posición de un objeto utilizando una cámara Web
El movimiento seguido por el objeto fue horizontal, para ilustrarlo a continuación se
muestran unas de las posiciones resultantes:
Figura 3.2 Fotografías de algunas de las posiciones del objeto durante la prueba
estas posiciones están en desorden, pero como el movimiento fue constante, se observa sin
embargo, la trayectoria seguida.
En esta prueba se comprueba claramente el efecto de la reflexión de luz y como
afecta los resultados obtenidos, que aunque tengan concordancia con la posición del objeto,
introducen un error en cuanto a la posición exacta del objeto, como se mencionó antes, más
aún en la prueba realizada, ya que el objeto utilizado brillaba, por lo cual reflejaba luz, lo
cual también se observa en los resultados, donde se puede ver como hay un reflejo del
objeto junto a él como se muestra en la siguiente foto:
Agosto del 2004
IE-0502
24
Determinación de la posición de un objeto utilizando una cámara Web
Figura 3.3 Fotografía de una posición del objeto
Lo importante aquí, es que se comprobó que la reflexión afecta los resultados, pero
para cuando se utilice en el laberinto y con el ratón, al disminuir la reflexión el ruido
producido por ésta no afectará los resultados, por lo cual esta no es una razón por la cual la
solución que se plantea no funcione.
A continuación se muestra la imagen de los centroides encontrados en la prueba:
Figura 3.4 Fotografía de los centroides obtenidos durante la prueba
Como se observa en la figura, los puntos que ilustran las posiciones determinadas
tienen el comportamiento de movimiento horizontal seguido por el objeto, lo cual
demuestra el correcto funcionamiento del programa, ahora para tener una idea del error se
Agosto del 2004
IE-0502
25
Determinación de la posición de un objeto utilizando una cámara Web
puede observar que este es pequeño al comparar los puntos con las fotos del objeto en
distintas posiciones, dado a que el número de píxeles de ruido son mucho menores que los
del objeto, lo cual desplaza un poco la posición calculada, pero aún así da una buena
aproximación de donde se encontraba el objeto en ese momento.
3.2.2 Segunda prueba
Como segunda prueba se dirigió la cámara hacia el piso, se puso una alfombra y se
utilizó un zapato deportivo de tela como objeto, para evitar que se dé alguna reflexión.
Además el zapato no se moverá para que se pueda verificar la correcta determinación del
objeto y se pueda observar el resultado en la imagen de los centroides encontrados.
Para verificar que el objeto se mantuvo en una sola posición se muestra una imagen
de varias de las posiciones obtenidas del objeto:
Figura 3.5 Fotografías de algunas de las posiciones del objeto durante la prueba
Agosto del 2004
IE-0502
26
Determinación de la posición de un objeto utilizando una cámara Web
La figura anterior muestra claramente la forma del zapato en una sola posición,
ahora bien, si se analiza la imagen de la posición mostrada más claramente en la imagen
que se tiene a continuación:
Figura 3.6 Fotografía de una posición tomada durante la prueba
se observa ruido en la parte superior, donde esta zona corresponde a la parte del piso que no
estaba cubierta por la alfombra. Esto demuestra nuevamente los efectos del reflejo, mas
aún si se observa como se da una zona blanca en el objeto, esto se dio debido a que el
zapato utilizado tiene en la plantilla de la parte interior una cobertura de tela gr is, lo cual
produce un color similar al fondo, cuando se produce la imagen en escala de grises y eso
provoca que esa parte no se tome en cuenta como parte del objeto.
Lo anterior resalta la importancia que tiene el contraste que debe tener el color del
fondo y el del objeto, ya que de no ser así se introducirá un error en las posiciones
calculadas al verse disminuido el tamaño del objeto. Para mostrarlo basta con observar la
foto del objeto en escala de grises para corroborar lo que se comentó anteriormente:
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
27
Figura 3.7 Fotografía en escala de grises del objeto durante la prueba
En la imagen se verifica lo dicho, ya que se observa como en las zonas donde
terminó la alfombra se introdujo ruido producto de la reflexión y como en efecto la tela de
la plantilla del zapato es de una magnitud de gris muy similar al color de la alfombra,
provocando que esto no se tome como parte del objeto.
Para verificar la determinación de la posición del objeto se muestra la figura
resultante de los centroides:
Figura 3.8 Fotografía de los centroides del objeto durante la prueba
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
28
Esta figura que se mostró verifica la exactitud del cálculo del centroide y como ante
condiciones que varían poco durante la toma de fotos, el error introducido es menor que el
introducido en la prueba #1. Ahora para que se observe numéricamente el error introducido
se muestran los resultados dados en el archivo Posiciones.txt tal y como lo imprime el
programa:
Inicio Ejecucion Programa de Captura: Fri Jul 23 15:11:09 2004
Fin Ejecucion Programa de Captura: Fri Jul 23 15:12:25 2004
La ejecucion del programa duro: 76 segundos
LOS TIEMPOS EN QUE SE TOMO CADA POSICION SE ENCUENTRAN EN LA CONSOLA
Centroides (x,y)
Zona
Tiempo(s)
Posicion #1 (130,129)
13
0
Posicion #2 (131,125)
13
0.545454
Posicion #3 (130,128)
13
1.09091
Posicion #4 (129,128)
13
1.63636
Posicion #5 (129,130)
13
2.18182
Posicion #6 (129,131)
13
2.72727
Posicion #7 (130,131)
13
3.27272
Posicion #8 (129,131)
13
3.81818
Posicion #9 (130,130)
13
4.36363
Posicion #10 (130,129)
13
4.90909
Posicion #11 (131,130)
13
5.45454
Posicion #12 (130,131)
13
5.99999
Posicion #13 (130,131)
13
6.54545
Posicion #14 (130,131)
13
7.0909
Posicion #15 (130,130)
13
7.63636
Posicion #16 (130,131)
13
8.18181
Posicion #17 (131,128)
13
8.72726
Posicion #18 (132,129)
13
9.27272
Posicion #19 (132,128)
13
9.81817
Posicion #20 (131,128)
13
10.3636
Posicion #21 (131,128)
13
10.9091
Posicion #22 (130,129)
13
11.4545
Posicion #23 (130,130)
13
12
Posicion #24 (131,128)
13
12.5454
Posicion #25 (129,132)
13
13.0909
Posicion #26 (130,131)
13
13.6364
Posicion #27 (129,130)
13
14.1818
Posicion #28 (130,129)
13
14.7273
Posicion #29 (130,127)
13
15.2727
Posicion #30 (131,126)
13
15.8182
Posicion #31 (131,128)
13
16.3636
Posicion #32 (130,129)
13
16.9091
Posicion #33 (130,127)
13
17.4545
Posicion #34 (130,127)
13
18
Posicion #35 (130,129)
13
18.5454
Posicion #36 (130,129)
13
19.0909
Posicion #37 (130,128)
13
19.6363
Posicion #38 (131,127)
13
20.1818
Posicion #39 (131,127)
13
20.7273
Posicion #40 (131,127)
13
21.2727
Posicion #41 (131,126)
13
21.8182
Posicion #42 (131,126)
13
22.3636
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
Posicion #43 (131,127)
Posicion #44 (131,128)
Posicion #45 (129,132)
Posicion #46 (129,131)
Posicion #47 (129,131)
Posicion #48 (128,132)
Posicion #49 (129,132)
Posicion #50 (131,127)
Posicion #51 (130,127)
Posicion #52 (130,130)
Posicion #53 (129,132)
Posicion #54 (129,131)
Posicion #55 (130,132)
Posicion #56 (129,130)
Posicion #57 (129,130)
Posicion #58 (130,130)
Posicion #59 (129,131)
Posicion #60 (129,131)
Posicion #61 (130,129)
Posicion #62 (130,130)
Posicion #63 (130,129)
Posicion #64 (131,128)
Posicion #65 (132,127)
Posicion #66 (131,127)
Posicion #67 (131,127)
Posicion #68 (131,127)
Posicion #69 (131,128)
Posicion #70 (129,129)
Posicion #71 (130,128)
Posicion #72 (130,128)
Posicion #73 (130,128)
Posicion #74 (130,128)
Posicion #75 (130,127)
Posicion #76 (130,128)
Posicion #77 (130,128)
Posicion #78 (130,128)
Posicion #79 (131,129)
Posicion #80 (130,129)
Posicion #81 (130,129)
Posicion #82 (130,129)
Posicion #83 (130,129)
Posicion #84 (131,129)
Posicion #85 (131,128)
Posicion #86 (130,128)
Posicion #87 (131,129)
Posicion #88 (131,129)
Posicion #89 (130,130)
Posicion #90 (130,128)
Posicion #91 (130,129)
Posicion #92 (130,130)
Posicion #93 (129,130)
Posicion #94 (130,129)
Posicion #95 (130,129)
Posicion #96 (130,130)
Posicion #97 (129,130)
Posicion #98 (129,129)
Posicion #99 (130,129)
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
29
22.9091
23.4545
24
24.5454
25.0909
25.6363
26.1818
26.7272
27.2727
27.8182
28.3636
28.9091
29.4545
30
30.5454
31.0909
31.6363
32.1818
32.7272
33.2727
33.8181
34.3636
34.909
35.4545
36
36.5454
37.0909
37.6363
38.1818
38.7272
39.2727
39.8181
40.3636
40.909
41.4545
41.9999
42.5454
43.0908
43.6363
44.1817
44.7272
45.2726
45.8181
46.3635
46.909
47.4544
47.9999
48.5453
49.0908
49.6363
50.1817
50.7272
51.2726
51.8181
52.3635
52.909
53.4544
Agosto del 2004
IE-0502
30
Determinación de la posición de un objeto utilizando una cámara Web
Posicion #100 (130,128)
Posicion #101 (130,129)
Posicion #102 (130,129)
Posicion #103 (129,130)
Posicion #104 (129,130)
Posicion #105 (129,131)
Posicion #106 (129,131)
Posicion #107 (129,130)
Posicion #108 (129,130)
Posicion #109 (130,131)
Posicion #110 (131,129)
13
13
13
13
13
13
13
13
13
13
13
53.9999
54.5453
55.0908
55.6362
56.1817
56.7271
57.2726
57.818
58.3635
58.9089
59.4544
La imagen de los centroides y las posiciones mostradas en el archivo Posiciones.txt
indican que la solución planteada consta de precisión para obtener la posición del objeto,
donde entre posición y posición la mayor diferencia que se tiene es de 5 en ambos ejes,
teniendo como valores máximos 132 y mínimos 128. Esto hace preever que si se hubiera
contado con una alfombra que cubriera toda la zona que captura la cámara y si el zapato no
hubiera tenido en su plantilla un color similar al de la alfombra, el resultado obtenido
posiblemente hubiera sido un conjunto de puntos mucho mas reducido que el obtenido.
En la práctica si se lograse eliminar totalmente la reflexión y se utilizara un objeto
de un color contrastante, la imagen que se obtendría probablemente contendría un solo
punto, confirmando que el objeto no se movió en lo absoluto.
3.2.3 Tercera prueba
Para esta prueba se ajustó la alfombra que se utilizó en la prueba #2 de forma que la
cámara captara una pequeña sección del piso, evitando que se dé un reflejo por esta razón.
Además se utilizó como objeto un disquete negro (para que se dé un contraste con el fondo)
en un mismo lugar, tratando de corregir las fuentes de ruido que se tuvieron en la prueba
anterior, obteniendo las siguientes fotos del objeto:
Agosto del 2004
IE-0502
31
Determinación de la posición de un objeto utilizando una cámara Web
Figura 3.9 Fotografía de algunas posiciones del objeto durante la prueba
Con estas fotos se observa como efectivamente el disquete no se movió y la forma
que tiene éste, aunque se contó con el inconveniente de que el disquete tiene una superficie
metálica, la cual introdujo un error, dado que como se observa, esta recortó la forma del
disquete. Para ilustrar lo anterior se observa a continuación la foto que capturó la cámara y
procesó el programa:
Figura 3.10 Fotografía en escala de grises del objeto
Agosto del 2004
IE-0502
32
Determinación de la posición de un objeto utilizando una cámara Web
con esta imagen se verifica como afectó el reflejo que tiene la parte metálica del disquete,
donde claramente se observa como el reflejo del disquete se combina con el color de la
alfombra, lo cual origina que cuando se procesa por el programa no se toma en cuenta
como parte del objeto.
Para el cálculo de los centroides del objeto, la imagen resultante es la siguiente:
Figura 3.11 Fotografía de los centroides del objeto durante la prueba
En esta imagen se nota un grupo de puntos menor al obtenido en la prueba #2 y con
una mayor aproximación en cuanto al punto en el cual verdaderamente se encontraba el
disquete, para ello se observa una foto de la posición del objeto y la del fondo cuadriculado
para tener una mejor noción de cuan precisa fue la determinación de la posición al calcular
el centroide:
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
33
Figura 3.12 Fotografía en escala de grises del fondo dividido en zonas
Figura 3.13 Fotografía de una posición del objeto
Comparando las posiciones, se nota como aunque se trató de ajustar la alfombra
para eliminar el ruido por el reflejo del piso, se introdujo una línea delgada en el borde
derecho e inferior. Esto produjo un corrimiento de la posición del disquete hacia abajo y a
la derecha, pero con me jores resultados a los obtenidos en la prueba anterior, por lo que se
confirma que conforme se van mejorando las condiciones en las que se toman las fotos de
las posiciones del objeto, los resultados se van mejorando. Además es importante notar
como aunque la resolución de la imagen no es buena, como se observa en la foto de una
posición, esto no afecta a la determinación de la posición del objeto, lo único que afectó
Agosto del 2004
IE-0502
34
Determinación de la posición de un objeto utilizando una cámara Web
para determinar donde se encontró el disquete fueron los reflejos producidos por el piso y
por las partes metálicas que tiene el disquete.
3.2.4 Tiempos de ejecución del programa
A continuación se va a realizar un análisis de tiempos obtenidos del programa
ejecutándose, para ello se obtuvieron posiciones por varios minutos, obteniendo los
resultados vistos en la siguiente tabla:
Tabla 2.1 Tiempos de ejecución del programa
Tiempo
Tiempo Error
especificado ejecución (s)
(s)
(s)
600
616
16
480
473
7
360
352
8
540
572
32
60
59
1
240
239
1
300
295
5
180
178
2
420
422
2
600
601
1
Promedios
7,5
Tiempo por
foto
especificado(s)
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
0,545454545
Tiempo por
foto en
Ejecución(s)
0,56
0,5375
0,53333333
0,57777778
0,53636364
0,54318182
0,53636364
0,53939394
0,54805195
0,54636364
Error
Tiempo
Tiempo Número
(s) procesando procesando Fotos
imágenes(s) una foto(s)
0,0145
1209
1,0990909 1100
0,008
665
0,7556818 880
0,0121
559
0,8469697 660
0,0323
1208
1,220202
990
0,0091
131
1,1909091 110
0,0023
586
1,3318182 440
0,0091
648
1,1781818 550
0,0061
251
0,7606061 330
0,0026
651
0,8454545 770
0,0009
1227
1,1154545 1100
0.545454545 0,54583297 0,0097
1,0344369
En la tabla 2.1 se observa claramente como en el programa se tiene una muy buena
aproximación del tiempo que se tarda en tomar cada foto, donde se estimó un tiempo de
0.5454s por foto y en la práctica en promedio se tiene un tiempo de 0.5458s, teniendo como
diferencia 0.0004s, además de un error promedio de 0.0097s; teniendo como error máximo
0.0323s, con lo que a los tiempos que se tienen para la toma de fotografías es muy
constante y confiable. Es importante observar que el error que se tiene para la toma de
cada fotografía se va aumentando dado al alto número de fotos que se toman en poco
tiempo, pero éste no llega a ser muy elevado según las pruebas realizadas ya que tiene
como máximo un valor de 32s, pero como valor promedio se dieron 7.5s, esto claro esta
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
35
que se tiene un mayor error cuando el tiempo de ejecución es mayor, por lo que entre más
número de fotos se tomen se va a tender a tener un mayor error en los tiempos, pero ello no
afecta en gran medida a los resultados.
Una situación importante que se observó cuando se estaban tomando los datos de la
tabla 2.1 es que cuando la computadora se forzó ejecutando el programa por más de 60
minutos consecutivos, los tiempos tendían a aumentar, por lo que una observación
importante para tomar en consideración es tener el cuidado de no ejecutar el programa por
más de 40 minutos, el cual es el tiempo aproximado de duración para procesar las
posiciones que se obtuvieron por 10 minutos consecutivos; teniendo entonces como
recomendación no obtener las posiciones por más de 10 minutos y luego volver a ejecutar
el programa, se darían mejores resultados si se le diera unos minutos a la computadora para
luego volver a ejecutar los programas, ya que cuando entre prueba y prueba se hizo esto,
los tiempos se mantuvieron estables.
Dado a lo apuntado anteriormente, otros datos de tiempos que se tabularon en las
pruebas realizadas, fue el tiempo total que dura el programa procesando las fotografías
tomadas, donde se tiene en promedio que por foto se dan 1.034s con un tiempo máximo de
1.3318s, apuntando para este dato que como se dijo en el párrafo anterior, los resultados
cuando se tenía la computadora trabajando por más de 40 minutos consecutivos sin dar
ningún intervalo entre ejecución y ejecución, entonces los tiempos tendieron a subir,
aunque teniendo en consideración la cantidad de fotografías que se están procesando para
obtener los datos que se imprimen en el archivo Posiciones.txt y la fotografía
Centroides.jpg donde se ilustran todas las posiciones obtenidas y los datos de importancia
para el usuario.
En general, la conclusión importante de la tabla 2.1 es que los datos que se obtienen
del programa una vez que se procesan las fotografías del objeto moviéndose son muy
buenos en cuanto a precisión y exactitud, teniendo errores pequeños tomando en cuenta que
el número de fotos tomadas es alto. Otra ventaja que tiene el programa es la impresión de
cada una de las posiciones del objeto con su respectivo número, ya que así se pueden
revisar rápidamente para saber cuales son los datos que verdaderamente valen en los datos
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
36
del archivo Posiciones.txt, para así poder tener una mayor confianza en los datos que se
tabulen una vez finalizada la obtención de las posiciones. Tomando en cuenta lo anterior,
se tienen en total en la carpeta donde se ejecutó el programa un total de 2200 fotos como
máximo, pero esto no es de gran preocupación en cuanto a espacio de memoria, ya que
estas se van regenerando con cada corrida del programa y además según las pruebas
realizadas el espacio en memoria utilizado por la carpeta con el mayor número de fotos fue
de 32 a 50 MB, lo cual no es una gran cantidad de memoria, por lo cual esta no sería una
dificultad para el correcto funcionamiento del computador.
Una situación importante es tomar en cuenta el computador donde se procesaron las
fotos utilizadas, esto va a ser un aspecto muy importante a tomar en cuenta, ya que el
equipo utilizado puede variar sustancialmente los datos que se obtuvieron anteriormente,
para ello es que en el apéndice A se agrega un apartado donde se especifican las
características del computador donde se hicieron las pruebas, ya que esto va a tener una
relevancia primordial en la eficiencia del programa.
Agosto del 2004
IE-0502
37
Determinación de la posición de un objeto utilizando una cámara Web
CAPÍTULO 4: Conclusiones y recomendaciones
4.1
Conclusiones
Una vez finalizado el proyecto, se concluye primeramente que según los resultados
de las pruebas realizadas se cumplió con el objetivo principal, dado que se brinda un
programa que determina las posiciones en las cuales se encuentra un ratón durante el
tiempo en el cual se toman las fotos de él moviéndose dentro de un laberinto.
La cámara Web se utilizó exitosamente en la plataforma de Linux instalada en la
máquina que se usó para probar el programa, donde se instalaron correctamente los
módulos y librerías necesarias para que se puedan tomar las fotos del ratón moviéndose en
el laberinto con una frecuencia alta de dos fotografías por segundo.
El código del programa fue escrito en el lenguaje C++, aprovechándose
las
funciones con las cuales cuentan sus librerías, lográndose que el código del programa sea
más simple y eficiente.
La estructura del programa se pudo realizar de una forma estructurada, donde se
tiene un archivo para las definiciones y otro en el cual se implementan las funciones.
El programa mvc versión 0.8.8 se utilizó óptimamente para poder tomar las
fotografías del objeto con una frecuencia aproximada de 2 fotos por segundo, con lo cual se
pudo tener un mayor número de fotos del ratón y establecer claramente la trayecroria que el
animal siguió.
Se logró hacer que el programa calcule el centro de masa del objeto encontrado,
para con ello determinarse con exactitud la posición y luego la zona en la cual se encuentra
el objeto.
Se construyó una imagen de la foto del fondo mostrando las divisiones entre la
zonas, con lo cual se consigue brindar al usuario la posibilidad de aj ustar el laberinto al
ancho de la imagen del fondo que se captura en la cámara y corroborar la validez de los
resultados obtenidos.
Para la creación del archivo con los resultados, se concluye que en él se pudo
imprimir la hora de inicio, final y el tiempo en el cual se tomaron las fotografías del ratón
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
moviéndose.
38
También se consigue escribir el número de posición y la posición del
centroide de éste en el momento que se tomó la foto, el cual se imprime al lado de la zona
en la cual se encuentra la posición determinada.
Para la interfaz gráfica del programa se diseñó una ventana con una barra de menú
que cuenta con las opciones Archivo y Acciones, además de un cuadro de texto en el centro
donde se indica al usuario los pasos a seguir y los cuidados que debe tener cuando ejecuta
el programa, con lo cual se logra brindar al usuario herramientas visuales fáciles para
utilizar el programa.
Con los análisis de las pruebas realizadas al programa, se concluye que los
resultados de las fotos fueron muy buenos, y se mejoran conforme van eliminándose las
superficies que producen reflejo y teniendo un objeto de un color que contraste con el
fondo.
Agosto del 2004
IE-0502
4.2
Determinación de la posición de un objeto utilizando una cámara Web
39
Recomendaciones
Debido a que las primeras veces que se corrió el programa se concluyó que la
cámara puede tener un tiempo de calibración de la iluminación cuando se utiliza por
primera vez luego de arrancar el sistema operativo, se recomienda utilizar una cámara que
no realice ningún ajuste de iluminación para evitarse errores en los resultados.
Una recomendación importante que se da luego de finalizar el proyecto utilizando la
metodología escogida para la captura de fotos, la cual tiene una dependencia de las
condiciones del medio en que se toman las fotografías, es la forma en que se procesaron
éstas.
Si se quiere realizar un programa más robusto, es preferible realizar una
comparación entre fotos consecutivas, aunque con esto se va a tener la complicación de que
se deberá de generar la forma del objeto, es probable que se eliminen los problemas tenidos
con la iluminación y los reflejos.
Agosto del 2004
IE-0502
40
Determinación de la posición de un objeto utilizando una cámara Web
BIBLIOGRAFÍA
Libros:
1. Eckel, Bruce. “Thinking in C++”, segunda edición, Prentice Hall, 2000.
2. Beer y Johnston, Ferdinand y Russell. “Estática”, sexta edición, McGraw Hill,
1997
Páginas web:
3. “Programa mvc”, www.turbolinux.com.cn/~merlin/mvc.
4. “Programa tcap”, http://toonarchive.com/tcap.
5. “V4l resources”,
http://student.wsp.krakow.pl/~mummin/pliki/dolinuxa/video%20Linux%20Linux%
20resources.html.
6. “Modelo de programación con v4l”,
http://oasis.dit.upm.es/~jantonio/documentos/revistas/video4linux/v4l_2.html
7. “Crear archivos en C”, www.linuxchile.cl/foros.php?op=ver&id=530
8. “Manual de Linux”, http://es.ttdp.org//Manuales-LuCAS/doc-manual- linux-procfs
9. “Install Manual”, http://www.debian.org/releases/stable/installmanual
Agosto del 2004
IE-0502
41
Determinación de la posición de un objeto utilizando una cámara Web
ANEXOS
Anexo 1.Manual de instalación del programa
Paquetes del kernel
En este punto, se considera que ya se tiene correctamente instalado en la máquina
donde se va a ejecutar el programa, el sistema operativo Linux de Debian, para esto se
tienen muchas maneras de hacerlo, se puede realizar su instalación directamente de la red o
con los discos que se encuentra en la página principal de Debian. La ventaja de instalar
este sistema es que se cuenta con mucha ayuda en la red, teniendo como manual principal
el que se encuentra en la página www.debian.org, donde se explica paso a paso el proceso
de instalación.
Los paquetes a incluir durante la recompilación del kernel son en los recursos que
se tienen para video, por ello se debe agregar video4linux para poder incluir en el sistema
linux de Debian las herramientas que se encuentran en las librerías de v4l. Además del
paquete de video for linux se debe incluir el módulo para la instalación de la cámara, para
la cámara utilizada basta con un módulo que se encuentra en el kernel, de no ser así se hace
necesario buscar si la cámara que se tiene es soportada en la red para linux, para que una
vez que se encontró el paquete de instalación se sigan las instrucciones para instalarlo.
Una vez que se tenga compilado el kernel utilizado es importante incluir los
módulos utilizando la instrucción modconfig o incluyendo el módulo en el archivo
/etc/modules, en las computadores utilizadas para implementar y probar el programa se
instaló el paquete de video4linux y se agregó el de la cámara web como módulo, teniendo
este último el nombre ibmcam, por lo cual para probar si se instaló correctamente ambos
paquetes primero para asegurar que se tiene bien el módulo de la cámara se puede dar la
instrucción modprobe ibmcam y una vez que se ejecute esta instrucción sin problemas se
puede instalar el programa xawtv utilizando la instrucción apt-get install xawtv y observar
si este programa se ejecuta correctamente, entonces se puede asegurar que están bien
instalados ambos paquetes dado a que este paquete utiliza ambos.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
42
Instalación de librerias y programas
Lo primero que se debe de instalar para correr el programa son las librerías para
C++ y las del compilador g++. Estas librerías son las necesarias para poder compilar el
programa, en caso de que una vez que se tengan instaladas las librerías siguientes, los
archivos ejecutables incluidos no corran y den algún error.
Las siguientes librerías son las que cuentan con las funcio nes necesarias para llevar
a cabo los procedimientos de tratamientos de imágenes, las librerías a incluir son
imagemagick y libmagick++6-dev, estas se instalan con la instrucción apt-get install
<nombre del paquete> (esta función se utiliza también para instalar las anteriores), una vez
que se tienen estas librerias instaladas se pueden utilizar las funciones para el
procesamiento de las fotos tomadas.
Luego de tener instaladas las librerías necesarias para correr el programa principal y
compilarlo, se hace necesario instalar el paquete wxGTK-2.4.2 el cual sirve para instalar las
librerías de wxwindows para utilizar las funciones necesarias para construir la interfaz
gráfica del programa.
Estas librerías son una herramienta sencilla para construir una
interfaz gráfica, ya que utilizan internamente las librerias de gtk, por lo que para poder
instalar correctamente wxGTK se debe instalar antes el paquete libgtk-dev. El paquete
wxGTK-2.4.2 es gratuito y se puede bajar de la red fácilmente, aunque estos paquetes
normalmente vienen comprimidos por lo que se hace necesario descomprimirlos en una
carpeta antes de instalarlos, a esta carpeta se le llamará wxwindows y luego se abrirá el
archivo de texto que trae con las instrucciones para su instalación.
Es importante tomar en cuenta que los paquetes se van actualizando, por lo cual
dependiendo de la versión de Linux que se tiene, los nombres de los paquetes pueden variar
en comparación con los nombrados aquí, por lo cual si se tienen problemas al instalar una
de estas librerías con la instrucción apt-get install se debe de observar la lista de paquetes
con los que se cuenta, para ello se utiliza la instrucción apt-cache search <nombre del
paquete> y poniendo los nombres de los paquetes anteriores, se despliegan los paquetes
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
43
que tengan un nombre similar al que se escribió, por lo que así se sabe con exactitud cual es
el nombre del paquete en la versión de Linux que se tiene instalada en la máquina.
Instalación del programa
Para instalar correctamente el programa primero se debe de verificar que se cuente
con los archivos necesarios. Para la instalación del programa primero se debe de tener las
carpetas con los programas para abrir las ventanas con las fotos tomadas por el programa,
estas carpetas tienen el nombre de FotoFondo, FotoFolder, FotoObjeto y FotoPosición, en
cada una de las carpetas se tiene un archivo ejecutable, un archivo .h, un archivo.cpp y un
makefile. Estas carpetas se deben guardar en la carpeta creada /root/wxwindows/wxGTK2.4.2/demos para que se compilen sin problema; una vez que se tengan las carpetas aquí, se
debe abrir una consola para ejecutar la instrucción make en la carpeta para compilar el
programa y crear el archivo ejecutable.
También se cuenta con el programa utilizado para capturar las imágenes, dado a que
este se modificó para tomar el fondo y para tomar las fotos para determinar las posiciones,
entonces se tiene las carpeta mvc que contiene las carpetas 1_Foto y Pidiendo_numero.
Para compilar el programa se debe estar en el archivo correspondiente y ejecutar la
instrucción make, esto se realiza para ambas carpetas, luego al ejecutable llamado mvc que
se crea en la carpeta 1_Foto se debe de cambiar su nombre por mvc1 y el ejecutable creado
en la carpeta Pidiendo_numero se deja con el nombre mvc.
Una vez que ya se compilaron estos programas, se tienen en cada una de esas
carpetas un ejecutable y se sigue por último con el programa principal, el cual se va ha
encuentrar en la carpeta proyecto_nuevo, esta se debe crear en la direcció n
/root/wxwindows/wxGTK-2.4.2/demos/ donde se encuentran las otras carpetas. Luego se
ejecuta make en una consola estando en esta carpeta y con ello ya se tiene el archivo
ejecutable llamado interfaz2 del programa principal el cual dentro de su ejecución va a
llamar a los demás ejecutables creados en las otras carpetas. Dado a esto es que se necesita
copiar los ejecutables de las carpetas anteriores en las cuales se compilaron los demás
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
44
programas como se explicó antes y teniendo el cuidado como se dijo anteriormente de
cambiar el nombre del ejecutable de la librería ../mvc/1_Foto por mvc1, para luego copiarlo
a la carpeta proyecto_nuevo donde se encuentra el ejecutable. Una vez que se tienen todos
los archivos ejecutables, los cuales se pueden diferenciar de los demás dado que son los
únicos que no tienen tipo como los demás (solamente se llaman por su nombre), por lo cual
entonces en sí dentro de la carpeta principal se deben tener los archivo ejecutables fondo,
centroides, objeto, posición, interfaz2, mvc1 y mvc.
Si se cumple con lo anterior, es probable que si se tiene correctamente instalada la
cámara y el paquete video4linux, el programa se ejecute con éxito, esto si se tienen los
cuidados mencionados en el manual de uso del programa.
Configuración del tiempo de captura de una foto
Este es un dato necesario para determinar los tiempos en que se toma cada foto
durante el tiempo en que se capturan fotos. Para determinarlo se debe ejecutar el programa
mvc, dando la instrucción ./mvc <número de fotos a tomar> y dado a que se le puede dar el
número de fotos a tomar y que el programa imprime en consola el tiempo y el número de la
foto tomada, entonces se puede determinar fácilmente las fotos tomadas por un minuto, y
teniendo este número se puede determinar el tiempo que dura tomando una foto, donde para
la máquina utilizada para las pruebas fue de 0.5454s y si se utiliza una máquina con una
velocidad de procesamiento parecido, es probable que éste varíe muy poco.
Entre mayores pruebas se realicen para determinar este tiempo mayor será la
precisión de los tiempos de ejecución del programa y los tiempos en que se tomó cada foto.
Finalmente cuando ya se tiene el tiempo que dura tomando una foto y el número de
fotos por minuto que toma, se deben cambiar lo s valores en el archivo interfaz2.cpp, esto se
puede realizar abriendo un programa para escribir códigos, donde se recomienda el anjuta,
ya que fue el utilizado para implementar el programa. Después de abierto en el anjuta el
archivo interfaz2.cpp se debe buscar al inicio las variables tiempo_captura, fotos_minuto y
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
45
modificar los valores de estas, para asegurarse que obtener resultados correctos según la
máquina que se está utilizando.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
46
Anexo 2. Manual de uso de programa
Partes de la ventana del programa
Para abrir el programa se debe acceder a la carpeta root/wxwindows/wxGTK2.4.2/demos/proyecto_nuevo (desde una consola o terminal) donde se encuentra el archivo
interfaz2, una vez que se está en esta carpeta ejecuta la instrucción ./interfaz2 y con ello se
abre la ventana para ejecutar el programa de detección del movimiento del ratón en el
laberinto.
A continuación se muestra la ventana del programa:
Una vez que se abrió la ventana se tiene en ella un cuadro de texto central en el cual
se brinda una ayuda para saber cual es el paso a seguir y las sugerencias según lo que se
esté ejecutando. Además se cuenta con una barra de menú que cuenta con las opciones
Archivo y Acciones, donde en la opción archivo se tiene la orden Salir para cerrar el
programa y la orden Créditos para mostrar una ventana con los créditos del programa. En
la otra opción de la barra se tiene Acciones en las cuales se tienen las opciones Obtener
Posiciones, Abrir foto del fondo, Abrir foto dl último objeto, Abrir foto de la primera
posición, Abrir foto de los posiciones y Calibración de la cámara. Estas son las opciones
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
47
que se tienen en la ventana del programa la cual muestra el título Detección de objetos
debido a la finalidad del programa.
Esto se observa en la siguiente imagen que muestra las opciones en el menú
Acciones:
Ejecución del programa
La ejecución del programa para obtener las posiciones del ratón en el laberinto es
muy sencilla, dado a que el programa siempre va mostrando cual es el próximo paso a
seguir y abre una serie de ventanas con advertencias y sugerencias para evitar errores en la
ejecución. Además es difícil perderse en los menús ya que solamente se tienen dos y el
menú para ejecutar el programa es Acciones.
Lo primero a tomar en cuenta es saber si se está ejecutando por primera vez el
programa luego de arrancado el sistema operativo, ya que se comprobó con las pruebas
realizadas que la cámara realiza un ajuste del lente respecto a la iluminación del lugar en
que se encuentra y esto produce lecturas incorrectas del programa. Aquí es importante
mencionar que aunque no se demostró en ninguna prueba utilizada, el cambio de posición
de la cámara puede provocar que se de un ajuste del lente, por lo que si se mueve la cámara
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
48
a un lugar con una iluminación diferente. Para evitar errores por estos motivos se tiene la
opción Calibración de la cámara, la cual activa la cámara por aproximadamente minuto y
medio para que ésta realice el ajuste del sensor y asegurarse que no lo haga durante la
ejecución del programa.
Si ya se ha ejecutado el programa no es necesaria ordenar calibrar la cámara, por lo
que se puede proceder a capturar las posiciones del ratón. Para ello se cuenta con la opción
Obtener posiciones, luego de que se ejecutó esta acció n inmediatamente se empieza a
capturar la foto del fondo, pero para evitar errores por ajustes de la cámara, la foto del
fondo se captura luego de tomar un número de fotos antes, lo cual toma alrededor de 20
segundos, por lo que durante este tiempo el laberinto no puede ser movido ni tener dentro
de él al ratón todavía.
La fotografía del fondo se toma y luego el programa pide el número de minutos a
determinar las posiciones, en esta opción se cuenta con un intervalo de 1 a 10 minutos
según las especificaciones dadas. Luego de escoger el número de minutos, el programa le
pide un nivel de resolución para la determinación de la posición del objeto, este varía entre
0 y 10, donde entre mayor sea este número mayor será la restricción que se le dé al
programa para determinar la posición del ratón.
El valor estándar según las pruebas
realizadas es 3 y 4 normalmente, pero si luego de observar las fotos de los resultados se
tiene ruido se recomienda aumentar éste número para eliminarlo.
Después de escoger el valor para la resolución, se empieza a tomar las fotos, pero es
importante tomar en cuenta que para prever nuevamente que los ajustes que realice la
cámara introduzcan errores se toman 25 fotos que no se van a tomar en cuenta, en lo cual
dura aproximadamente 15 segundos, por lo que es aconsejable introducir el ratón antes
oprimir el botón OK en una ventana que le comunica al usuario que se van a iniciar a tomar
las fotos, aunque se debe de tomar en cuenta que los movimientos que éste realice en los
primeros 15 segundos no se van a tomar en cuenta en los resultados.
El programa va a durar un minuto según la exactitud que se tenga en el número de
fotos que se determinó que toma la cámara según la máquina en la cual se está ejecutando
la captura.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
49
El programa sugiere que se observe el proceso de tomar las fotos en la consola
donde se abrió el programa con la instrucción ./interfaz2, ya que allí se van a desplazar el
número de fotos que se han tomado y los tiempos en que se tomaron, con una exactitud
dada en segundos. Luego se da una ventana que comunica que las fotos ya fueron tomadas
y que si se abrió la ventana de consola se minimice para abrir la ventana del programa
principal para observar los resultados obtenidos.
Durante el tiempo en que se están procesando las fotos tomadas se pueden observar
los resultados en la carpeta del programa, donde se imprimen las fotos del ratón en la
posición donde se encontraba. Cuando se terminan de procesar las fotos, lo cual lleva
aproximadamente el doble del tiempo que se duró tomando fotos, se imprime en el cuadro
de texto la hora a la cual se procesó cada posición y se indica que ya se crearon las fotos,
por lo que estas se pueden observar escogiendo cual de ellas abrir según la opción que se de
en el menú Acciones.
Es importante también tomar en cuenta que el programa imprime una foto para cada
posición, lo cual permite al usuario observar rápidamente en la carpeta del programa cuales
posiciones se determinaron con la presencia de ruido y cuales no, para tener una absoluta
confianza en los resultados obtenidos.
Otra ventaja del programa es que crea un archivo con el tiempo que duró tomando
fotos, los tiempos en que tomó la foto para cada posición y el punto en el cual se
encontraba el ratón en ese momento, además de la zona en la cual se encontraba, teniendo
una división de 25 zonas del laberinto, las cuales tienen la siguiente estructura
0
6
11
16
21
1
7
12
17
22
2
8
13
18
23
3
9
14
19
24
4
10
15
20
25
Para observar claramente como se dividió el laberinto, cuando se crea la foto del
fondo se incluyen las divisiones de las zonas, para comparar resultados con los puntos
mostrados en la foto de las posiciones.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
50
Este programa se puede ejecutar cuantas veces consecutivas se quiera, no hay
restricción para ello, por lo que se pueden realizar varias pruebas continuas y aunque las
pruebas realizadas dan una confianza en los resultados que se obtienen, debido a la
sensibilidad que tiene por la iluminación y los problemas que se dan si se movió la cámara
durante la ejecución, es que se debe de comprobar los resultados observando las fotos
resultantes de las posiciones, para poder obtener las posiciones con un error mínimo, esto
tomando en cuenta que se cumpla con todas las recomendaciones dadas en las conclusiones
de este trabajo.
Agosto del 2004
IE-0502
51
Determinación de la posición de un objeto utilizando una cámara Web
Anexo 3. Recomendaciones de utilización
Dado el procedimiento utilizado para determinar los puntos en los que se mueve el
objeto, se dan a continuación una serie de recomendaciones, donde lo primordial es que
deben darse igualdad de condiciones del entorno durante el tiempo en que se están tomando
las fotos del objeto moviéndose. Las principales condiciones a tomar en cuenta para la
correcta ejecución del programa son la iluminación y la posición de la cámara, para poder
tener buenos resultados se debe de tener un fondo donde se tenga una mínima o nula
reflexión, para no tener picos de iluminación en la cámara, por ello se recomienda que el
color de éste sea uno que absorba luz y contraste con el color del objeto, por ejemplo para
el caso del ratón que es blanco, sería bueno tener un laberinto azul pintado o forrado con un
material que no refleje, como se especificó anteriormente.
Otra situación es la posición de la cámara y el fondo que esta capturando la cámara,
donde es de vital importancia que no se dé ningún tipo de movimiento en la imagen que se
este tomando, de darse un movimiento en la cámara o el fondo todos los resultados se
verían afectados, dado a que se daría una diferencia en todos los píxeles de la imagen , lo
cual ocasionaría que la determinación del objeto sería imposible, ya que lo que se pretende
es que lo único que varía entre la foto del fondo sin el objeto y las fotos del objeto
moviéndose es tener una igualdad total en el fondo y que la única variación que se tenga
sea el objeto, para así obtener únicamente al objeto y no tener ningún tipo de ruido que
vaya a afectar los resultados.
Una precaución que se debe tener es no tener la cámara recibiendo directamente luz,
ya que el lente de la cámara realiza ajustes, con lo que se va introduciendo errores, esto se
puede observar en las fotos que imprime el programa de cada posición, donde el resultado
si se tienen condiciones ideales sería únicamente la forma del objeto (en este caso del ratón)
lo que se debería ver, si esto no fuera así es porque alguna condición se varío, es aquí
donde surge la importancia de la calidad de la iluminación que se le dé al fondo que esta
capturando la cámara, ya que esta debe ser constante, para no tener variaciones que se
vayan luego a tomar en cuenta como diferencia a la hora de obtener los píxeles donde está
Agosto del 2004
IE-0502
52
Determinación de la posición de un objeto utilizando una cámara Web
el objeto. Aunque para evitar esto se incluyó el filtro anteriormente analizado, este no va a
eliminar del todo los picos de iluminación que se den, por ello es de vital importancia que
la iluminación se mantenga constante durante la toma de fotografías del objeto moviéndose.
Según la cámara que se utilice, puede tenerse un tiempo de calibración de la
iluminación cuando se utiliza por primera vez luego de arrancar el sistema operativo, por lo
que se recomienda que cuando se arranque el computador utilizado, antes de capturar el
movimiento del ratón en el laberinto, se ejecute la función que se agregó en la barra de
menú Acciones llamada “Calibrar la cámara” para asegurarse que no se den resultados
negativos.
Si se tienen en consideración las recomendaciones anteriormente dichas es posible
que no haya que tener preocupaciones por los datos obtenidos, ya que la eficacia del
programa es muy buena, la única consideración que queda es la del equipo utilizado, donde
la computadora debe tener un mínimo de especificaciones para que el programa puede
ejecutarse correctamente y con los tiempos que se tienen en la tabla 2.1 para tomar cada
foto. Además es posible que el tiempo que dure procesando cada foto aumente si la
computadora utilizada tiene menor memoria RAM o un procesador más lento, por lo que la
diferencia entre el equipo puede ocasionar que los resultados no sean satisfactorios, lo ideal
sería contar con una máquina con especificaciones parecidas a las utilizadas (las
especificaciones de la máquina usada se agregan en los anexos del trabajo) para poder tener
una absoluta confianza de que el programa corra exitosamente.
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
53
Anexo 4. Especificaciones del equipo utilizado
•
Procesador Intel Pentium 4 de 1.6 GHz
•
384 MB de memoria ram
•
Tarjeta de video Nvidia GeforceII de 32 MB
•
Tarjeta madre Intel I-810 con tarjeta de sonido incorporada
•
CD-Writer LG de 16x-10x-40x
•
Monitor LG Studioworks 553V
•
Cámara Web: IBM VGA camera XVP610, 5.0±5%V, 350mA Máximos.
FCC ID: KSX-X9902
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
54
Anexo 5. Código del programa
Programa mvc-0.8.8 modificado
Archivo mvc.c
/*
* mvc.c
*
* Copyright (C) Merlin Ma. 2000-2004.
* EMail: [email protected]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <linux/videodev.h>
#ifdef HAVE_JPEG
#include <jpeglib.h>
#endif
#ifdef HAVE_PNG
#include <png.h>
#endif
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
55
#include <libgen.h>
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <linux/videodev.h>
#ifdef HAVE_JPEG
#include <jpeglib.h>
#endif
#ifdef HAVE_PNG
#include <png.h>
#endif
#include "font.h"
#include "config.h"
typedef struct myvideo {
char *device;
int devfd;
int width;
int height;
int depth;
int input;
int maxinputs;
int norm;
unsigned int brightness;
unsigned int contrast;
char *buf;
int mmaped;
int mbufsize;
} MyVID;
/* global variable */
static int verbose = DEF_VERBOSE;
static int quitflag = 0;
static int daemon_flag = 0;
static int usr1_flag = 0;
static char *logfile = "/dev/null";
/* USER1 signal handler */
void sig_usr1(int signal)
{
printf("Got SIGUSR1, trigger a capture.\n");
usr1_flag = 1;
}
void block_sigs(void)
{
sigset_t masked_signals;
sigemptyset(&masked_signals);
sigaddset(&masked_signals, SIGUSR1);
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
56
sigaddset(&masked_signals, SIGINT);
sigaddset(&masked_signals, SIGTSTP);
sigprocmask(SIG_BLOCK, &masked_signals, NULL);
}
void unblock_sigs(void)
{
sigset_t masked_signals;
sigemptyset(&masked_signals);
sigaddset(&masked_signals, SIGUSR1);
sigaddset(&masked_signals, SIGINT);
sigaddset(&masked_signals, SIGTSTP);
sigprocmask(SIG_UNBLOCK, &masked_signals, NULL);
}
void usage(void)
{
fprintf(stderr,
"mvc version " VERSION " - motion detection video capture program \n\n"
"Usage: mvc <options>\n\n"
" -B picture brightness value.\n"
" -C picture contrast value.\n"
" -D run in daemon mode.\n"
" -O Base directory for output images. default is current dir.\n"
" -o Don't create sub-directories for output.\n"
" -t Print t imestamp on image.\n"
" -d <device> video device (default:" VIDEO_DEV ").\n"
" -e <program> excute a external program while motion detected.\n"
" -f {jpeg|png} set output file format. default is jpeg.\n"
" -q <quality>
jpeg quality setting. \n"
" -h print this help.\n"
" -i <channel> which input channel to use, default is 1, or 0 if only 1 input.\n"
" -m use mono color (grayscale) for capture.\n"
" -n {pal|ntsc|secam|auto} video norm to use, default: PAL\n"
" -s XxY size of the output image, example: -s 640x480\n"
" -a HxV block division number in Horizantal and Vertical. Ex: -a 16x8\n"
" -b <diff_block_limit>
threshold of hot block number.\n"
" -c <diff_color_limit>
threshold of block color difference.\n"
" -w delay time for each capture(seconds), example: -w 0.5\n"
" -l logfile used in daemon mode. default is null.\n"
" -v increase verbose level for more details, can multiple applied.\n\n");
}
/* init v4l device for image capture */
int v4l_init(MyVID * myvid)
{
int devfd;
int i, ret = 0;
int input;
struct video_capability vid_caps;
struct video_channel vid_chnl;
struct video_picture vid_pict;
struct video_window vid_win;
struct video_mbuf vid_buf;
/*
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
57
* open the video4linux device
*/
int max_try = 5;
while ((devfd = open(myvid->device, O_RDWR)) == -1 && --max_try)
sleep(1);
if (devfd == -1) {
fprintf(stderr, "Can't open device %s\n", VIDEO_DEV);
ret urn -1;
}
myvid->devfd = devfd;
/*
* get capabilities of the device
*/
if (ioctl(devfd, VIDIOCGCAP, &vid_caps) == -1) {
perror("ioctl (VIDIOCGCAP)");
return -2;
}
myvid->maxinputs = vid_caps.channels;
/* print channel names */
if (verbose >= 2) {
for (i = 0; i < myvid->maxinputs; i++) {
vid_chnl.channel = i;
if (ioctl(devfd, VIDIOCGCHAN, &vid_chnl) == -1) {
perror("ioctl (VIDIOCGCHAN)");
}
printf("The name of input channel #%d is \"%s\".\n", i, vid_chnl.name);
}
}
input = myvid->input;
if (input == -1) {
// if no input channel specified, use first composite.
input = (myvid->maxinputs == 1) ? 0 : 1;
// tv often use channel 0, skip it.
}
if (myvid->input > myvid->maxinputs - 1) {
input = myvid->maxinputs - 1;
printf("Warning: Input channel number over range. use %d instead.\n", input);
}
if (verbose >= 2) {
printf("Total %d input channel(s). Using channel #%d.\n", myvid->maxinputs, input);
printf("Supported resolution range: %dx%d => %dx%d\n\n", vid_caps.minwidth,
vid_caps.minheight, vid_caps.maxwidth, vid_caps.maxheight);
}
/*
* get default video properties and then set new value
*/
if (ioctl(devfd, VIDIOCGPICT, &vid_pict) == -1) {
perror("ioctl (VIDIOCGPICT)");
ret = 1;
}
vid_pict.brightness = myvid->brightness;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
58
vid_pict.contrast = myvid->contrast;
if (myvid->depth == 1)
vid_pict.palette = VIDEO_PALETTE_GREY;
else if (myvid->depth == 3)
vid_pict.palette = VIDEO_PALETTE_RGB24;
else {
printf("Wrong color depth. only 1 or 3 is valid.\n");
return -3;
}
if (ioctl(devfd, VIDIOCSPICT, &vid_pict) == -1) {
perror("ioctl (VIDIOCSPICT)");
ret = 1;
}
/*
* get default and then set new channel and norm
*/
vid_chnl.channel = input;
if (ioctl(devfd, VIDIOCGCHAN, &vid_chnl) == -1) {
perror("ioctl (VIDIOCGCHAN)");
}
vid_chnl.channel = input;
vid_chnl.norm = myvid->norm;
if (ioctl(devfd, VIDIOCSCHAN, &vid_chnl) == -1) {
perror("ioctl (VIDIOCSCHAN)");
ret = 2;
}
/*
* check if drvier support mmap mode and do init
*/
if (ioctl(devfd, VIDIOCGMBUF, &vid_buf) == -1) {
fprintf(stderr, "No mmap support, Use read instead.\n");
myvid->mmaped = 0;
if (ioctl(devfd, VIDIOCGWIN, &vid_win) != -1) {
vid_win.width = myvid->width;
vid_win.height = myvid->height;
if (ioctl(devfd, VIDIOCSWIN, &vid_win) == -1) {
perror("ioctl (VIDIOCSWIN)");
return -2;
}
}
}
else {
myvid->mmaped = 1;
myvid->mbufsize = vid_buf.size;
}
return ret;
}
/*
* read rgb image from v4l device
* return: mmap'ed buffer and size
*/
int get_image(MyVID * myvid)
{
struct video_mmap vid_mmap;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
59
char *map;
int len;
int framesize = myvid->width * myvid->height * myvid->depth;
if (myvid->mmaped) {
map = mmap(0, myvid->mbufsize, PROT_READ | PROT_WRITE, MAP_SHARED, myvid->devfd,
0);
if ((unsigned char *) -1 == (unsigned char *) map) {
perror("mmap()");
return -1;
}
vid_mmap.format = (myvid->depth == 1) ? VIDEO_PALETTE_GREY :
VIDEO_PALETTE_RGB24;
vid_mmap.frame = 0;
vid_mmap.width = myvid->width;
vid_mmap.height = myvid->height;
if (ioctl(myvid->devfd, VIDIOCMCAPTURE, &vid_mmap) == -1) {
perror("VIDIOCMCAPTURE");
munmap(map, myvid->mbufsize);
return -1;
}
if (ioctl(myvid->devfd, VIDIOCSYNC, &vid_mmap) == -1) {
perror("VIDIOCSYNC");
munmap(map, myvid->mbufsize);
return -1;
}
memcpy(myvid->buf, map, framesize);
munmap(map, myvid->mbufsize);
}
else {
len = read(myvid->devfd, myvid->buf, framesize);
if (len <= 0) {
return -1;
}
}
return 0;
}
/*
* Write image buffer to jpeg file.
*/
void put_image_jpeg(char *filename, IMG image, int quality)
{
#ifdef HAVE_JPEG
char *buf = image.buf;
int width = image.width;
int height = image.height;
int depth = image.depth;
int y, x, line_width;
JSAMPROW row_ptr[1];
struct jpeg_compress_struct cjpeg;
struct jpeg_error_mgr jerr;
char *line;
FILE *fd;
if ((fd = fopen(filename, "w+")) == NULL) {
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
60
perror("fopen JPG");
exit(-2);
}
line = malloc(width * 3);
if (!line)
return;
cjpeg.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cjpeg);
cjpeg.image_width = width;
cjpeg.image_height = height;
cjpeg.input_components = 3;
cjpeg.in_color_space = JCS_RGB;
if (depth == 1) {
cjpeg.input_components = 1;
cjpeg.in_color_space = JCS_GRAYSCALE;
}
jpeg_set_defaults(&cjpeg);
jpeg_set_quality(&cjpeg, quality, TRUE);
cjpeg.dct_method = JDCT_FASTEST;
jpeg_stdio_dest(&cjpeg, fd);
jpeg_start_compress(&cjpeg, TRUE);
row_ptr[0] = line;
if (depth == 1) {
line_width = width;
for (y = 0; y < height; y++) {
row_ptr[0] = buf;
jpeg_write_scanlines(&cjpeg, row_ptr, 1);
buf += line_width;
}
}
else {
line_width = width * 3;
for (y = 0; y < height; y++) {
for (x = 0; x < line_width; x += 3) {
line[x] = buf[x + 2];
line[x + 1] = buf[x + 1];
line[x + 2] = buf[x];
}
jpeg_write_scanlines(&cjpeg, row_ptr, 1);
buf += line_width;
}
}
jpeg_finish_compress(&cjpeg);
jpeg_destroy_compress(&cjpeg);
free(lin e);
fclose(fd);
#else
fprintf(stderr, "NOT Compiled with JPEG support!\n\n");
exit(2);
#endif
}
/*
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
61
* Create direcotry recursively
*/
/*
int pmkdir(char *path)
{
struct stat st;
int umask_save;
char *dir, *parent;
dir = strdup(path);
if (stat(dir, &st) < 0 && errno == ENOENT) {
parent = dirname(dir);
pmkdir(parent);
if (verbose >= 1)
printf("Making dir: %s\n", path);
umask_save = umask(0);
umask(umask_save);
if (mkdir(path, 00777 & ~umask_save) < 0) {
perror("MKDIR ");
};
}
free(dir);
return 0;
}*/
/*
* Divide image into sx * sy blocks. For each splited block,
* calculate its average RGB color, then store these RGB color
* values into array r.
*/
int proc_img(RGB24 * r, IMG image, int sx, int sy)
{
char *buf = image.buf;
int w = image.width;
int h = image.height;
int depth = image.depth;
unsigned char *p;
int x, y, m, n;
int blk_wid = w / sx, blk_hgt = h / sy;
int x0, y0, x1, y1;
int s = blk_wid * blk_hgt;
unsigned int R, G, B;
int r_offset, g_offset;
if (depth == 1) {
r_offset = 0;
g_offset = 0;
}
else {
r_offset = 2;
g_offset = 1;
}
for (n = 1; n <= sy; n++) {
for (m = 1; m <= sx; m++) {
x0 = (m - 1) * blk_wid;
y0 = (n - 1) * blk_hgt;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
62
x1 = blk_wid * m - 1;
y1 = blk_hgt * n - 1;
R = G = B = 0;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++) {
p = buf + (y * w + x) * depth;
R += *(p + r_offset);
G += *(p + g_offset);
B += *p;
}
}
r->red = R / s;
r->green = G / s;
r->blue = B / s;
r++;
}
}
return s;
}
/*
* main()
*/
int main(int argc, char **argv)
{
//int entrada_contador=0;
int contador=0;
/*creo un contador para tomar un numero determinado de posiciones*/
int c=0,n = 0;
int ofmt = DEF_FMT;
int create_dir = 1;
int ptimestamp = PRINT_TIME;
int prog_run = 0, ret, pstat;
int blks, slow_count;
int i,j,k;
unsigned int buflen;
char *buf;
IMG image;
RGB24 *colors_new, *colors_last, *colors_older, *ptr;
char *basedir = BASEDIR;
char *userprog = NULL;
pid_t pid = -1;
char lasttime[32], str_date[32], str_time[32],filename[255];
time_t now;
struct tm *tm;
float w = DEF_INTERVAL;
unsigned int delay = w * 1000000;
MyVID myvid;
char *device = VIDEO_DEV;
int width = DEF_WIDTH, height = DEF_HEIGHT;
int input = IN_DEFAULT;
int norm = NORM_DEFAULT;
int brightness = DEF_BRIGHTNESS;
int contrast = DEF_CONTRAST;
int depth = 3;
int blk_x = DEF_BLK_X;
int blk_y = DEF_BLK_Y;
int color_diff_ts = DEF_COLOR_TS;
/* default color diff threshold */
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
int hotblk_ts = blk_x * blk_y / 64 + 1;
int jpeg_quality = QUAL_DEFAULT;
63
/* default hot block threshold */
/* default jpeg quality setting */
//ENTRADA DEL NUMERO DE VECES A EJECUTAR EL PROGRAMA
i=j=k=0;
while((int)argv[1][i]!=0)
{
k=k*10+(int)argv[1][i]-48;
i++;
}
if(contador==25){
printf("SE VAN A INICIAR A DETERMINAR LAS POSICIONES");
}
if (signal(SIGUSR1, sig_usr1) == SIG_ERR) {
printf("can not setup SIGUSR1 handler.\n");
exit(1);
}
while ((c = getopt(argc, argv, "B:C:O:a:b:c:d:e:s:q:f:n:i:l:w:Dhmovt")) != EOF) {
/*
* B: brightness -B 32768
* C: contrast -C 32768
* D: run in daemon mode
* O: base directory for output
* o: don't create sub-directories
* a: horizontal split number x vertical split number -a 16x8
* b: threshold of hot block number (0-blk_x*blk_y)
* c: threshold of color diff for each block (0-255*3)
* d: v4l device name
* e: execute a external program while motion detected.
* s: width x height -s 640x480
* q: jpeg quality -q 85
* f: output file format
* t: print timestamp on image
* m: grayscale mode
* n: input video norm
* i: input channel #
* l: logfile -l /var/log/mvc.log
* w: delay time for each capture(seconds), -w 0.5
* h: help
*/
switch (c) {
case 'B':
sscanf(optarg, "%d", &brightness);
break;
case 'C':
sscanf(optarg, "%d", &contrast);
break;
case 'D':
daemon_flag = 1;
break;
case 'O':
basedir = optarg;
break;
case 'd':
device = optarg;
break;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
64
case 's':
sscanf(optarg, "%dx%d", &width, &height);
break;
case 'a':
sscanf(optarg, "%dx%d", &blk_x, &blk_y);
hotblk_ts = blk_x * blk_y / 64 + 1;
break;
case 'b':
sscanf(optarg, "%d", &hotblk_ts);
break;
case 'c':
sscanf(optarg, "%d", &color_diff_ts);
break;
case 'e':
userprog = optarg;
break;
case 'f':
if (strcasecmp("jpeg", optarg) == 0) {
ofmt = FMTJPEG;
}
else if (strcasecmp("png", optarg) == 0) {
ofmt = FMTPNG;
}
break;
case 't':
ptimestamp = 1;
break;
case 'm':
depth = 1;
break;
case 'n':
if (strcasecmp("ntsc", optarg) == 0) {
norm = VIDEO_MODE_NTSC;
}
else if (strcasecmp("pal", optarg) == 0) {
norm = VIDEO_MODE_PAL;
}
else if (strcasecmp("secam", optarg) == 0) {
norm = VIDEO_MODE_SECAM;
}
else if (strcasecmp("auto", optarg) == 0) {
norm = VIDEO_MODE_AUTO;
}
break;
case 'o':
create_dir = 0;
break;
case 'q':
sscanf(optarg, "%d", &jpeg_quality);
break;
case 'w':
sscanf(optarg, "%f", &w);
delay = w * 1000000;
break;
case 'i':
sscanf(optarg, "%d", &input);
break;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
65
case 'l':
logfile = optarg;
break;
case 'v':
verbose++;
break;
case 'h':
default:
usage();
exit(1);
}
}
myvid.device = device;
myvid.width = width;
myvid.height = height;
myvid.depth = depth;
myvid.input = input;
myvid.norm = norm;
myvid.brightness = brightness;
myvid.contrast = contrast;
block_sigs();
/* bttv driver ioctl hates signal */
if (v4l_init(&myvid) != 0) {
fprintf(stderr, "v4l init fault!\n");
exit(0);
}
unblock_sigs();
buflen = myvid.width * myvid.height * myvid.depth;
myvid.buf = malloc(buflen);
blks = blk_x * blk_y;
colors_new = calloc(blks, sizeof(RGB24));
colors_last = calloc(blks, sizeof(RGB24));
colors_older = calloc(blks, sizeof(RGB24));
/* grub a init image as reference */
if (verbose >= 3) {
printf("Initializing first image...\n");
}
block_sigs();
image.buf = myvid.buf;
image.width = width;
image.height = height;
image.depth = depth;
if (get_image(&myvid) == 0) {
unblock_sigs();
proc_img(colors_last, image, blk_x, blk_y);
memcpy(colors_older, colors_last, blks * sizeof(RGB24));
}
/* begin loop */
slow_count = 0;
while (!quitflag) {
Agosto del 2004
IE-0502
66
Determinación de la posición de un objeto utilizando una cámara Web
block_sigs();
if (get_image(&myvid) == 0) {
unblock_sigs();
buf = myvid.buf;
image.buf = myvid.buf;
proc_img(colors_new, image, blk_x, blk_y);
contador++;
//incremento al contador
/* Write Image */
//ESCRIBE EL NUMERO DE FOTOS QUE QUIERA Y LAS LLAMA Foto#
time(&now);
tm = localtime(&now);
strftime(str_time, 31, "%H.%M.%S", tm);
strftime(str_date, 31, "%Y-%m-%d", tm);
if (strcmp(str_time, lasttime) == 0)
n++;
else
n = 0;
strcpy(lasttime, str_time);
sprintf(filename,"objeto%i",contador);
if (ofmt == FMTJPEG) {
strcat(filename, ".jpg");
put_image_jpeg(filename, image, jpeg_quality);
}
if (verbose >= 1) {
printf("Se imprimio el %s --- %s\a\n", filename,str_time);
}
/* fork and execute external program if needed */
if (userprog != NULL) {
if (!prog_run) {
prog_run = 1;
if (verbose >= 3) {
printf("Start user program: %s\n", userprog);
}
if ((pid = fork()) == -1) {
perror("Fork: ");
exit(-1);
}
}
if (pid == 0) {
}
else {
// child
ret = system(userprog);
exit(ret);
// parent
if (waitpid(-1, &pstat, WNOHANG) != 0) {
if (WIFEXITED(pstat) && verbose >= 3) {
printf("User program is done.
exit code %d.\n", WEXITSTATUS(pstat));
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
67
}
prog_run = 0;
}
}
}
/* update 'color_older' array */
memcpy(colors_older, colors_new, blks * sizeof(RGB24));
slow_count = 0;
/************************************************************************/
EL PROGRAMA SE EJECUTA HASTA TOMAR 10 FOTOS EN QUE DETECTO MOVIMIENTO
/************************************************************************/
if(contador>=k){
quitflag=1;
}
ptr = colors_last;
colors_last = colors_new;
colors_new = ptr;
}
else {
fprintf(stderr, "Error: Can't get image \n");
}
usleep(delay);
}
exit(0);
/* end of while */
}
Archivo font.h
typedef struct RGB24 {
unsigned char red;
unsigned char green;
unsigned char blue;
} RGB24;
typedef struct IMG {
int width;
int height;
int depth;
int format;
char *buf;
} IMG;
typedef struct font {
char *fontdata;
int char_width;
int char_height;
} FONT;
extern void fontinit();
extern int gputch(IMG image, int x0, int y0, int ch, RGB24 color, FONT font);
extern int gputs(IMG image, int x0, int y0, char *str, RGB24 color, FONT font);
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
68
extern FONT font8x16;
extern FONT font6x11;
Archivo config.h
#define VERSION "0.8.8"
/* Default video device */
#define VIDEO_DEV
"/dev/video0"
/* Default output directory */
#define BASEDIR "."
/* Default capture size */
#define DEF_WIDTH
320
#define DEF_HEIGHT 240
/* Default input port
* usually, tv = 0, composite1 = 1, composite2 = 2, svideo = 3.
* if specify -1 here and if only 1 channel (such as ov511 webcam) supported
* by your device, then mvc will use channel 0 as input, if more than 1 channels
* supported by your device (such as most bttv card), it will use channel 1
* as input, because most tv card use channel 0 as tv input, so skip it.
*/
#define IN_DEF AULT
-1
/* Default video norm, defined in videodev.h */
#define NORM_DEFAULT VIDEO_MODE_PAL
/* Default brightness and contrast value (0-65535) */
#define DEF_BRIGHTNESS 32768
#define DEF_CONTRAST 32768
/* Default screen divider */
#define DEF_BLK_X
#define DEF_BLK_Y
16
8
/* Default block color diff threshold */
#define DEF_COLOR_TS 50
/* Default interval for sample rate (sec) */
#define DEF_INTERVAL 0.3
/* this multiplier used for slow motion detection.
Usually, this value is good enough. To disable
slow motion detect, set 0 here. */
#define SLOW_COUNT_MAX
60
/* Default output format */
#define DEF_FMT
FMTJPEG
#define FMTJPEG
#define FMTPNG
1
2
/* Default JPEG file quality */
#define QUAL_DEFAULT 90
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
69
/* Default verbose level for message output */
#define DEF_VERBOSE
1
/* Print timestamp on image or not.
* FONTSIZE, font6x11 for smaller, font8x16 for bigger
*/
#define PRINT_TIME
0
#define FONTSIZEfont6x11
Archivo makefile
include depend.inc
prefix=/usr
dist=$(prefix)/bin
CC = gcc
all: mvc
depend.inc:
@echo Generating depend.inc file for this system...
@sh depend.sh
OBJS=mvc.o font.o
mvc: $(OBJS)
$(CC) $(LIBS) -o $@ $(OBJS)
.c.o:
$(CC) $(CFLAGS) $(DEFS) -c $<
strip: mvc
strip -s mvc
install: mvc
mkdir -p $(dist)
install -s mvc $(dist)/
clean:
rm -f *.o mvc
distclean: clean
rm -f depend.inc *.jpg *.bak *~
rm -rf [0-9][0-9][0-9][0-9]-*
Archivo depend.inc
LIBS= -ljpeg -lpng12
CFLAGS=-O2 -Wall -g -I. -I/usr/include/libpng12
DEFS= -DHAVE_JPEG -DHAVE_PNG
Archivo depend.sh
#!/bin/sh
CC=${CC-gcc}
CFLAGS=${CFLAGS-'-O2 -Wall -g -I.'}
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
70
LIBS=''
DEFS=''
compile='rm -f conftest.o ; $CC $CFLAGS $CFLAGS2 $TESTLIBS conftest.c -o conftest &> /dev/null'
#test libjpeg
[ -f conftest ] && rm -f conftest
cat << XEOF > conftest.c
#include <stdio.h>
#include <jpeglib.h>
main()
{
struct jpeg_compress_struct cjpeg;
struct jpeg_error_mgr jerr;
cjpeg.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cjpeg);
}
XEOF
TESTLIBS='-ljpeg'
eval $compile
if [ -f conftest ] ; then
LIBS="$LIBS -ljpeg"
DEFS="$DEFS -DHAVE_JPEG"
else
echo "WARNING: libjpeg NOT Found."
fi
#test libpng
[ -f conftest ] && rm -f conftest
cat << XEOF > conftest.c
#include <stdio.h>
#include <png.h>
main()
{
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
}
XEOF
TESTLIBS='-lpng'
if which libpng-config &> /dev/null ; then
CFLAGS2=`libpng-config --cflags`
TESTLIBS=`libpng-config --libs`
else if which pkg-config &> /dev/null ; then
for libpng in libpng libpng12 libpng10 nolibpng.pc; do
if pkg-config --exists $libpng ; then
break;
fi
done
if [ "$libpng" != "nolibpng.pc" ] ; then
CFLAGS2=`pkg-config --cflags $libpng`
TESTLIBS=`pkg-config --libs $libpng`
fi
fi
fi
eval $compile
if [ -f conftest ] ; then
Agosto del 2004
IE-0502
71
Determinación de la posición de un objeto utilizando una cámara Web
CFLAGS="$CFLAGS $CFLAGS2"
LIBS="$LIBS $TESTLIBS"
DEFS="$DEFS -DHAVE_PNG"
else
echo "WARNING: libpng NOT Found."
fi
rm -f conftest.c conftest
echo LIBS=$LIBS > depend.inc
echo CFLAGS=$CFLAGS >> depend.inc
echo DEFS=$DEFS >> depend.inc
Programa Principal
Archivo interfaz.h
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "wx/file.h"
#include "wx/mstream.h"
#include "wx/wfstream.h"
#include "wx/quantize.h"
#include <ctime>
#include <cstring>
#ifndef C_matriz_H
#define C_matriz_H
/*************************************************************/
#include <iostream>
/*************************************************************/
using namespace std;
/*************************************************************/
/*************************************************************************
COMIENZA LA DEFINICION DE LA CLASE C_matriz Y LAS FUNCIONES DE LA MISMA, ADEMAS DE LAS
FUNCIONES PARA EL PROCESAMIENTO DE LAS FOTOGRAFIAS TOMADAS
*************************************************************************/
class C_matriz
{
public:
C_matriz(int=1, int=1);
//parámetros por defecto, estos son fila, columna
C_matriz(const C_matriz &);
//constructor de copia
~C_matriz();
float get(int fila, int columna) const; //retorna un elemento de la C_matriz
void set(int fila, int columna ,float dato); //graba un elemento en una posición de la C_matriz
C_matriz &operator=(const C_matriz &);
//Operador de asignación
Agosto del 2004
IE-0502
72
Determinación de la posición de un objeto utilizando una cámara Web
private:
int filas;
int columnas;
float *ptr_data;
};
/*************************************************************/
#endif
C_matriz::C_matriz(int x, int y)
{
x>0 ? filas=x : filas=1;
y>0 ? columnas=y : columnas=1;
ptr_data=new float[filas*columnas]; //se crea un puntero, en el se va a almacenar
for(int i=0;i<filas*columnas;i++)
//los datos de la matriz, luego se limpia el arreglo
ptr_data[i]=0;
//para evitar que tenga basura
};
/*************************************************************/
C_matriz::C_matriz(const C_matriz &Matriz) //este es un cosntructor de copia
{
filas=Matriz.filas;
columnas=Matriz.columnas;
ptr_data=new float[filas*columnas];
for(int i=0;i<filas*columnas;i++)
ptr_data[i]=Matriz.ptr_data[i];
};
/*************************************************************/
C_matriz::~C_matriz()
{
delete [] ptr_data;
//el destructor borra el puntero
};
/*************************************************************/
/* El operador = se utiliza para hacer la igual entre una */
/* funcion y un objeto tipo C_matriz
*/
C_matriz &C_matriz::operator=(const C_matriz & Matriz)
{
if(&Matriz!=this)
//this es un puntero, aqui se verifica
{
if((filas!=Matriz.filas)||
//que los valores adquiridos sean los mismos
(columnas!=Matriz.columnas)) //que la matriz que se esta igualando
{
delete [] ptr_data;
filas=Matriz.filas;
columnas=Matriz.columnas;
ptr_data=new float[filas*columnas];
}
for(int i=0;i<filas*columnas;i++)
ptr_data[i]=Matriz.ptr_data[i];
//aqui se realiza la igualdad de los elementos
}
//de la matriz
return *this;
//permite concatenación
};
/*************************************************************/
float C_matriz::get(int i,int j) const
//la funcion obtiene los valores de las posiciones
{
//de la matriz que se le indique
if(i>=0 && i<=filas && j>=0 && j<=columnas) //se asegura que no se pase de los limites de la matriz
return ptr_data[(i-1)*columnas+(j-1)]; //returna de esta manera, dado a que se tiene solo
Agosto del 2004
IE-0502
73
Determinación de la posición de un objeto utilizando una cámara Web
else
{
//un arreglo, donde se conoce las filas y las columnas
//desplega un mensaje de error y terminas la funcion
//en la cuál se llamó a get()
cout<<"get() error: Ãndices fuera de los là mites"<<i<<","<<j<<endl;
exit(0);
}
};
/*************************************************************/
void C_matriz::set(int i,int j,float element) //la funcion set guarda un dato tipo float en la posicion
{
//de la matriz que se le indique
if(i>0 && i<=filas && j>0 && j<=columnas) //se asegura que no se pase de los limites de la matriz
ptr_data[(i-1)*columnas+(j-1)]=element; //lo guarda de esta manera ya que la matriz se guarda
else
//en un arreglo
{
//desplega un mensaje de error y terminas la funcion
//en la cuál se llamó a set()
cout<<"set() error: Ãndices fuera de los lÃmites"<<endl;
exit(0);
}
};
/********************************************************/
//Funcion para imprimir la imagen, crear un archivo de nombre archivo_modificado
bool imprimir(string archivo, string archivo_modificado, const C_matriz &matriz){
Image Imagen(archivo);
//utiliza la libreria magick++ para obtener el valor de cada pixel
ColorRGB pixelrgb;
//y sus tres elementos para RGB
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1; j<=320;j++){
pixelrgb=Imagen.pixelColor(j-1,i-1);
//magick++ recorre primero columns luego rows, contrario a matriz
pixelrgb.green(matriz.get(i,j));
pixelrgb.red(matriz.get(i,j));
pixelrgb.blue(matriz.get(i,j));
Imagen.pixelColor(j-1,i-1,pixelrgb);
//Asigna al objeto tipo Image el valor del pixel
}
}
Imagen.write(archivo_modificado);
//crea una imagen con los valores del objeto Imagen
return true;
}
/*************************************************************************
La función iluminancia se utiliza para crear la imagen en grises, utilizando los valores dados para multiplicar los
elementos RGB de cada pixelColor
*************************************************************************/
C_matriz iluminancia(string imagen1){
Image Imagen;
Imagen.read(imagen1);
ColorRGB pixelrgb;
C_matriz matriz_iluminancia(Imagen.rows(),Imagen.columns());
float iluminancia1;
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1;j<=320;j++){
pixelrgb=Imagen.pixelColor(j-1,i-1);
Agosto del 2004
IE-0502
74
Determinación de la posición de un objeto utilizando una cámara Web
iluminancia1 = pixelrgb.red()*0.299 + pixelrgb.green()*0.587 +pixelrgb.blue()*0.114;
matriz_iluminancia.set(i,j,iluminancia1);
}
}
return matriz_iluminancia;
}
/*************************************************************************
El siguiente filtro observa el valor de cada pixel, si el valor es muy alto lo reduce en
mayor medida, conforme los valores van siendo mas bajos, los va reduciendo en menor medida.
Ademas reduce un poco los vecinos tipo 4 para no tener mucha variacion en la imagen
*************************************************************************/
C_matriz filtro1(C_matriz &matriz){
for (unsigned int i=2; i<=239;i++){
for (unsigned int j=2;j<=319;j++){
if(matriz.get(i,j)>0.8){
matriz.set(i,j,matriz.get(i,j)*0.85);
matriz.set(i,j-1,matriz.get(i,j-1)*0.9);
matriz.set(i,j+1,matriz.get(i,j+1)*0.9);
matriz.set(i-1,j,matriz.get(i-1,j)*0.9);
matriz.set(i+1,j,matriz.get(i+1,j)*0.9);
}
}
}
return matriz;
}
/*************************************************************************
Esta funcion es la encargada de detectar los pixeles en que se encuentra el objeto,
recibe dos matrices que contienen los valores en escala de grises de dos imagenes y los
compara, restandolos y sacando su valor absoluto, luego pone en negro los valores ,
dependiendo si la diferencia fue mayor al valor almacenado en la variable limites
*************************************************************************/
C_matriz deteccion_objeto(C_matriz &matriz_fondo,C_matriz &matriz_objeto,float limite ){
float elemento;
C_matriz matriz_resta(240,320);
for (unsigned int i=1; i<=239;i++){
for (unsigned int j=1;j<=319;j++){
elemento=abs(matriz_fondo.get(i,j)-matriz_objeto.get(i,j)); //Saca el valor absoluto a cada
resultado de la resta
matriz_resta.set(i,j,elemento); //almacena el valor en matriz_resta
if(matriz_resta.get(i,j)>limite){ //lo evalua a ver si es mayor al limite lo pone negro
matriz_resta.set(i,j,0);
//sino lo pone blanco
}
else{
matriz_resta.set(i,j,1);
}
}
}
return matriz_resta;
}
/*************************************************************************
La funcion centroides_x obtiene el centroide en x del objeto almacenado en la matriz que
contiene el objeto en color negro, siendo esta el resultado de la funcion deteccion_objeto,
esta suma en la variable numero_pixeles los pixeles que forman el objeto que seria el area
y en la variable suma_x las distancias de este pixel a el pixel en (0,0), luego aplica la
formula para el centroide, dividiendo la suma de las distancias entre el total de pixeles
del objeto y devuelve la posicion donde se encuentra el centroide
*************************************************************************/
Agosto del 2004
IE-0502
75
Determinación de la posición de un objeto utilizando una cámara Web
unsigned int centroides_x(C_matriz &matriz){
unsigned int centroide_x;
unsigned int suma_x=0;
unsigned int numero_pixeles=0;
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1;j<=320;j++){
if(matriz.get(i,j)==0){
suma_x=suma_x+j;
numero_pixeles++;
}
}
}
centroide_x=(suma_x/numero_pixeles);
return (centroide_x);
}
/*************************************************************************
Esta funcion hace el mismo procedimiento que la funcion centroides_x, pero con los valores en el eje y, para luego
devolver la posicion del centroide en el eje y
*************************************************************************/
unsigned int centroides_y(C_matriz &matriz){
unsigned int centroide_y;
unsigned int suma_y=0;
unsigned int numero_pixeles=0;
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1;j<=320;j++){
if(matriz.get(i,j)==0){
suma_y=suma_y+i;
numero_pixeles++;
}
}
}
centroide_y=(suma_y/numero_pixeles);
return (centroide_y);
}
/*************************************************************************
Esta funcion basicamente recibe una matriz en la que se encuentran los pixeles de una imagen y le escribe encima unas
rayas negras mostrando la division de zonas que se esta haciendo para determinar la posicion del objeto
*************************************************************************/
C_matriz cuadricula(C_matriz &matriz){
C_matriz matriz_cuadricula(240,320);
float elemento;
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1;j<=320;j++){
if((j==320)||(j==256)||(j==192)||(j==128)||(j==64)||(j==1)){
matriz_cuadricula.set(i,j,1);
}
else{
if((i==240)||(i==192)||(i==144)||(i==96)||(i==48)||(i==1)){
matriz_cuadricula.set(i,j,1);
}
else{
elemento=matriz.get(i,j);
matriz_cuadricula.set(i,j,elemento);
}
}
}
Agosto del 2004
IE-0502
76
Determinación de la posición de un objeto utilizando una cámara Web
}
return matriz_cuadricula;
}
/*************************************************************************
IMPLEMENTACION DE LA CLASE Time Y DE LAS FUNCIONES NECESARIAS PARA DETERMINAR EL
TIEMPO EN QUE SE ESTAN DETERMINANDO LAS POSICIONES
*************************************************************************/
class Time {
std::time_t t;
std::tm local;
char asciiRep[26];
//crea un arreglo de tipo char para almacenar los caracteres
unsigned char lflag,aflag; //de la hora
void updatelocal(){
if(!lflag){
local= *std::localtime(&t);
//se tiene un puntero t para determinar cuando se llamo la funcion
}
}
void updateAscii(){
if(!aflag){
updatelocal();
//devuelve un string en Ascii con la hora y fecha
std::strcpy(asciiRep,std::asctime(&local));
aflag++;
}
}
public:
Time() {mark();}
void mark() {
lflag=aflag=0;
std::time(&t);
}
const char* ascii(){
updateAscii();
return asciiRep;
}
//devuelve el string con la fecha y hora
int delta(Time* dt) const {
return int(std::difftime(t,dt->t));
//devuelve el tiempo transcurrido desde start hasta end
}
//los cuales son punteros de inicio y final
};
/*************************************************************************
COMIENZA LA IMPLEMENTACION DE LA INTERFAZ GRAFICA
*************************************************************************/
class MyApp: public wxApp
{
public:
bool OnInit();
//esta clase contempla las caracteristicas de la ventana
};
class MyFrame: public wxFrame
{
public:
MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h);
virtual ~MyFrame() { delete wxLog::SetActiveTarget(m_logOld); }
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
77
void OnAbout( wxCommandEvent &event );
//son las definiciones de las funciones que se van
void OnQuit( wxCommandEvent &event ); //a tener para realizar todas las funciones que
void AbrirFondo( wxCommandEvent &event ); //tiene el programa en el menu
void AbrirObjeto( wxCommandEvent &event );
void Posiciones( wxCommandEvent &event);
void AbrirPosicion( wxCommandEvent &event);
void AbrirPosiciones( wxCommandEvent &event);
void Calibracion(wxCommandEvent &event);
wxTextCtrl *m_log; //este puntero es el utilizado para escribir al cuadro de texto
wxLog
*m_logOld; //de la ventana del programa
private:
DECLARE_EVENT_TABLE()
//se declara una tabla de eventos donde se incluyen las funciones
};
/************************************************************************/
Archivo interfaz2.cpp
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#include <iostream>
using namespace std;
#include <Magick++.h>
using namespace Magick;
#include <string>
using std::string;
#include <fstream>
#include <cstdio>
#include <cstdlib>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/frame.h"
#include "wx/panel.h"
#include "wx/stattext.h"
#include "wx/menu.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#endif
#include "wx/calctrl.h"
#include "interfaz2.h"
/***********************************************************************
Esta instruccion se pone para que el compilador sepa que se va a implementar una
ventana de clase MyApp
************************************************************************/
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
78
IMPLEMENT_APP(MyApp)
//Definiciones de las funciones que se tienen en la barra de menu de la ventana
enum
{
ID_QUIT = 108,
ID_ABOUT = 109,
ID_ABRIRFONDO = 112,
ID_ABRIROBJETO = 113,
ID_POSICIONES = 114,
ID_ABRIRPOSICION = 115,
ID_ABRIRPOSICIONES = 116,
ID_CALIBRAR = 117
};
bool MyApp::OnInit()
{
// Se crea la ventana principal del programa
MyFrame *frame = new MyFrame((wxFrame *) NULL,
_T("Deteccion de Objetos"), 50, 50, 700, 420);
frame->SetSizeHints( 500, 400 );
wxMenu *file_menu = new wxMenu();
//Se crea un puntero file_menu el cual despliega las funciones del menu Archivo
file_menu->Append( ID_ABOUT, _T("&Creditos..."));
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, _T("&Salir"));
//Se crea el menu Acciones, con las funciones que tiene
wxMenu *acciones_menu = new wxMenu();
acciones_menu->Append(ID_POSICIONES,_T("&Obtener
Posiciones"));
acciones_menu->Append(ID_ABRIRFONDO,_T("&Abrir Fotografia del Fondo"));
acciones_menu->Append(ID_ABRIROBJETO,_T("&Abrir Fotografia del ultimo objeto"));
acciones_menu->Append(ID_ABRIRPOSICION,_T("&Abrir Fotografia de la primera posicion"));
acciones_menu->Append(ID_ABRIRPOSICIONES,_T("&Abrir Fotografia de las posiciones"));
acciones_menu->Append(ID_ABRIRPOSICIONES,_T("&Calibracion de la camara"));
//se crea la barra de menu con las dos opciones Archivo y Acciones
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, _T("&Archivo"));
menu_bar->Append(acciones_menu,_T("&Acciones"));
frame->SetMenuBar(menu_bar);
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
/*************************************************************************
Se crea la tabla de eventos con todas las funciones que se tienen en la barra de menu creada
*************************************************************************/
BEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
EVT_MENU (ID_QUIT, MyFrame::OnQuit)
EVT_MENU (ID_ABRIRFONDO,MyFrame::AbrirFondo)
Agosto del 2004
IE-0502
79
Determinación de la posición de un objeto utilizando una cámara Web
EVT_MENU (ID_ABRIROBJETO,MyFrame::AbrirObjeto)
EVT_MENU (ID_ABRIRPOSICION,MyFrame::AbrirPosicion)
EVT_MENU (ID_ABRIRPOSICIONES,MyFrame::AbrirPosiciones)
EVT_MENU (ID_POSICIONES,MyFrame::Posiciones)
EVT_MENU (ID_CALIBRAR,MyFrame::Calibracion)
END_EVENT_TABLE()
/*************************************************************************
En el constructor de la clase MyFrame se crea el cuadro de texto en la ventana principal
del programa
*************************************************************************/
MyFrame::MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h)
: wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h) )
{
m_log = new wxTextCtrl( this, -1, _T("Esta es la ventana de control de eventos\nPara ejecutar el
programa vaya a Acciones y oprima Obtener Posiciones \nSi esta ejecutando el programa por primera vez luego de
inicializado Linux, debe calibrar la camara antes de Obtener posiciones"),
wxPoint(5,260), wxSize(630,100),
wxTE_MULTILINE | wxTE_READONLY /* | wxTE_RICH */);
m_logOld = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
CreateStatusBar(2);
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// TRUE forza a cerrar la ventana, si se escoge la opcion Salir del menu Archivo
Close(TRUE);
}
//Despliega una ventana con los creditos del programa y avisa la accion en la ventana
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Programa de Deteccion de Objetos\nCreado por: Juan Lara Flores\nEscuela de
Ingenieria\nUCR"),
_T("Creditos del Programa"), wxOK | wxICON_INFORMATION, this);
*m_log<<_T("Se abrio la ventana con los creditos del programa de Deteccion de objetos\n");
}
/*************************************************************************
La funciones llamadas AbrirXXXXX se utilizan para abrir una ventana con la foto que se dice en la barra del menu
Acciones, estas hacen una llamada a otro programa para que la foto que se despliegue sea la ultima que se genero, ya que
si no se hace de esta manera, se carga la que estaba con ese nombre antes de que se ejecute el programa principal
./interfaz2
*************************************************************************/
void MyFrame::AbrirFondo(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Se va a abrir la fotografia del fondo\nPara salir vaya al menu Archivo y ejecute el
comando Salir\n"),
_T("Fotografia del fondo"), wxOK | wxICON_INFORMATION, this);
system("./fondo"); //Se hace la llamada a otro programa para que se vea la ultima foto tomada
}
void MyFrame::AbrirObjeto(wxCommandEvent& WXUNUSED(event))
{
Agosto del 2004
IE-0502
80
Determinación de la posición de un objeto utilizando una cámara Web
wxMessageBox(_T("Se va a abrir la fotografia del objeto\nPara salir vaya al menu Archivo y ejecute el
comando Salir\n"),
_T("Fotografia del objeto"), wxOK | wxICON_INFORMATION, this);
system("./objeto");
}
void MyFrame::AbrirPosicion(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Se va a abrir la fotografia de la ultima primera posicion tomada\nPara salir vaya al menu
Archivo y ejecute el comando Salir\n"),
_T("Fotografia de la primera posicion"), wxOK | wxICON_INFORMATION, this);
system("./posicion");
}
void MyFrame::AbrirPosiciones(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Se va a abrir la fotografia de las posiciones determinadas\nPara salir vaya al menu Archivo
y ejecute el comando Salir\n"),
_T("Fotografia de las posiciones determinadas"), wxOK | wxICON_INFORMATION, this);
system("./centroides");
}
void MyFrame::Calibracion(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("La camara se dura calibrandose alrededor de minuto y medio\nRealice esta operacion
cuando ejecuta por primera vez\n el programa luego de inicializado el sistema operativo"),
_T("Calibracion de la camara"), wxOK | wxICON_INFORMATION, this);
system("./mvc2");
}
/*************************************************************************
Esta funcion es la principal del programa, en ella se ordena empezar a tomar las fotos para
las posiciones, para tomar las fotos llama al programa mvc creado en el lenguaje C, el cual
toma las fotos y las almacena en la carpeta, para que luego de tomarlas sean procesadas,
los pasos seguidos se explican seguidamente
*************************************************************************/
void MyFrame::Posiciones (wxCommandEvent &)
{
C_matriz objeto,deteccion,objeto1,deteccion1,centroides(240,320),fondo1,fondo,fondocuadricula;
int numobjetos=1;
int n=0;
unsigned int contador1=0;
unsigned int centroide_x,centroide_y;
unsigned int *array_x,*array_y;
float limite=0.15;
char archivo[255];
char archivo1[255];
int numeroposiciones=0;
int limite1=3;
float tiempo=0;
fotos_minuto=110;
tiempo_foto=0.545454;
//Esta llamada a este puntero se hace para escribir el mensaje en el cuadro de texto
wxMessageBox(_T("Si se esta ejecutando el programa por primera vez luego de haber iniciado el sistema
operativo, utilice la opcion Calibrar la camara"),
_T("ADVERTENCIA"), wxOK | wxICON_INFORMATION, this);
*m_log << _T("Se va a iniciar a obtener las posiciones del objeto\n");
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
81
//Se crea el archivo Posiciones.txt
ofstream out("Posiciones.txt");
//se toma la foto llamando al programa mvc1 que toma 25 fotos
system("./mvc1");
//a la matriz fondo se le asigna la matriz que devuelve la
//funcion fondo y a esta se le aplica el filtro y se almacena
//en fondo1 para luego mandarla a fondocuadricula y imprimirle
//las rayas que dividen el fondo en zonas
fondo=iluminancia("fondo1.jpg");
fondo1=filtro1(fondo);
fondocuadricula=cuadricula(fondo1);
imprimir("fondo.jpg","fondo1.jpg",fondocuadricula);
*m_log << _T("Se tomo la fotografia del fondo, para verificarla abra el menu Acciones\n");
//Aqui se crea la ventana que recibe el numero de minutos que se quiere obtener posiciones
numeroposiciones = wxGetNumberFromUser(_T("Por cuantos minutos desea tomar posiciones:"),
_T("Minutos a ejecutar:"),
_T("Posiciones a determinar"),
numeroposiciones,
0, 10,
this);
//Dura 0.5454s por foto, por lo que en un minuto toma 110 fotos y esto se multiplica
//por el numero de minutos para obtener el total de fotos tomadas
numeroposiciones=(numeroposiciones*fotos_minuto);
cout<<"Se escogio correr el programa por: "<<numeroposiciones<<" minutos"<<endl;
array_x=new unsigned int [numeroposiciones];
array_y=new unsigned int [numeroposiciones];
*m_log << _T("Se van a iniciar a obtener las posiciones del objeto, no mueva la camara\n");
wxMessageBox(_T("Escoja la resolucion que quiere para la foto\nEntre mayor sea el valor, menor cantidad de
puntos del objeto se obtendran\nSi la foto salio con ruido aumente el valor para mejorarla\nSe recomienda 3 o 4, Observe
los resultados"),
_T("Valor limite estipulado como diferencia"), wxOK | wxICON_INFORMATION, this);
limite1 = wxGetNumberFromUser(_T("Escoja el valor de resolucion de la foto del objeto"),
_T("Escoja el valor de 0-10:"),
_T("Posiciones a determinar"),
limite1,
0, 10,
this);
switch(limite1){
case 0:
limite=0.13;
break;
case 1:
limite=0.14;
break;
case 2:
limite=0.145;
break;
case 3:
limite=0.15;
break;
case 4:
limite=0.155;
break;
Agosto del 2004
IE-0502
82
Determinación de la posición de un objeto utilizando una cámara Web
case 5:
limite=0.16;
break;
case 6:
limite=0.165;
break;
case 7:
limite=0.17;
break;
case 8:
limite=0.175;
break;
case 9:
limite=0.18;
break;
}
cout<<limite<<endl;
//Se crea un mensaje de advertencia, para que el usuario se devuelva a la consola donde
//corrio el programa y repita los minutos y observe los tiempos en que toma cada foto
wxMessageBox(_T("Repita el numero de posiciones que desea tomar\nCuando el programa lo pide en la
consola\nObserve que en ella se imprimen los tiempos en los que se tomo cada posicion"),
_T("ADVERTENCIA"), wxOK | wxICON_INFORMATION, this);
Time start;
system("./mvc");
Time end;
//Se crea un mensaje para que el usuario minimice la consola y vuelva al programa
//para que este procese las fotos tomadas
wxMessageBox(_T("Minimice esta ventana de consola y vuelva al programa de deteccion de\nobjetos y espere
mientras se procesan la fotos tomadas"),
_T("ADVERTENCIA"), wxOK | wxICON_INFORMATION, this);
//De esta forma se imprime en el archivo Posiciones.txt
out<<"\nInicio Ejecucion Programa de Captura: "<<start.ascii()<<"\nFin Ejecucion Programa de Captura:
"<<end.ascii()<<endl;
out<<"La ejecucion del programa duro: "<<end.delta(&start)<<" segundos"<<endl;
out<<"LOS TIEMPOS EN QUE SE TOMO CADA POSICION SE ENCUENTRAN EN LA
CONSOLA\n"<<endl;
out<<"Centroides\n(x,y)
Zona
Tiempo(s)"<<endl;
//Se entra a un ciclo que va a procesar todas las fotos tomadas por el programa mvc
while(numobjetos<=numeroposiciones){
n++;
if(n>=50){ //Se desprecian las primeras 10 fotos para asegurar que la camara enfoque
cout<<"entre al if"<<n<<"/"<<numobjetos<<endl;
if(numobjetos==1){
tiempo=0;
}
else{
tiempo=tiempo+tiempo_foto;
//Se calcula el tiempo en que se tomo cada foto, segun
}
//el tiempo promedio que dura por cada foto
//Se crea un string objeto#(numero del objeto)
sprintf(archivo,"objeto%i.jpg",n);
//se manda la foto a la funcion iluminancia para que la convierta
Agosto del 2004
IE-0502
83
Determinación de la posición de un objeto utilizando una cámara Web
//a escala de grises y la pase por el filtro
objeto=iluminancia(archivo);
objeto1=filtro1(objeto);
imprimir("fondo.jpg","objeto.jpg",objeto1);
sprintf(archivo1,"Posicion%i",numobjetos);
//Se mandan ambas matrices, una con el fondo
deteccion=deteccion_objeto(fondo1,objeto1,limite);
imprimir("fondo.jpg",archivo1,deteccion);
//y otra con la foto recien abierta, para luego
//imprimir el resultado de la funcion deteccion_objeto
centroide_x=centroides_x(deteccion);
array_x[contador1]=centroide_x;
//guarda en el arreglo el centroide en x del objeto
centroide_y=centroides_y(deteccion);
array_y[contador1]=centroide_y;
//guarda en el arreglo el centroide en y del objeto
//Imprime el tiempo en que proceso la imagen y el numero de posicion que es
wxLogStatus(this, _T("Posicion #%ld"), numobjetos);
out<<"Posicion #"<<numobjetos<<endl;
//se indica la posicion en Posiciones.txt
/***********************************************************************
SE VAN A DETERMINAR LAS ZONAS EN LAS QUE SE ENCUENTRA EL OBJETO
CON UNA SERIE DE IF QUE DIVIDEN LA IMAGEN DEVUELTA POR deteccion_objeto
***********************************************************************/
if((0<=centroide_x)&&(centroide_x<64)&&(0<=centroide_y)&&(centroide_y<48)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t0\t \t"<<tiempo<<endl;
}
if((64<=centroide_x)&&(centroide_x<128)&&(0<=centroide_y)&&(centroide_y<48)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t1\t \t"<<tiempo<<endl;
}
if((128<=centroide_x)&&(centroide_x<192)&&(0<=centroide_y)&&(centroide_y<48)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t2\t \t"<<tiempo<<endl;
}
if((192<=centroide_x)&&(centroide_x<256)&&(0<=centroide_y)&&(centroide_y<48)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t3\t \t"<<tiempo<<endl;
}
if((256<=centroide_x)&&(centroide_x<=320)&&(0<=centroide_y)&&(centroide_y<48)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t4\t \t"<<tiempo<<endl;
}
if((0<=centroide_x)&&(centroide_x<64)&&(48<=centroide_y)&&(centroide_y<96)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t5\t \t"<<tiempo<<endl;
}
if((64<=centroide_x)&&(centroide_x<128)&&(48<=centroide_y)&&(centroide_y<96)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t6\t \t"<<tiempo<<endl;
}
if((128<=centroide_x)&&(centroide_x<192)&&(48<=centroide_y)&&(centroide_y<96)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t7\t \t"<<tiempo<<endl;
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
84
}
if((192<=centroide_x)&&(centroide_x<256)&&(48<=centroide_y)&&(centroide_y<96)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t8\t \t"<<tiempo<<endl;
}
if((256<=centroide_x)&&(centroide_x<=320)&&(48<=centroide_y)&&(centroide_y<96)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t10\t\t"<<tiempo<<endl;
}
if((0<=centroide_x)&&(centroide_x<64)&&(96<=centroide_y)&&(centroide_y<144)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t11\t\t"<<tiempo<<endl;
}
if((64<=centroide_x)&&(centroide_x<128)&&(96<=centroide_y)&&(centroide_y<144)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t12\t\t"<<tiempo<<endl;
}
if((128<=centroide_x)&&(centroide_x<192)&&(96<=centroide_y)&&(centroide_y<144)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t13\t\t"<<tiempo<<endl;
}
if((192<=centroide_x)&&(centroide_x<256)&&(96<=centroide_y)&&(centroide_y<144)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t14\t\t"<<tiempo<<endl;
}
if((256<=centroide_x)&&(centroide_x<=320)&&(96<=centroide_y)&&(centroide_y<144)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t15\t\t"<<tiempo<<endl;
}
if((0<=centroide_x)&&(centroide_x<64)&&(144<=centroide_y)&&(centroide_y<192)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t16\t\t"<<tiempo<<endl;
}
if((64<=centroide_x)&&(centroide_x<128)&&(144<=centroide_y)&&(centroide_y<192)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t17\t\t"<<tiempo<<endl;
}
if((128<=centroide_x)&&(centroide_x<192)&&(144<=centroide_y)&&(centroide_y<192)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t18\t\t"<<tiempo<<endl;
}
if((192<=centroide_x)&&(centroide_x<256)&&(144<=centroide_y)&&(centroide_y<192)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t19\t\t"<<tiempo<<endl;
}
if((256<=centroide_x)&&(centroide_x<=320)&&(144<=centroide_y)&&(centroide_y<192)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t20\t\t"<<tiempo<<endl;
}
if((0<=centroide_x)&&(centroide_x<64)&&(192<=centroide_y)&&(centroide_y<=240)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t21\t\t"<<tiempo<<endl;
}
if((64<=centroide_x)&&(centroide_x<128)&&(192<=centroide_y)&&(centroide_y<=240)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t22\t\t"<<tiempo<<endl;
Agosto del 2004
IE-0502
85
Determinación de la posición de un objeto utilizando una cámara Web
}
if((128<=centroide_x)&&(centroide_x<192)&&(192<=centroide_y)&&(centroide_y<=240)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t23\t\t"<<tiempo<<endl;
}
if((192<=centroide_x)&&(centroide_x<256)&&(192<=centroide_y)&&(centroide_y<=240)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t24\t\t"<<tiempo<<endl;
}
if((192<=centroide_x)&&(centroide_x<256)&&(192<=centroide_y)&&(centroide_y<=240)){
out<<"("<<centroide_x<<","<<centroide_y<<")\t"<<"\t25\t\t"<<tiempo<<endl;
}
/********************************************************************/
numobjetos++;
//se aumentan los contadores para comparar cuantas fotos
contador1++;
//se han procesado hasta este momento
}
}
*m_log << _T("Se va a imprimir la fotografia con las posiciones del objeto\n");
/***********************************************************************
Seguidamente lo que se hace es crear la imagen Centroides.jpg, imprimiendo un
punto en la posicion donde esta el centroide del objeto, esto recorriendo los
arreglos creados con todos los centroides encontrados y recorriendo todas las
posiciones de la imagen de 320x240
************************************************************************/
for (unsigned int i=1; i<=240;i++){
for (unsigned int j=1;j<=320;j++){
if((j==320)||(j==256)||(j==192)||(j==128)||(j==64)||(j==1)){
centroides.set(i,j,0);
}
else{
if((i==240)||(i==192)||(i==144)||(i==96)||(i==48)||(i==1)){
centroides.set(i,j,0);
}
else{
centroides.set(i,j,1);
}
}
for(unsigned int k=0;k<=contador1;k++){
if((array_x[k]==j)&&(array_y[k]==i)){
centroides.set(i,j,0);
}
}
}
}
imprimir("fondo.jpg","centroides.jpg",centroides); //aqui se imprime Centroides.jpg
*m_log << _T("Se creo la fotografia con las posiciones, para abrirla vaya al menu Acciones\n");
*m_log << _T("Observe los resultados en el archivo Posiciones.txt localizado en la carpeta del
programa\n");
}
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
86
Archivo makefile
# Generated automatically from Makefile.in by configure.
# Purpose: makefile for calendar example (UNIX).
# Created: 2000-01-03
top_srcdir = ../..
top_builddir = ../..
program_dir = demos/proyecto
PROGRAM=interfaz2
OBJECTS = interfaz2.o
DEPFILES=interfaz2.d
include /root/wxwindows/wxGTK-2.4.2/demos/proyecto/makeprog.env
-include $(DEPFILES)
Archivo makelib.env
# Template makefile for building wxWindows companion libraries.
#
# Author: Ron Lee <[email protected]>
# Created: 19/3/2000
# $Id: makelib.env.in,v 1.12.2.1 2002/11/03 23:58:38 VS Exp $
#
# To use, set the following vars before including it:
#
# top_srcdir
# top_builddir
# libsrc_dir
#
# TARGET_LIBNAME
# LIBVERSION_CURRENT
# LIBVERSION_REVISION
# LIBVERSION_AGE
# HEADER_PATH
# HEADER_SUBDIR
#
# HEADERS
# OBJECTS
#
# either a shared or static lib will be built according to the
# option given to configure.
#
prefix = /usr/local
exec_prefix = ${prefix}
includedir = ${prefix}/include
libdir = ${exec_prefix}/lib
INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
Agosto del 2004
IE-0502
87
Determinación de la posición de un objeto utilizando una cámara Web
TARGETLIB_STATIC = $(TARGET_LIBNAME).a
TARGETLIB_SHARED =
$(TARGET_LIBNAME).so.$(LIBVERSION_CURRENT).$(LIBVERSION_REVISION).$(LIBVERSION_AGE)
TARGETLIB_LINK1 = $(TARGET_LIBNAME).so.$(LIBVERSION_CURRENT)
TARGETLIB_LINK2 = $(TARGET_LIBNAME).so
TARGETLIB_SONAME =
LDFLAGS_VER SIONING = -Wl,--version-script,$(top_builddir)/version-script
# NB: see remark in Makefile.in as to why we don't use %.foo: %.bar rules
.SUFFIXES: .o .c .cpp .cxx
.c.o:
$(CC) -c $(CFLAGS) $(PICFLAGS) -o $@ $<
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(PICFLAGS) -o $@ $<
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(PICFLAGS) -o $@ $<
# the comment at the end of the next line is needed because otherwise autoconf
# would remove this line completely - it contains a built-in hack to remove
# any VPATH assignment not containing ':'
VPATH = :$(top_srcdir)/$(libsrc_dir) # ':' for autoconf
include $(top_builddir)/src/make.env
all: libtype_so
libtype_so: $(top_builddir)/lib/$(TARGETLIB_SHARED)
libtype_a: $(top_builddir)/lib/$(TARGETLIB_STATIC)
$(top_builddir)/lib/$(TARGETLIB_SHARED): $(OBJECTS)
@$(INSTALL) -d $(top_builddir)/lib
$(SHARED_LD) $@ $(TARGETLIB_SONAME) $(OBJECTS) $(LDFLAGS_VERSIONING)
cd $(top_builddir)/lib \
&& $(RM) $(TARGETLIB_LINK1) $(TARGETLIB_LINK2) \
&& $(LN_S) $(TARGETLIB_SHARED) $(TARGETLIB_LINK1) \
&& $(LN_S) $(TARGETLIB_SHARED) $(TARGETLIB_LINK2)
$(top_builddir)/lib/$(TARGETLIB_STATIC): $(OBJECTS)
@$(INSTALL) -d $(top_builddir)/lib
@$(RM) $@
$(AR) $(AROPTIONS) $@ $(OBJECTS)
$(RANLIB) $@
install: install_so install_headers
install_so:
$(INSTALL_PROGRAM) $(top_builddir)/lib/$(TARGETLIB_SHARED) $(libdir)/$(TARGETLIB_SHARED)
@$(RM) $(libdir)/$(TARGETLIB_LINK1) $(libdir)/$(TARGETLIB_LINK2)
cd $(libdir) \
&& $(LN_S) $(TARGETLIB_SHARED) $(TARGETLIB_LINK1) \
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
88
&& $(LN_S) $(TARGETLIB_SHARED) $(TARGETLIB_LINK2)
install_a:
$(INSTALL_PROGRAM) $(top_builddir)/lib/$(TARGETLIB_STATIC) $(libdir)/$(TARGETLIB_STATIC)
install_headers:
$(INSTALL) -d $(includedir)/wx/$(HEADER_SUBDIR)
@for h in $(HEADERS); do \
$(INSTALL_DATA) $(HEADER_PATH)/$(HEADER_SUBDIR)/$$h
$(includedir)/wx/$(HEADER_SUBDIR)/$$h; \
echo "installing $(includedir)/wx/$(HEADER_SUBDIR)/$$h"; \
done
uninstall:
$(RM) $(libdir)/$(TARGETLIB_STATIC)
$(RM) $(libdir)/$(TARGETLIB_SHARED)
$(RM) $(libdir)/$(TARGETLIB_LINK1)
$(RM) $(libdir)/$(TARGETLIB_LINK2)
@echo "removing headers"
@for h in $(HEADERS); do \
$(RM) $(includedir)/wx/$(HEADER_SUBDIR)/$$h; \
done
@if test -d $(includedir)/wx/$(HEADER_SUBDIR); then \
rmdir $(includedir)/wx/$(HEADER_SUBDIR); \
fi
@-rmdir $(includedir)/wx
clean:
$(RM) $(OBJECTS) $(top_builddir)/lib/$(TARGETLIB_SHARED) \
$(top_builddir)/lib/$(TARGETLIB_LINK1) \
$(top_builddir)/lib/$(TARGETLIB_LINK2) \
$(top_builddir)/lib/$(TARGETLIB_STATIC) core
.PHONY: all libtype_so libtype_a install install_so install_a install_headers uninstall clean
Archivo makeprog.env
# Make environment for making samples on Unix
# The binary program extension, if any, including dots (e.g. '.exe')
PROGRAM_EXT =
BIN_PROGRAM = $(PROGRAM)$(PROGRAM_EXT)
RES_PROGRAM_OBJ =
BUNDLE = $(BIN_PROGRAM).app/Contents
# NB: see remark in Makefile.in as to why we don't use %.foo: %.bar rules
.SUFFIXES: .o .c .cpp .cxx .rc _resources.o
.c.o:
$(CC) -c $(CFLAGS) $(APPEXTRADEFS) -o $@ $<
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(APPEXTRADEFS) -o $@ $<
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(APPEXTRADEFS) -o $@ $<
Agosto del 2004
IE-0502
89
Determinación de la posición de un objeto utilizando una cámara Web
.rc_resources.o:
$(RESCOMP) -i $< -o $@ $(RESFLAGS)
# the comment at the end of the next line is needed because otherwise autoconf
# would remove this line completely - it contains a built-in hack to remove
# any VPATH assignment not containing ':'
VPATH = :$(top_srcdir)/$(program_dir) # ':' for autoconf
# Set defaults from configure
include /root/wxwindows/wxGTK-2.4.2/demos/proyecto/make.env
#include $(top_builddir)/src/make.env
all: $(BIN_PROGRAM) install_dirs install_data
$(BIN_PROGRAM):
$(OBJECTS) $(top_builddir)/lib/libwx_gtk2u-2.4.so.0.1.1 $(RES_PROGRAM_OBJ)
$(CXX) $(LDFLAGS_EXE) -o $@ $(OBJECTS) $(LDLIBS) $(LIBRARIES) $(RES_PROGRAM_OBJ)
#
install_dirs:
@list='$(DATADIRS)'; for p in $$list; do \
mkdir -p $(top_builddir)/$(program_dir)/$$p; \
done
install_data:
@list='$(DATAFILES)'; for p in $$list; do \
if test ! -s $(top_builddir)/$(program_dir)/$$p; then \
cp -pRf $(top_srcdir)/$(program_dir)/$$p $(top_builddir)/$(program_dir)/$$p; \
fi; \
done
clean:
rm -f $(OBJECTS) $(DEPFILES) $(BIN_PROGRAM) $(RES_PROGRAM_OBJ) core
#
# Targets to build a Mac OS X application bundle
#
bundle: $(BUNDLE)/MacOS/$(PROGRAM) $(BUNDLE)/Info.plist $(BUNDLE)/PkgInfo
$(BUNDLE)/Resources/$(PROGRAM).rsrc $(BUNDLE)/Resources/wxmac.icns
$(BUNDLE)/Info.plist: $(top_srcdir)/src/$(TOOLKITDIR)/Info.plist.in $(top_builddir)/lib/libwx_gtk2u-2.4.so.0.1.1
@$(INSTALL) -d `dirname $@`
sed -e "s/IDENTIFIER/`echo $(program_dir) | sed 's,/,.,g'`/" \
-e "s/EXECUTABLE/$(PROGRAM)/" \
-e
"s/VERSION/$(WX_MAJOR_VERSION_NUMBER).$(WX_MINOR_VERSION_NUMBER).$(WX_RELEASE_NUM
BER)/" $< > $@
$(BUNDLE)/PkgInfo:
@$(INSTALL) -d `dirname $@`
echo -n "APPL????" > $@
$(BUNDLE)/MacOS/$(PROGRAM): $(OBJECTS) $(top_builddir)/lib/libwx_gtk2u-2.4.so.0.1.1
@$(INSTALL) -d `dirname $@`
$(CXX) $(LDFLAGS_EXE) -o $@ $(OBJECTS) $(LDLIBS) $(LIBRARIES)
$(BUNDLE)/Resources/$(PROGRAM).rsrc: $(top_builddir)/lib/
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
90
@$(INSTALL) -d `dirname $@`
cp $< $@
$(BUNDLE)/Resources/wxmac.icns: $(top_srcdir)/src/$(TOOLKITDIR)/wxmac.icns
@$(INSTALL) -d `dirname $@`
cp $< $@
Archivo make.env
# File: make.env
# Author: Julian Smart, Robert Roebling, Vadim Zeitlin, Ron Lee
# Created: 1993
# Updated: 2001
# Copyright:(c) 1993, AIAI, University of Edinburgh,
# Copyright:(c) 1999, Vadim Zeitlin
# Copyright:(c) 1999, Robert Roebling
# Copyright:(c) 2001, Ron Lee
#
####################### GENERAL SETTINGS ############################
# see comment near LDFLAGS at the end of file
EXTRALIBS = -pthread -Wl,--version-script,$(top_builddir)/version-script -Wl,--export-dynamic -pthread -lgtk-x11-2.0
-lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangoxft -1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl lgthread-2.0 -lglib-2.0 -lpng -ljpeg -ltiff -lz -Wl,--export-dynamic -lpangoft2-1.0 -lpango-1.0 -lgobject -2.0 -lgmodule-2.0 ldl -lglib-2.0 -lm -lMagick++
OPENGLLIBS =
LDFLAGS_GL =
LDLIBS = ${APPEXTRALIBS} ${top_builddir}/lib/libwx_gtk2u-2.4.so.0.1.1 ${EXTRALIBS}
TOOLKIT = GTK
TOOLKITDIR = gtk
WXLIB = libwx_gtk2u-2.4.a
WXSHLIB = libwx_gtk2u-2.4.so.0.1.1
WXLIBBASE = wx_gtk2u
########################### VERSION #################################
WX_MAJOR_VERSION_NUMBER = 2
WX_MINOR_VERSION_NUMBER = 4
WX_RELEASE_NUMBER = 2
########################### Programs #################################
CXX
CC
= c++
= gcc
# Compiler for lex/yacc .c programs
CCLEX
= gcc
LEX
= lex
YACC
= yacc
AR
= ar
AS
=
NM
=
LN_S
= ln -s
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
91
STRIP
= strip
AROPTIONS = rcu
RANLIB
= ranlib
LD
=
MAKEINFO =
RM
= rm -f
SHARED_LD = c++ -shared -o
RESFLAGS =
RESCOMP =
DEREZ
DLLTOOL
=
=
INSTALL
= /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = /usr/bin/install -c
########################### Flags #################################
DEBUG = -g
CPPFLAGS = ${APPEXTRACPPFLAGS} -I${top_builddir}/lib/wx/include/gtk2u-2.4 -I${top_srcdir}/include -pthread
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 I/usr/X11R6/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES
$(EXTRADEFS) $(APPEXTRADEFS) -D__WXGTK__ -DGTK_NO_CHECK_CASTS
CFLAGS = ${APPEXTRACFLAGS} ${CPPFLAGS} -O2 -MMD -pthread -Wall -c $(DEBUG) --pedantic
CXXFLAGS = ${APPEXTRACXXFLAGS} ${CPPFLAGS} -O2 -MMD -I/usr/include/pango -1.0 I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread –Wall
PICFLAGS = -fPIC
# taking into account how SHARED_LD is defined, appending LDFLAGS to it
# doesn't work, so we put them in the end of the linker command line in
# EXTRALIBS instead (see above)
# LDFLAGS = -pthread
# specific linker flags for when building executables since there
# Mac OS X requires specific linker flags for executables linked
# against dynamic shared libraries
LDFLAGS_EXE =
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
92
Programas para abrir las fotografías resultantes
Archivo centroides.h
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "wx/file.h"
#include "wx/mstream.h"
#include "wx/wfstream.h"
#include "wx/quantize.h"
class MyFrame;
class interfaz;
class MyCanvas: public wxScrolledWindow //clase para crear la foto como un Bitmap
{
public:
MyCanvas() {}
MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
~MyCanvas();
void OnPaint( wxPaintEvent &event );
wxBitmap *my_posiciones_jpeg; //declaracion del puntero tipo wxBitmap para portar la imagen
private: //declaraciones de la tabla de eventos y de la clase dinamica
DECLARE_DYNAMIC_CLASS(MyCanvas)
DECLARE_EVENT_TABLE()
};
class MyFrame: public wxFrame
{
public:
MyFrame();
void OnAbout( wxCommandEvent &event ); //funciones de la barra de menu Archivo
void OnQuit( wxCommandEvent &event );
MyCanvas
*m_canvas; //puntero tipo MyCanvas para crear la imagen
private: //declaraciones de la clase dinamica y la tabla de eventos de la clase
DECLARE_DYNAMIC_CLASS(MyFrame)
DECLARE_EVENT_TABLE()
};
class interfaz : public wxApp //funcion inicial para crear las aplicaciones de la ventana
{
public:
virtual bool OnInit();
Agosto del 2004
IE-0502
93
Determinación de la posición de un objeto utilizando una cámara Web
protected:
private:
};
DECLARE_APP(interfaz)
Archivo centroides.cpp
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxp rec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/frame.h"
#include "wx/panel.h"
#include "wx/stattext.h"
#include "wx/menu.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#endif
#include "wx/calctrl.h"
#include "centroides.h"
IIMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) //Tabla de eventos de la clase MyCanvas
EVT_PAINT(MyCanvas::OnPaint)
END_EVENT_TABLE()
MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, //Esta es la instruccion para implementar la clase
const wxPoint &pos, const wxSize &size )
//dinamica para observar la foto
: wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER ) //constructor de la clase MyCanvas
{
my_posiciones_jpeg = (wxBitmap*) NULL;
SetBackgroundColour(* wxWHITE);
//se crea el fondo de la ventana blanco
wxBitmap bitmap( 100, 100 );
//tamano de la foto
wxMemoryDC dc;
dc.SelectObject( bitmap );
dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
dc.SetPen( *wxBLACK_PEN );
dc.DrawRectangle( 0, 0, 100, 100 );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( 20, 20, 60, 60 );
dc.SelectObject( wxNullBitmap );
wxString dir;
wxImage image = bitmap.ConvertToImage();
//se convierte el bitmap a imagen
Agosto del 2004
IE-0502
94
Determinación de la posición de un objeto utilizando una cámara Web
#if wxUSE_LIBJPEG
image.Destroy();
if ( !image.LoadFile( dir + _T("/root/wxwindows/wxGTK-2.4.2/demos/proyecto_nuevo/centroides.jpg")) ) //Aqui va la
direccion de la foto
wxLogError(wxT("No se puede abrir la imagen")); //ventana de error en caso de no poder abrir la foto
else
my_posiciones_jpeg = new wxBitmap( image ); //agrega la foto a un Bitmap
#endif // wxUSE_LIBJPEG
}
MyCanvas::~MyCanvas()
{
delete my_posiciones_jpeg; //destructor borra la imagen de la memoria
}
void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) //funcion para abrir la imagen
{
wxPaintDC dc( this );
PrepareDC( dc );
dc.DrawText( _T("Posiciones del Objeto"), 30, 15 ); //titulo de la foto
if (my_posiciones_jpeg && my_posiciones_jpeg->Ok())
dc.DrawBitmap( *my_posiciones_jpeg, 30, 30 ); //se pone la imagen en la ventana y se le da la posicion 30,30
}
const int ID_QUIT = 108; //declaraciones de la funciones de la barra de menu Archivo
const int ID_ABOUT = 109;
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
BEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
EVT_MENU (ID_QUIT, MyFrame::OnQuit)
END_EVENT_TABLE()
//tabla de MyFrame
MyFrame::MyFrame()
//constructor de la clase MyFrame para crear la ventana
: wxFrame( (wxFrame *)NULL, -1, _T("Fotografia de las Posiciones del Objeto"),
wxPoint(20,20), wxSize(470,360) ) //tamano de la ventana
{
wxMenu *file_menu = new wxMenu();
//se crea la barra de menu
file_menu->Append( ID_ABOUT, _T("&Ayuda..."));
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, _T("&Salir"));
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, _T("&Archivo"));
SetMenuBar( menu_bar );
//se agrega la barra de menu a la ventana
CreateStatusBar(2);
int widths[] = { -1, 100 };
SetStatusWidths( 2, widths );
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
95
m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); //se le agrega a la ventana la foto
m_canvas->SetScrollbars( 10, 10, 10, 15 );//tamano de la ventana
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE); //verdadera para salirse del programa
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Esta es la fotografia del fondo\nPara cerrarla, oprima Archivo y luego Salir\nVolvera a la ventana
de ejecucion del programa de deteccion de objeto"),
_T("AYUDA"), wxOK | wxICON_INFORMATION, this); //creditos del programa
}
IMPLEMENT_APP(interfaz)
bool interfaz::OnInit() //funcion para la iniciacion de la ventana
{
// Se crea las aplicaciones principales de la ventana
#if wxUSE_LIBJPEG
wxImage::AddHandler( new wxJPEGHandler );
#endif
wxFrame *frame = new MyFrame();
frame->Show( TRUE );
return true;
}
Archivo fondo.h
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "wx/file.h"
#include "wx/mstream.h"
#include "wx/wfstream.h"
#include "wx/quantize.h"
class MyFrame;
class interfaz;
class MyCanvas: public wxScrolledWindow //clase para crear la foto como un Bitmap
{
public:
MyCanvas() {}
MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
~MyCanvas();
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
96
void OnPaint( wxPaintEvent &event );
wxBitmap *my_fondo_jpeg; //declaracion del puntero tipo wxBitmap para portar la imagen
private: //declaraciones de la tabla de eventos y de la clase dinamica
DECLARE_DYNAMIC_CLASS(MyCanvas)
DECLARE_EVENT_TABLE()
};
class MyFrame: public wxFrame
{
public:
MyFrame();
void OnAbout( wxCommandEvent &event ); //funciones de la barra de menu Archivo
void OnQuit( wxCommandEvent &event );
MyCanvas
*m_canvas; //puntero tipo MyCanvas para crear la imagen
private: //declaraciones de la clase dinamica y la tabla de eventos de la clase
DECLARE_DYNAMIC_CLASS(MyFrame)
DECLARE_EVENT_TABLE()
};
class interfaz : public wxApp //funcion inicial para crear las aplicaciones de la ventana
{
public:
virtual bool OnInit();
protected:
private:
};
DECLARE_APP(interfaz)
Archivo fondo.cpp
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/frame.h"
#include "wx/panel.h"
#include "wx/stattext.h"
#include "wx/menu.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#endif
#include "wx/calctrl.h"
#include "fondo.h"
Agosto del 2004
IE-0502
97
Determinación de la posición de un objeto utilizando una cámara Web
IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow) //Esta es la instruccion para implementar la clase
//dinamica para observar la foto
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
//Tabla de eventos de la clase MyCanvas
EVT_PAINT(MyCanvas::OnPaint)
END_EVENT_TABLE()
MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, //constructor de la clase MyCanvas
const wxPoint &pos, const wxSize &size )
: wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER )
{
my_fondo_jpeg = (wxBitmap*) NULL;
SetBackgroundColour(* wxWHITE);
wxBitmap bitmap( 100, 100 );
//se crea el fondo de la ventana blanco
//tamano de la foto
wxMemoryDC dc;
dc.SelectObject( bitmap );
dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
dc.SetPen( *wxBLACK_PEN );
dc.DrawRectangle( 0, 0, 100, 100 );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( 20, 20, 60, 60 );
dc.SelectObject( wxNullBitmap );
wxString dir;
wxImage image = bitmap.ConvertToImage(); //se convierte el bitmap a imagen
#if wxUSE_LIBJPEG
image.Destroy();
if ( !image.LoadFile( dir + _T("/root/wxwindows/wxGTK-2.4.2/demos/proyecto_nuevo/fondo1.jpg")) ) //Aqui va la
direccion de la foto
wxLogError(wxT("No se puede abrir la imagen")); //ventana de error en caso de no poder abrir la foto
else
my_fondo_jpeg = new wxBitmap( image ); //agrega la foto a un Bitmap
#endif // wxUSE_LIBJPEG
}
MyCanvas::~MyCanvas()
{
delete my_fondo_jpeg; //destructor borra la imagen de la memoria
}
void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) //funcion para abrir la imagen
{
wxPaintDC dc( this );
PrepareDC( dc );
dc.DrawText( _T("Fondo"), 30, 15 );
if (my_fondo_jpeg && my_fondo_jpeg->Ok())
dc.DrawBitmap( *my_fondo_jpeg, 30, 30 ); //se pone la imagen en la ventana y se le da la posicion 30,30
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
98
}
const int ID_QUIT = 108; //declaraciones de la funciones de la barra de menu Archivo
const int ID_ABOUT = 109;
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
BEGIN_EVENT_TABLE(MyFrame,wxFrame) //tabla de MyFrame
EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
EVT_MENU (ID_QUIT, MyFrame::OnQuit)
END_EVENT_TABLE()
MyFrame::MyFrame() //constructor de la clase MyFrame para crear la ventana
: wxFrame( (wxFrame *)NULL, -1, _T("Fotografia del Fondo"), //titulo de la ventana
wxPoint(20,20), wxSize(470,360) ) //tamano de la ventana
{
wxMenu *file_menu = new wxMenu(); //se crea la barra de menu
file_menu->Append( ID_ABOUT, _T("&Ayuda..."));
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, _T("&Salir"));
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, _T("&Archivo"));
SetMenuBar( menu_bar ); //se agrega la barra de menu a la ventana
CreateStatusBar(2);
int widths[] = { -1, 100 };
SetStatusWidths( 2, widths );
m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); //se le agrega a la ventana la foto
m_canvas->SetScrollbars( 10, 10, 10, 15 );//tamano de la ventana
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE); //verdadera para salirse del programa
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Esta es la fotografia del fondo\nPara cerrarla, oprima Archivo y luego Salir\nVolvera a la ventana
de ejecucion del programa de deteccion de objeto"),
_T("AYUDA"), wxOK | wxICON_INFORMATION, this); //creditos del programa
}
IMPLEMENT_APP(interfaz)
bool interfaz::OnInit() //funcion para la iniciacion de la ventana
{
// Se crea las aplicaciones principales de la ventana
#if wxUSE_LIBJPEG
wxImage::AddHandler( new wxJPEGHandler );
#endif
wxFrame *frame = new MyFrame();
frame->Show( TRUE );
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
99
return true;
}
Archivo objeto.h
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "wx/file.h"
#include "wx/mstream.h"
#include "wx/wfstream.h"
#include "wx/quantize.h"
class MyFrame;
class interfaz;
class MyCanvas: public wxScrolledWindow //clase para crear la foto como un Bitmap
{
public:
MyCanvas() {}
MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
~MyCanvas();
void OnPaint( wxPaintEvent &event );
wxBitmap *my_objeto_jpeg;
//declaracion del puntero tipo wxBitmap para portar la imagen
private:
//declaraciones de la tabla de eventos y de la clase dinamica
DECLARE_DYNAMIC_CLASS(MyCanvas)
DECLARE_EVENT_TABLE()
};
class MyFrame: public wxFrame
{
public:
MyFrame();
void OnAbout( wxCommandEvent &event );
void OnQuit( wxCommandEvent &event );
MyCanvas
*m_canvas;
//funciones de la barra de menu Archivo
//puntero tipo MyCanvas para crear la imagen
private: //declaraciones de la clase dinamica y la tabla de eventos de la clase
DECLARE_DYNAMIC_CLASS(MyFrame)
DECLARE_EVENT_TABLE()
};
class interfaz : public wxApp //funcion inicial para crear las aplicaciones de la ventana
Agosto del 2004
IE-0502
100
Determinación de la posición de un objeto utilizando una cámara Web
{
public:
virtual bool OnInit();
protected:
private:
};
DECLARE_APP(interfaz)
Archivo objeto.cpp
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/frame.h"
#include "wx/panel.h"
#include "wx/stattext.h"
#include "wx/menu.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#endif
#include "wx/calctrl.h"
#include "objeto.h"
IIMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) //Tabla de eventos de la clase MyCanvas
EVT_PAINT(MyCanvas::OnPaint)
END_EVENT_TABLE()
MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, //Esta es la instruccion para implementar la clase
const wxPoint &pos, const wxSize &size )
//dinamica para observar la foto
: wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER ) //constructor de la clase MyCanvas
{
{
my_objeto_jpeg = (wxBitmap*) NULL;
SetBackgroundColour(* wxWHITE);
wxBitmap bitmap( 100, 100 );
//se crea el fondo de la ventana blanco
//tamano de la foto
wxMemoryDC dc;
dc.SelectObject( bitmap );
dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
dc.SetPen( *wxBLACK_PEN );
dc.DrawRectangle( 0, 0, 100, 100 );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( 20, 20, 60, 60 );
dc.SelectObject( wxNullBitmap );
Agosto del 2004
IE-0502
101
Determinación de la posición de un objeto utilizando una cámara Web
wxString dir;
wxImage image = bitmap.ConvertToImage();
//se convierte el bitmap a imagen
#if wxUSE_LIBJPEG
image.Destroy();
if ( !image.LoadFile( dir + _T("/root/wxwindows/wxGTK-2.4.2/demos/proyecto_nuevo/objeto.jpg")) ) //Aqui va la
direccion de la foto
wxLogError(wxT("No se puede abrir la image n"));
else
my_objeto_jpeg = new wxBitmap( image ); //agrega la foto a un Bitmap
#endif // wxUSE_LIBJPEG
}
MyCanvas::~MyCanvas()
{
delete my_objeto_jpeg; //destructor borra la imagen de la memoria
}
void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) //funcion para abrir la imagen
{
wxPaintDC dc( this );
PrepareDC( dc );
dc.DrawText( _T("Objeto"), 30, 15 ); //titulo de la foto
if (my_objeto_jpeg && my_objeto_jpeg->Ok())
dc.DrawBitmap( *my_objeto_jpeg, 30, 30 ); //se pone la imagen en la ventana y se le da la posicion 30,30
}
const int ID_QUIT = 108; //declaraciones de la funciones de la barra de menu Archivo
const int ID_ABOUT = 109;
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
BEGIN_EVENT_TABLE(MyFrame,wxFrame) //tabla de MyFrame
EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
EVT_MENU (ID_QUIT, MyFrame::OnQuit)
END_EVENT_TABLE()
MyFrame::MyFrame() //constructor de la clase MyFrame para crear la ventana
: wxFrame( (wxFrame *)NULL, -1, _T("Fotografia del Objeto"),
wxPoint(20,20), wxSize(470,360) )
//tamano de la ventana
{
wxMenu *file_menu = new wxMenu(); //se crea la barra de menu
file_menu->Append( ID_ABOUT, _T("&Ayuda..."));
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, _T("&Salir"));
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, _T("&Archivo"));
SetMenuBar( menu_bar );
//se agrega la barra de menu a la ventana
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
102
CreateStatusBar(2);
int widths[] = { -1, 100 };
SetStatusWidths( 2, widths );
m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); //se le agrega a la ventana la foto
m_canvas->SetScrollbars( 10, 10, 10, 10 );//tamano de la ventana
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
//verdadera para salirse del programa
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Esta es la fotografia del objeto\nPara cerrarla, oprima Archivo y luego Salir\nVolvera a la ventana
de ejecucion del programa de deteccion de objeto"),
_T("AYUDA"), wxOK | wxICON_INFORMATION, this); //creditos del programa
}
IMPLEMENT_APP(interfaz)
bool interfaz::OnInit() //funcion para la iniciacion de la ventana
{
// Se crea las aplicaciones principales de la ventana
#if wxUSE_LIBJPEG
wxImage::AddHandler( new wxJPEGHandler );
#endif
wxFrame *frame = new MyFrame();
frame->Show( TRUE );
return true;
}
Archivo posición.h
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "wx/file.h"
#include "wx/mstream.h"
#include "wx/wfstream.h"
#include "wx/quantize.h"
class MyFrame;
class interfaz;
class MyCanvas: public wxScrolledWindow
//clase para crear la foto como un Bitmap
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
103
{
public:
MyCanvas() {}
MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
~MyCanvas();
void OnPaint( wxPaintEvent &event );
wxBitmap *my_posicion_jpeg; //declaracion del puntero tipo wxBitmap para portar la imagen
private: //declaraciones de la tabla de eventos y de la clase dinamica
DECLARE_DYNAMIC_CLASS(MyCanvas)
DECLARE_EVENT_TABLE()
};
class MyFrame: public wxFrame
{
public:
MyFrame();
void OnAbout( wxCommandEvent &event ); //funciones de la barra de menu Archivo
void OnQuit( wxCommandEvent &event );
MyCanvas
*m_canvas; //puntero tipo MyCanvas para crear la imagen
private:
DECLARE_DYNAMIC_CLASS(MyFrame)
DECLARE_EVENT_TABLE()
};
class interfaz : public wxApp //funcion inicial para crear las aplicaciones de la ventana
{
public:
virtual bool OnInit();
protected:
private:
};
DECLARE_APP(interfaz)
Archivo posición.cpp
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#include <iostream>
#include <string>
using std::string;
#include <cstdlib>
#include <fstream>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/frame.h"
#include "wx/panel.h"
Agosto del 2004
IE-0502
104
Determinación de la posición de un objeto utilizando una cámara Web
#include "wx/stattext.h"
#include "wx/menu.h"
#include "wx/layout.h"
#include "wx/msgdlg.h"
#endif
#include "wx/calctrl.h"
#include "posicion.h"
IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow) //Esta es la instruccion para implementar la clase
//dinamica para observar la foto
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
EVT_PAINT(MyCanvas::OnPaint)
END_EVENT_TABLE()
MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, //Esta es la instruccion para implementar la clase
const wxPoint &pos, const wxSize &size )
: wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER ) //constructor de la clase MyCanvas
{
my_posicion_jpeg = (wxBitmap*) NULL;
SetBackgroundColour(* wxWHITE); //se crea el fondo de la ventana blanco
wxBitmap bitmap( 100, 100 );
//tamano de la foto
wxMemoryDC dc;
dc.SelectObject( bitmap );
dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
dc.SetPen( *wxBLACK_PEN );
dc.DrawRectangle( 0, 0, 100, 100 );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( 20, 20, 60, 60 );
dc.SelectObject( wxNullBitmap );
wxString dir;
wxImage image = bitmap.ConvertToImage(); //se convierte el bitmap a imagen
#if wxUSE_LIBJPEG
image.Destroy();
if ( !image.LoadFile( dir + _T("/root/wxwindows/wxGTK-2.4.2/demos/proyecto_nuevo/Posicion1")) ) //Aqui va la
direccion de la foto
wxLogError(wxT("No se puede abrir la imagen"));
else
my_posicion_jpeg = new wxBitmap( image ); //agrega la foto a un Bitmap
#endif // wxUSE_LIBJPEG
}
MyCanvas::~MyCanvas()
{
delete my_posicion_jpeg; //destructor borra la imagen de la memoria
}
Agosto del 2004
IE-0502
105
Determinación de la posición de un objeto utilizando una cámara Web
void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) //funcion para abrir la imagen
{
wxPaintDC dc( this );
PrepareDC( dc );
dc.DrawText( _T("Posicion del Objeto"), 30, 15 ); //titulo de la foto
if (my_posicion_jpeg && my_posicion_jpeg->Ok())
dc.DrawBitmap( *my_posicion_jpeg, 30, 30 ); //se pone la imagen en la ventana y se le da la posicion 30,30
}
const int ID_QUIT = 108; //declaraciones de la funciones de la barra de menu Archivo
const int ID_ABOUT = 109;
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
BEGIN_EVENT_TABLE(MyFrame,wxFrame)
//tabla de MyFrame
EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
EVT_MENU (ID_QUIT, MyFrame::OnQuit)
END_EVENT_TABLE()
MyFrame::MyFrame() //constructor de la clase MyFrame para crear la ventana
: wxFrame( (wxFrame *)NULL, -1, _T("Fotografia del Objeto en la Posicion"),
wxPoint(20,20), wxSize(470,360) ) //tamano de la ventana
{
wxMenu *file_menu = new wxMenu();
//se crea la barra de menu
file_menu->Append( ID_ABOUT, _T("&Ayuda..."));
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, _T("&Salir"));
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, _T("&Archivo"));
SetMenuBar( menu_bar );
//se agr ega la barra de menu a la ventana
CreateStatusBar(2);
int widths[] = { -1, 100 };
SetStatusWidths( 2, widths );
m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); //se le agrega a la ventana la foto
m_canvas->SetScrollbars( 10, 10, 10, 15 );//tamano de la ventana
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
//verdadera para salirse del programa
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Esta es la fotografia del fondo\nPara cerrarla, oprima Archivo y luego Salir\nVolvera a la ventana
de ejecucion del programa de deteccion de objeto"),
_T("AYUDA"), wxOK | wxICON_INFORMATION, this); //creditos del programa
}
IMPLEMENT_APP(interfaz)
Agosto del 2004
IE-0502
Determinación de la posición de un objeto utilizando una cámara Web
106
bool interfaz::OnInit()
//funcion para la iniciacion de la ventana
{
// Se crea las aplicaciones principales de la ventana
#if wxUSE_LIBJPEG
wxImage::AddHandler( new wxJPEGHandler );
#endif
wxFrame *frame = new MyFrame();
frame->Show( TRUE );
return true;
}
Agosto del 2004
Descargar