24 de septiembre de 2008

Algoritmo de Esqueletizacion de Pavlidis


En ocasiones, debido a la gran cantidad de información que presenta una imagen, resulta conveniente trabajar solo con las características más importantes de la imagen a procesar. Para el caso particular de reconocimiento óptico de caracteres las características más importantes se encuentran representadas en el esqueleto del caracter.

Entendemos por Esqueletización a una transformación que busca reducir la cantidad de datos o simplificar la forma del objeto, con el fin de encontrar características útiles en algoritmos de reconocimiento y clasificación.


El algoritmo de esqueletizacion de Pavlidis se basa en la idea de que los pixeles esqueletales son solo aquellos pixels que presentan alguna similaridad con alguna de las plantillas que se muestran a continuación:


En las plantillas del inciso A, al menos un píxel de los grupos etiquetados como A o B debe ser diferente de cero. Los píxeles marcados con el valor de 2 son píxeles esqueletales.

En la plantilla del inciso B, al menos un píxel marcado con debe ser diferente de cero. Si ambos píxeles etiquetados con C son diferentes de cero, entonces los píxeles etiquetados con CA o pueden tener cualquier valor. De otra manera, al menos un miembro de cada par marcados con BA y deben ser diferentes de cero


En base a esta teoría y atendiendo a dificultades en los resultados con el algoritmo antes mencionado, planteo una solución alternativa, la cual se basa en las rotaciones de las plantillas que muestro a continuacion:

Según lo cual, las cuatro rotaciones en 90º de cada una de las plantillas deben ser comparadas con cada uno de los 4-vecinos de cada pixel de la imagen. Los 4-vecinos de un pixel en una vecindad de 3x3 se denota bajo el siguiente esquema:
Y los que son necesarios a considerarse en el algoritmo de pavlidis y en ste algoritmo son los pixels 0,2,4,6.


Algoritmo
% Entrada: Imagen binarizada imBin normalizada (0 = negro, 1 = blanco)
% Salida: Imagen Esqueletizada normalizada (0=negro, 1=blanco)

REMAIN = 1; % se usa para denotar la existencia de pixeles esqueletales
SKEL = 0; % se fija a cierta cuando alguna vecindad de un pixel es similar a
% alguna de las plantillas existentes en P
CONVERTIR IMBIN A CEROS Y UNOS Y ALMACENARLA EN IMG
nf = NUMERO DE FILAS DE MATRIZ img
nc = NUMERO DE COLUMNAS DE MATRIZ img
d = 1 % columnas que no se evalúan por ser la plantilla de 3 x 3
MIENTRAS REMAIN = 1
REMAIN = 0;
PARA k=1 hasta 4 % los indices de los vecinos de un determinado punto
% se recorre toda la imagen
PARA i=1+d hasta nf-d
PARA j=1+d hasta nc-d
SI P TIENE EL VALOR DE 1 Y SI J-VECINO TIENE EL VALOR DE CERO
SKEL = 0
SI VECINDAD DE P CONCUERDA CON ALGUNA PLANTILLA, SKEL SE ACTUALIZA A 1
SI SKEL == 1 ENTONCES % si la plantilla concuerda con la matriz
img(i,j) = 2;
EN CASO CONTRARIO
img(i,j) = 3;
REMAIN = 1;
FIN SI
FIN SI
FIN PARA
FIN PARA
REEMPLAZAR TODOS LOS PIXELS CON VALOR “3” POR “0”
FIN PARA
FIN MIENTRAS % fin del algoritmo



Aca les dejo la implementación del algoritmo de pavlidis, con una ligera modificación hecha por mi parte para Adelgazamiento de Imágenes. El trabajo fue desarrollado en el curso de Procesamiento de Imágenes, un curso de Pre-grado de la carrera de Informática en la Universidad Nacional de Trujillo. El codigo esta hecho en matlab y se encuentra documentado.

Consultas en bases de datos de Imagenes

Las soluciones computacionales actuales a necesidades de información de ciertas empresas necesitan almacenar y recuperar información propia para poder desempeñar sus actividades diarias tales como retiros y depósitos en caso de bancos, consulta de precios y facturación en caso de un centro comercial, y un sinfín de actividades que requieren siempre una base de datos (o bases de datos) para su funcionamiento. Dependiendo de las necesidades de información de la empresa y su manipulación es que se escoge entre distintos tipos de bases de datos la que más se adecúe a una solución en particular y con esta se satisfacen las necesidades de información de las aplicaciones.

Existen aplicaciones que manipulan información multimedia o imágenes, como los servicios de información satelitales en los que es necesaria la ubicación directa de la imagen, para este tipo de necesidades existe un tipo de base de datos denominado “Base de datos de Imágenes”, en el cual el índice o llave es una imagen(a diferencia de las bases de datos convencionales en las que contábamos con un ID de tipo cadena o numérico), por lo que nos daremos cuenta de que el tipo de consultas en este tipo de bases de datos es muy distinto al que nosotros conocemos en las bases de datos convencionales.

Todo esto nos lleva a pensar en un factor importantísimo en toda aplicación (como lo vendría a ser el propio manejador de la base de datos): “La Eficiencia”. Imaginemos una base de datos de imágenes en las que se quiera recuperar todas las imágenes que posean un rectángulo en el extremo izquierdo, y que se encuentren entre un rango de tono de gris determinado. ¿Será eficiente la respuesta de la base de datos en una base con unos cien mil registros? Obviamente el factor eficiencia está asociado directamente al intérprete de consultas de la base de datos que, como reitero es muy distinto al de una base de datos convencional.

En este paper lo que se pretende es brindar una visión global del tratamiento de bases de datos de imágenes haciendo hincapié en las consultas en este tipo de bases de datos por lo importante de ellas en la recuperación de información en este tipo de bases de datos.


21 de septiembre de 2008

Conexiones a Bases de Datos en C#

En la actualidad, el acceso a datos por parte de nuestros programas de escritorio es algo indispensable, y el uso de bases de datos dan fe de ello, tanto en el trabajo como en la vida universitaria de cualquier estudiante de computación y afines.

En vista de ello, y ya que actualmente me encuentro estudiando C#, me animé a incursionar más en el mundo del software propietario y aprovechar las herramientas y tecnologías que proveen.


ADO.NET es una colección de clases, interfaces, estructuras y tipos enumerados que permiten acceder a los datos almacenados en una base de datos desde la plataforma .NET. Si bien se puede considerar una versión mejorada de ADO, no comparte con éste su jerarquía de clases.

DO .NET usa XML. De hecho, los conjuntos de datos se almacenan internamente en XML, en vez de almacenarse en binario como sucedía en ADO. Al estar los datos almacenados en XML, se simplifica el acceso a los datos a través de HTTP (algo que ocasiona problemas en ADO si los datos tienen que pasar cortafuegos). Por otro lado, se simplifica la comunicación entre aplicaciones al ser XML un formato estándar.

Con ADO .NET se puede acceder a los datos de dos formas distintas:

  • Acceso conectado: Acceso sólo de lectura con cursores unidireccionales ("firehose cursors"). La aplicación realiza una consulta y lee los datos conforme los va procesando con la ayuda de un objeto DataReader.
  • Acceso desconectado: La aplicación ejecuta la consulta y almacena los resultados de la misma para procesarlos después accediendo a un objeto de tipo DataSet. De esta forma, se minimiza el tiempo que permanece abierta la conexión con la base de datos.

Al proporcionar conjuntos de datos de forma desconectada, se utilizan mejor los recursos de los servidores y se pueden construir sistemas más escalables que con ADO (que mantenía abierta la conexión con la base de datos la mayor parte del tiempo). Este enfoque resulta más adecuado en sistemas distribuidos como Internet.

Ahora vamos a ver unos cuantos códigos de ejemplo de conexiones de base de datos en C#.

Si tenemos una base de datos en SQL Server (aunque funciona para cualquier base que se encuentre registrada previamente en el DSN de usuario), de nombre “ModeladorSQL” en el DSN de Usuario y con nombre del servidor = “HOME” (el nombre del computador), el código de una conexión será de la siguiente manera:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace WindowsApplication1
{
class ejemplo1
{
SqlConnection conexion;

public ejemplo1()
{

inicializarConexionBD();
consultaBD();
cerrarConexionBD();
}

private void cerrarConexionBD()
{
conexion.Close();
}

private void inicializarConexionBD()
{
conexion = new SqlConnection("Server=HOME;Database=ModeladorSQL;Integrated Security=True");
conexion.Open();
}

private void consultaBD()
{
SqlDataReader dr;
SqlCommand comm = new SqlCommand("Select nombre from Tipo_Atributo",conexion);
dr = comm.ExecuteReader();
while(dr.Read())
{
Console.WriteLine(dr.GetString(0));

}
}
}
}


La sencilla aplicación busca reportar la primera columna del resultado de la consulta, la cual devuelve todos los atributos “nombre” de la tabla “Tipo_Atributo”

Otra forma de obtener el mismo resultado, pero de una manera más elaborada es la siguiente, solo reemplazamos el procedimiento consultaBD por el que se muestra a continuacion:


private void consultaBD()

{
DataSet d = new DataSet();
SqlCommand com = new SqlCommand("Select nombre from Tipo_Atributo",conexion);
SqlDataAdapter sda = new SqlDataAdapter();
sda.SelectCommand = com;
sda.Fill(d);
DataTable data = d.Tables[0];
foreach (DataRow dr in data.Rows)
{
int i;
for (i = 0; i < data.Columns.Count; i++)
{
Console.WriteLine(dr[i].ToString());
}
}
}


En el ejemplo anterior hacemos uso de un objeto de tipo DataSet,una caché de memoria interna de datos recuperados desde un origen de datos. Este tipo de estructura permite almacenar más de una tabla dentro de ella. Para hacer uso de ella en las consultas, es necesario declarar un SqlDataAdapter, el cual llenará los datos de la consulta dentro de ella, en una nueva tabla.

ODBC.NET es un componente complementario del Kit de desarrollo de software (SDK) de Microsoft .NET Framework. Proporciona acceso a los controladores ODBC nativos de la misma manera que el proveedor de datos de OLE DB .NET proporciona acceso a los proveedores de OLE DB nativos. Aunque el proveedor de datos de ODBC .NET está pensado para trabajar con todos los controladores ODBC compatibles, sólo se ha probado con los siguientes:

  • Controlador ODBC de Microsoft SQL
  • Controlador ODBC de Microsoft para Oracle
  • Controlador ODBC de Microsoft Jet

Las conexiones, sin embargo son bastante similares a las hechas usando ADO.NET, aunque no con la potencialidad de esta ultima. Veamos un ejemplo:

Asumiendo que la base de datos se encuentra en SQL Server 2000, que el servidor se llama “HOME” y que la base de datos, en orígenes de datos se encuentra registrada como “modeladorSQL”.

using System;
using System.Data;
using System.Data.Odbc;

namespace WindowsApplication1
{
class ejemplo2
{
OdbcConnection conexion;

public ejemplo2()
{
inicializarConexionBD_ODBC();
consulta_ODBC();
cerrarConexionBD();
}

private void cerrarConexionBD()
{
conexion.Close();
}

private void inicializarConexionBD_ODBC()
{
conexion = new OdbcConnection("Driver={SQL Server};Server=HOME;Database=modeladorSQL;IntegratedSecurity=True");
conexion.Open();
}

private void consulta_ODBC()
{
OdbcCommand comm;
comm = new OdbcCommand("Select nombre from Tipo_Atributo", conexion);
OdbcDataReader reader = comm.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
}
}
}

Esta es una forma sencilla de conectar una base de datos, sin embargo podemos hacerlo de una manera más elaborada:

private void consulta_ODBC()
{
OdbcCommand comm;
DataSet d = new DataSet();
comm = new OdbcCommand("Select nombre from Tipo_Atributo",conexion);
OdbcDataAdapter da = new OdbcDataAdapter();
da.SelectCommand = comm;
da.Fill(d);
DataTable data = d.Tables[0];
foreach (DataRow dr in data.Rows)
{
for (int i = 0; i < data.Columns.Count; i++)
{
Console.WriteLine(dr[i].ToString());
}
}
}


Vemos que trabaja con estructuras similares a ADO.NET, como objetos DataView, OdbcDataAdapter muy similar a SqlDataAdapter. Depende de gustos, de la aplicación y del gestor de base de datos a utilizar. Hay que tener en cuenta que en ODBC especificamos el driver a utilizar para la base de datos correspondiente, algo que no se ve en ADO.NET.. en fin..

Espero que les sea de utilidad . Saludos

Fuentes:

http://support.microsoft.com/kb/310988/es
http://msdn.microsoft.com/es-es/library/system.data.dataset(VS.80).aspx
http://elvex.ugr.es/decsai/csharp/databases/index.xml