martes, 21 de diciembre de 2010
Un ejemplo curioso
sábado, 18 de diciembre de 2010
Sistema de Coordenadas de Objeto (II)
Para solventarlo y evitar que el objeto se vuelva irreconocible simplemente debido a una mala orientación se va ha cambiar el método de selección de los vectores que definen el sistema de coordenadas del objeto que hasta ahora se basaba en los vectores que conformaban el rectángulo que envolvía al objeto y que ahora pasará a basarse en el vector de mayor módulo entre todos los puntos que conforman el nivel 0, es decir el contorno más exterior del objeto. Además en caso de que haya más de un vector con un módulo similar (p.e. en objetos simétricos) para seleccionar el vector y que sea seleccionado siempre el mismo se deberá que cumpla una serie de propiedades o condiciones (como menor angulo con respecto a la horizontal, etc.)
Una vez definido este vector se tomara como eje de giro siendo el menor angulo posible para poner dicho vector en perpendicular con respecto a la horizontal con centro en el punto medio del vector. Un vez realizado este giro se seguirá con el procedimiento actual de definir el sistema de coordenadas a partir del nuevo rectángulo que rodea al objeto tal y como se hacia hasta ahora.
viernes, 10 de diciembre de 2010
Sentido de la vista
Para facilitar esta tarea y distinguir entre lo que le enseñamos y lo que es fondo o información no relevante Infant contará con un algoritmo que analizará las zonas invariables de las diferentes capturas de la cámara creando una imagen de fondo que almacenará los valores de los pixeles que permanecen más o menos constantes a lo largo del tiempo.
Después cada una de las imágenes obtenidas se compará con esta imagen de fondo por medio de la comparación de la varianza entre los pixeles próximos de cada pixel de la imagen (con lo que se evitará en gran medida que los cambios de iluminación afecten al resultado). Para realizar esta operación de cada pixel, tanto en la imagen base con en la captura que se trata de obtener se obtendrá una matriz 3 x 3 con los siguientes valores:
donde M n,m representa el valor del pixel de la imagen original.
Finalmente las dos matrices obtenidas se restan y se obtiene una matriz final en la que si ninguna de las celdas exteriores supera un determinado valor absoluto significa que el pixel pertenece al fondo (y se actualiza la imagen de fondo con el valor del pixel de la imagen nueva) o en caso contrario es parte de un nuevo elemento en pantalla con lo que se añade a la imagen a analizar.
A continuación os dejo un video en el que podéis ver los resultados, aunque de momento solo es una prueba del algoritmo en el que en los primeros instantes se crea una imagen de fondo (todavía no he implementado el que se genere con los nuevos valores) y a continuación salgo yo haciendo el tonto y enseñándole cosas:
miércoles, 8 de diciembre de 2010
Integración SQLite en C++
Abrir y cerrar la base de datos
En C\C++ una base de datos SQLite es manejada por el objeto sqlite3, que no es otra cosa que un puntero a la base de datos. Para abrir una base de datos cuya ruta es ruta_bd tan solo tenemos que llamar a la función sqlite3_open tal y como en el ejemplo siguiente:
...
if (sqlite3_open(ruta_bd, MemoryDb) != SQLITE_OK)
return -1;
} else {
return 0;
}
Por otro lado analogamente para cerrar una base de datos tan solo hay que llamar a la función sqlite3_close como por ejemplo en:
return 0;
else
return -1;
Consultas de lectura
Una vez abierta la base de datos si queremos realizar una consulta deberemos trabajar con un puntero al objeto sqlite3_stmt y con las funciones sqlite3_prepare_v2 para preparar la consulta que se desea realizar y sqlite3_step para ejecutarla sobre la base de datos. Además y una vez terminadas las operaciones deberemos utilizar sqlite3_finalize que libera los recursos utilizados por sqlite3_stmt.
Por otro lado si queremos obtener los datos que obtenemos de una consulta debermos utilizar las siguentes funciones según el tipo de dato leido:
- sqlite3_column_blob
- sqlite3_column_bytes
- sqlite3_column_bytes16
- sqlite3_column_double
- sqlite3_column_int
- sqlite3_column_int64
- sqlite3_column_text
- sqlite3_column_text16
Un ejemplo con con todo ello es el siguinete:
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(this->MemoryDb,"SELECT * FROM things;",-1,&stmt,NULL) == SQLITE_OK)
{
while (sqlite3_step(stmt) == SQLITE_ROW) // Mientras que se reciban filas...
{
string Name = string(reinterpret_cast
double AvAng = sqlite3_column_double(stmt, 2);
cout ....
sqlite3_finalize(stmt);
return 0;
} else {
return -1;
}
Consultas de escritura y paso de parámetros
En el caso de querer insertar o actualizar datos en una tabla SQLite desde nuestra aplicación es que ahora a la consulta en SQL (con el signo ? donde irá el parametro) deberemos pasarle parámetros con los datos que queremos insertar o modificar. Para ello la API de SQLite dispone de una serie de funciones según el tipo de dato del parámetro:
- sqlite3_bind_blob
- sqlite3_bind_double
- sqlite3_bind_int
- sqlite3_bind_int64
- sqlite3_bind_null
- sqlite3_bind_text
- sqlite3_bind_text16
- sqlite3_bind_zeroblob
sqlite3_stmt* stmt;
int id = 999;
string name = "Infant"
if (sqlite3_prepare_v2(MemoryDb, "INSERT INTO tags VALUES (?, ?);", -1,&stmt,NULL) == SQLITE_OK)
{
sqlite3_bind_int(stmt, 1, id); // Se añaden los parámetros.
sqlite3_bind_text(name.c_str(),-1,SQLITE_STATIC);
sqlite3_step(stmt); // se ejecuta
sqlite3_finalize(stmt); // y finaliza.
return 0;
}
else
{
return -1;
}
lunes, 6 de diciembre de 2010
Paso parámetros entre Lua y C++ : Tablas
Para trabajar con tablas desde C\C++ en primer lugar hay que definir la tabla (por su nombre) y a continuación irle añadiendo los valores con los que valla a trabajar el script sobre dicha tabla. Un ejemplo de estos dos pasos serían las siguientes líneas:
lua_State *L = lua_open();
luaL_openlibs(L);
// Se crea una tabla nueva.
lua_newtable(L);
// Se establece el elemento cuya clave es 1 el valor 45.56
lua_pushnumber( L, 1 );
lua_pushnumber( L, 45.56 );
lua_rawset( L, -3 ); // Escribe el valor
// Se establece el elemento "2" cuyo valor el 99.99
lua_pushnumber( L, 2 );
lua_pushnumber( L, 99.99 );
lua_rawset( L, -3 );
// Se añade a las variable globales (que por cierto es la tabla G_) la nueva tabla llamada "infant"
lua_setglobal( L, "infant" );
// ... aqui llamada al script y otras operaciones...
// Se cierra Lua.
lua_close(L);
Como veis no es nada complicado y es por ello que va ha ser la forma de pasar argumentos entre Infant y Lua contenido en nuestro caso dicha tabla la definición de los diferentes niveles y vectores que componen cada nivel.
Un ejemplo de script que podría hacer uso de estos valores pasados a Lua es el siguiente en el que se escriben todos los valores que contiene la tabla "infant"
for i=0,table.getn(infant) do
print(i,infnat[i])
end
viernes, 3 de diciembre de 2010
Paso parámetros entre Lua y C++ : Variables globales
Bien lo primero que tenéis que hacer el instalar Lua en vuestro sistema. Una vez hecho esto y si habeis configurado vuestro entorno de desarrollo lo mejor es probar si lo habies hecho bien y para ello os recomiendo que hagais una prueba compilando el siguiente codigo:
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
int main()
{
lua_State *LS = lua_open();
luaL_dofile(LS,"hello_name.lua");
lua_close(LS);
}
En el que como podeis ver importamos todas las cabeceras de la API de Lua y a continuación se crea un puntero a una estructura lua_State que sirve como base para cuaquier otra función con la que queramos trabajar. Después se abre el interprete, ejecutamos un script (que tan solo sacara por pantalla un hola mundo) y cerramos nuevamente el interprete.
Como podeís ver es un proces bastante simple, pero, ¿y si queremos que los scripts que tenemos en Lua se comuniquen con la aplicación y\o viceversa? Para ello la API dispone de varias funciones que agilizan estas tareas. En primer lugar y la forma más rapida y sencilla es por medio de variables globales que generamos en nuestra aplicación y que luego utiliza el script en Lua y cuyo contenido puede ser accedido tanto en el script como en la aplicación. Un ejemplo de ello sería el siguiente:
int main()
{
lua_State *L = lua_open();
// Establecemos la variable global "name" y le asiganmos un valor
lua_setglobal(L, "name");
lua_pushstring(L, "Project Infnat");
luaL_dofile(L,"hello_name.lua");
lua_close(L);
}
Para usar esta variable en el script deberemos saber que el script requiere de ella ya que para su utilización se accede a una variable con el mismo nombre que la que se a creado en el codigfo en C. Un sript en Lua que hace uso de esta sería:
io.write("Hello ", name,"\n")
Si, solo esta linea. En caso de querer modificar esta variable en el script y obtener los resultado suponiendo que se alamacenaran en esa variable tan solo tenemos que hacer una llamada a la función lua_getglobal como en el ejemplo:
lua_getglobal(L, "name");
string ret_name = "";
if (lua_isstring(L, -1)) {
ret_name = lua_tostring(L, -1));
printf(ret_name.c_str());
}
Donde -1 es el orden de llamada a la variable con la funcion lua_getglobal(...) y tal y como podeis ver en la API en el caso de los diferentes tipos de variables llamariamos a diferentes funciones segun el tipo.
lunes, 29 de noviembre de 2010
Reglas
- Existe punto (se genera siempre)
- Comprueba si un determinado punto existe en la estructura que se compara.
- El sicript tendra tantos "existe puntos" como puntos comunes (+- 10% distancia) entre todos los objetos en la categoria.
- Existe nivel (se genera siempre)
- Este tipo de comprobacion se creara si todos los objetos de una misma categoria tienen niveles similares y en el mismo orden.
- En siguientes versiones además se definirá la relación que existe entre los diferentes niveles (como diferencia porcentual de área, la posición relativa de sus centros de gravedad o puntos medios, etc.).
- Tiene número minimo-maximo de verices. (se genera si hay más de un objeto en la misma categoria)
- Esta regla se genera si entre los diferentes objetos de la categoria la diferencia entre el minimo y el maximo es menor a la media.
- Tiene N vectores como (se genera si hay más de un objeto de la misma categoria)
- Regla que comprueba si en un determinado objeto se dan determinados vectores.
- Tiene x lineas de longitud min - max. (se genera si hay más de un objeto de la misma categoría)
- Regla que se crea si se detecta que en todos los objetos se tienen vectores con el mismo (o parecido) módulo.
viernes, 26 de noviembre de 2010
Primer Script en Lua
Ahora mismo estoy pensando en la forma de preparar otros generadores de reglas para completar el script y que se creen analizando propiedades comunes de los objetos de las diferentes categorías del "árbol de conocimiento" (tm) :P de Infant. Por otro lado he pensado que sería una buena idea preparar un par de manuales de como integrar Lua en aplicaciones C++, pasar parámetros, tablas, etc. así que espero publicar alguno la semana que viene.
miércoles, 24 de noviembre de 2010
Infant se reescribirá a si mismo
Para ello Infant generará un script en Lua en el que se defina una función que decidirá si un deterinado objeto pertenece o no a una determinada categoría, código que será generado según las propiedades y características comunes y no cumunes de todos los objetos pertenecientes a esa categoría, lo precompilará (para mayor velocidad) y después utilizará ese script para decidir si un objeto nuevo, desconocido en principio, pertenece o no a esa categoría.
Por supuesto aun esta todo por hacer pero ya os iré contando.
lunes, 22 de noviembre de 2010
Sistema de coordendas de objeto
Uno de los elementos clave en los que se basará Infant es el Sistema de Coordenadas de Obejeto y que consiste basicamente en que una vez vectorializados los bordes de un determinado objeto estos se convertiran a un sistema propio de coordendas.
Origen de la idea
Esto va ha sonar un poco raro... pero cerrar los ojos e imaginaros primero una manzana cualquiera y después borrar esa imagen de la manzana e imaginaros la Torre Eiffel. En esas imagenes que se os presentan, por lo menos en mi caso, aparece la manzana en la misma escala que la torre es decir que si suporponeis esas dos imagenes las dos tendran el mismo tamaño y la manzana tapará a la Torre Effiel. Es juesto en esa idea de mantener las proporciones en referencia al total de la dimensiones de cada objeto en la que se basa el sistema.
Sistema de coordendas de objeto
Para desarrollar las ideas anteriormente descritas nace la necesidad del sistema de coordendas unico para todos los elementos y surge a raiz de querer comparar estos objetos entre si, para lo que debe garantizarse que:
- Todos los objetos estan en la misma escala, es decir que si se compara un determinado simbolo que ocupa 1000x1000 px. y el mismo simbolo pero en una de 100x100 se sigan podiendo comparar los vectores de ambos.
- La posicion relativa entre estos vectores es la misma, es decir que siempre se realizen las mismas transformaciones en objetos similares.
- Que no haya deformaciones o si las hay que sean iguales en todos los objetos (en nuestro caso las habrá).
Matematicamente simplemente se define un sistema ortonormal en el que el origen de coordenadas es la coordenda menor (inferior izquierda) de la imagen y los vectores directores (aunque en nuetro caso su módulo no es la unidad sino el 100%) son los compuestos por el ancho y el largo del bounding box que contiene el objeto despues para transformar el objeto a ese sistema de coordenadas lo que hacemos es simplemente, sobre cada vector aplicaicar una traslacion y escalarlos segun el porcentaje en relacion al nuevos ejes de coordendas por lo que la operacion matematica es simplemnte suma y multiplicacion de vectores. Como imagino que será mucho mas fácil verlo graficamente un ejemplo sencillo sería el siguiente en el que la letra J pasa a convertirse en la letra J en el sistema de coordendas de objeto (aplicando también una simplificación a la imagen vectorializada de la que ya hablaremos):
domingo, 21 de noviembre de 2010
Que haceres
Id Tarea | Descripción de la Tarea |
2200 | Knowleadge tree loading |
2201 | Camera image loading |
2202 | Manage and extract camera data |
2203 | Rule generation system |
2204 | Integrate rule generation system on tree structure |
2205 | Recongnize single objects with cam |
2206 | Create teaching interface |
2207 | Create observer interface |
jueves, 18 de noviembre de 2010
Paradigmas de aprendizaje automático
- Aprendizaje deductivo
- Aprendizaje analítico
- Algoritmos genéticos
- Conexionismo
- Aprendizaje analógico
- Aprendizaje inductivo
- Aprendizaje mediante descubrimiento
lunes, 15 de noviembre de 2010
Parecidos razonables
Ya le he enseñado a Infant las letras mayusculas a partir de fichas (es decir imagenes con cada una de las letras) y la verdad es que después al volver a comparar con una nueva letra A los parecidos con las demás letras han dado los resultados esperados (incluso demasiado así que algo habremos hecho mal :P):
100 % similar to a,letra,mayuscula
0 % similar to b,letra,mayuscula
0 % similar to c,letra,mayuscula
0 % similar to d,letra,mayuscula
0 % similar to e,letra,mayuscula
12 % similar to f,letra,mayuscula
0 % similar to g,letra,mayuscula
25 % similar to h,letra,mayuscula
0 % similar to i,letra,mayuscula
0 % similar to j,letra,mayuscula
12 % similar to k,letra,mayuscula
0 % similar to l,letra,mayuscula
0 % similar to letra,mayuscula,o
6 % similar to letra,mayuscula,p
0 % similar to letra,mayuscula,q
12 % similar to letra,mayuscula,r
0 % similar to letra,mayuscula,s
0 % similar to letra,mayuscula,t
0 % similar to letra,mayuscula,u
0 % similar to letra,mayuscula,v
25 % similar to letra,mayuscula,x
0 % similar to letra,mayuscula,y
0 % similar to letra,mayuscula,z
Si ya se que faltan un par de letras pero con las letras M,N y W no se vectorizan del todo bien así que ahora toca corregir esos pequeños fallos.
sábado, 13 de noviembre de 2010
Proceso de apendizaje
A continuación os presento algunos de los puntos básicos sobre el proceso de aprendizaje a partir de los cuales se basarán los algoritmos de aprendizaje automático de Infant:
- Si existe cualquier duda sobre el concepto a aprender es mejor no aprender.
- Si se tiene la certeza de que un determinado concepto es correcto pero este no se parece a lo ya aprendido entonces crear una excepción (principio de no alteración). Es decir, es mejor no modificar drásticamente un concepto aprendido.
- El aprendizaje se ha de realizar en pasos muy pequeños, secuencialmente y refinando las ideas. Esta es la llamada ley de Martin que dice “You can't learn anything unless you almost know it already” o lo que es lo mismo, “No puedes aprender nada a menos que ya casi lo sepas”.
- No modificar nunca el conocimiento de base (llamemos lo leyes), es decir, conceptos en los cuales se tiene la total certeza de que son tal cual se han aprendido y no pueden modificarse (este punto es mío :P)(por ejemplo leyes físicas, que un circulo es una sucesión de puntos con la misma distancia un punto llamado centro o las tres leyes de la robótica).
sábado, 6 de noviembre de 2010
jueves, 4 de noviembre de 2010
El cerebro de Infant en un árbol
La idea es por tanto, que según se vallan introduciendo nuevos conceptos estos se jerarquicen de modo que finalmente tengamos una estructura como la siguiente que organiza todo el "conocimiento" adquirido por Infant:
La finalidad principal de añadir esta estructura es que una vez aprendidos y organizados una serie de objetos/conceptos el sistema sea capaz de reconocer (mediante la creación de reglas) por si mismo nuevos objetos de una determinada categoría e incluso ser capaz (en un futuro muy lejano :P) de especificar de qué objeto se trata a partir de la generalización y con la ayuda de fuentes de datos externas (digamos wikipedia o google images)...
martes, 2 de noviembre de 2010
Letra A
I|L|V|P|X|Y|X|Y
7|0|0|0|6.50572125468138e-15|98.8372093023256|45.0|0.0
7|0|0|1|45.0|0.0|58.75|3.48837209302326
7|0|0|2|58.75|3.48837209302326|100.0|98.8372093023256
7|0|0|3|100.0|98.8372093023256|85.0|98.8372093023256
7|0|0|4|85.0|98.8372093023256|72.5|69.7674418604651
7|0|0|5|72.5|69.7674418604651|26.25|70.9302325581395
7|0|0|6|26.25|70.9302325581395|13.75|100.0
7|0|0|7|13.75|100.0|6.50572125468138e-15|98.8372093023256
7|1|0|0|7.65378971138986e-15|97.2222222222222|46.4285714285714|0.0
7|1|0|1|46.4285714285714|0.0|100.0|100.0
7|1|0|2|100.0|100.0|7.65378971138986e-15|97.2222222222222
sábado, 30 de octubre de 2010
Vectores y niveles
jueves, 28 de octubre de 2010
Follow Me
Para los que quieran estar informados en directo sobre el proyecto, ideas, problemas que surgan, y otras noticias importantes sobre el avance del proyecto (y alguna que otra tontería) he creado la cuenta @ProjectInfant en Twitter . Follow Me!
miércoles, 27 de octubre de 2010
Librerías
Librería para la creación de aplicaciones que necesitan hacer uso de algoritmos de vision por ordenador. Entre sus caracterisitcas esta el acceso y manejo de diferentes cámaras, algoritmos de procesamiento de imagenes, algoritmos de vision estereoscopica, reconocimiento de caras, etc. Para Infant de esta librería utilizaremos principalmente el manejo de cámaras y alguna que otra funcion de procesado de imagenes.
Que viene a ser un sistema de base de datos relacional libre, sencillo y potente. En nuestro caso será la memoria del sistema ya que almacenara todo lo que Infant vaya aprendiendo.
Librería para la creacion de interfaces gráficos cuya principal caracterísitca es el mínimo consumo de recursos y que en nuestro caso servirá para crear principalmente los interfaces para el entrenamiento (aprendiaje) de Infant.
vlib:
Líbreria propia y que será liberada junto con el proyecto creada principalmente para manejar datos vectoriales y realizar las difernetes operaciones necesarias sobre ellos (traslacion ,rotacion, centroide, convex hull, etc.).
lunes, 25 de octubre de 2010
Presentación
Tal y como dice la descripción en la ficha del V CUSL sobre el proyecto:
Infant es un proyecto/experimento en el que se tratará, mediante el uso de algoritmos de aprendizaje automático y visión por ordenador crear una aplicación capaz de identificar objetos por medio de diferentes técnicas.
Es decir, la idea principal es crear un sistema que sea capaz de aprender a diferenciar y distinguir determinados objetos y una vez aprendidos capaz de diferenciarlos en diferentes escenas o en las imagenes capturadas por una camara.