OCR desde Java o .NET

En la empresa donde trabajo, soy Lider de Proyecto de un Sistema a desarrollar llamado CoReVi (Control de Registro de Visitas), el cual pretende acelerar el registro de las visitas que recibe una empresa. Una de las características más sobresalientes esta en el hecho de que para agilizar el proceso, se deben capturar los datos del visitante de manera automática mediante alguna de las 3 identificaciones aceptadas por el sistema:

  1. Credencial de Elector
  2. CURP
  3. Cartilla Militar

La imágen de la credencial será digitalizada por medio de un escaner, el sistema deberá identificar el tipo de credencial que se trata y procederá en automático a llenar en el sistema los datos de:

  • Apellido Paterno
  • Apellido Materno
  • Nombre
  • Domicilio
  • Edad
  • Sexo

De esta forma se pretende disminuir el tiempo y los errores de captura, al hacer automático todo el proceso que comúnmente se hace de forma manual!

Una de las apuestas de la empresa es el desarrollo bajo Java, se pensó en hacerlo en esta plataforma. Sin embargo, con unos días de investigación que realicé, comense a darme cuenta que esto no era muy factible. Lamentablemente no encontré un buen OCR Open Source para poder utilizarlo desde Java, probe GOCR, tesseract-ocr, entre otros. Sin embargo, el resultado de reconocimiento fue muy pobre para las identificaciones (Credencial de elector) descritas con anterioridad. El desarrollar un OCR estaba fuera de nuestro alcanse, pues para desarrollar un buen producto, aparte de capacidad, se necesita de $$$ la cual por el bajo sueldo era imposible siquiera tener las ganas de hacerlo.

Además, otro problema que no pude resolver por mi innexperiencia fué sobre la Adquisición de Imágenes. Usando Twain fue posible adquirir la imágen desde Java, pero existia un gran inconveniente! Y erá que no podia ocultar la ventana del programa controlador del dispositivo, es decir, desde Java y sin importar el fabricante del escaner, se “adquiria” la imágen, no sin antes pasar por la ventanita esa del escáner en donde primero habia que hacer una “vista previa ” de la imágen para poder recortarla al tamaño de la credencial y finalmente digitalizar!

Obviamente el proceso anterior dejaba de ser tan “automático” como se pretendia que fuera, pues requeria la intervensión del usuario. Entre este y el gran problema de no contar con un buen OCR decidi que el proyecto no se desarrollaría bajo la plataforma Java.

Fué entonces cuando decidi mirar al acerrimo rival, .NET! Debo reconocer que en .NET mis problemas quedaron resueltos.

La adquisición de imágenes mediante WIA y el uso de MODI como OCR me permitieron dar una tentativa solución a mi problema. Con WIA he logrado adquirir la imágen directamente sin pasar por ninguna ventana del controlador y mediante MODI he logrado muy buenos resultados en el reconocimiento de imagen-texto, así pues, logré obtener los datos del visitante arriba mencionados de forma automática y en cuestión de segundos para poder ser enviados a la Base de Datos!

El desarrollo del sistema, arranco formalmente hace unos días, es decir, los días anteriores habian sido solo de investigación para ver que tan factible era desarrollarlo sobre Java o buscar alternativas. Una vez que pude resolver esos inconvenientes en .NET, ya se arranco bien el desarrollo del proyecto, aunque claro, hay que seguir una metodología! Primero es realizar el análisis de requisitos, elaborar documentos, Diagramas UML, Diagrama E-R, más documentos, esperar a que me los validen, etc etc y posteriormente iniciar la codificación! Es decir, tratar de llevar una buena Ingeniería de Software, en especifico, cumplir con la norma de MOPROSOFT (NMX-I-059/01-NYCE).

Publicaré más adelante, como adquirir imágenes desde Java y .NET. Desde Java mediante el uso de Twain y desde .NET con WIA. Con Java y Twain habrá que pasar primero por el programa controlador del dispositivo.

Saludos!!

Formulario de contacto en Flash y PHP

Estas son las primeras líneas que escribo para poder aportar algo productivo, no tenía ni idea de que podía publicar , pero recordé por un instante que busque en internet información sobre formularios de contacto en flash y php, así que explicare un poco de esto, la información que escribiré son sólo pedazos de pequeñas lecturas, así que si hay algo parecido es porque tal vez es una coincidencia(en realidad tomé como referencia un par de páginas).

Explicaré de manera sencilla como realizar un formulario de contacto en flash y php , para este ejemplo utilice la versión 8 de flash y php 5.

Además de lo anterior, debemos usar la función mail(); de php , osea seria bueno tener un servidor de correo.
Aunque hay muchos ejemplos en internet sobre este tema, solo quise hacer una prueba paso por paso, y quitarme de algunas dudas que tenia respecto al código.

Lo comparto y espero que sea de utilidad, o por lo menos sirva de guía.
Empezamos por diseñar el archivo .fla , abrimos flash clic en nuevo documento , configuramos color y tamaño del escenario, en el menú insertar elegimos nuevo símbolo – clip de película y le damos un nombre, en este caso use un clip de película para darle movimiento a todo el formulario: un clip de película es una película dentro de otra que nos sirve para dar efectos y tener varias animaciones separadas al mismo tiempo , si solo quisiera el formulario sin ningún tipo de animación simplemente podría empezar por diseñarlo sin insertar ese tipo de símbolo, pero para no hacerlo tan aburrido, decidí darle un pequeño efecto.

Una vez creado el clip, diseñaremos el formulario en ese clip, insertamos tres campos de texto y les asignamos un nombre de instancia a cada uno : nombre, eemail, y otro que se llame mensaje de tipo texto dinámico donde se mostrarán los mensajes a la hora de realizar alguna acción.

También agregamos dos botones uno para enviar los datos y procesarlos y el otro para limpiar el formulario. Si no tenemos idea de cómo dibujar un botón, podemos usar botones ya prediseñados en el menú ventana – bibliotecas comunes.
Bueno, el siguiente paso es salir del clip de película para utilizarlo en nuestro escenario, damos clic sobre la línea de tiempo donde dice Escena1 para regresar a la película principal.

Por el momento no hay nada en el escenario, pero tenemos un clip de película el cualopodemos ver que se encuentra en la biblioteca presionando f11, aquí arrastramos el clip hasta posicionarlo en el escenario.

Ahora podemos darle animación a nuestro formulario como si se tratara de una imagen, pero en realidad es una película que procesará datos, en este momento nos encontramos en el fotograma 1, presionamos f6 en otro fotograma puede ser el 16 o 25 dependiendo de que tan rápido queremos que dure la película, después clic derecho interpolación de movimiento.

Nos posicionamos en el fotograma 1 y elegimos de la barra de herramientas el icono de transformación libre, y escalamos la figura , de manera que quede pequeña, también podemos hacer que gire, para esto damos un clic en cualquier fotograma que se encuentre en medio del primero y el último y en propiedades, elegimos hacia donde girara.
El escenario debe verse como la siguiente imagen.Aqunque en el archivo original le agregue que también vaya apareciendo con el efecto alpha, del panel propiedades.

Pero si dejamos asi la animación se repetira infinitamente, por lo que falta escribir la línea stop(); en el último fotograma donde termina la animación y clic en acciones.

Después de todo la parte del diseño, solo queda que funcione.

Ahora damos doble clic sobre nuestro clip de película, estando dentro de su línea de tiempo, nos dirigimos al primer fotograma y escribimos en acciones lo siguiente.

nombre.text = “”;
eemail.text = “”;
asunto.text = “”;

Esto es para que cada que iniciemos la animación no se guarde basura y muestre resultados inesperados.
Ahora pasamos al botón enviar ,con un clic derecho y en acciones escribimos el siguiente código que ya esta documentado por alguna duda.

on(release){
//if (nombre.text.length && eemail.text.length && asunto.text.length)
//Verifica que todos los campos no esten vacios

if (nombre.text.length && eemail.text.length && asunto.text.length){
//(eemail.text.indexOf(”@”) != -1 && eemail.text.indexOf(”.”) != -1)
//Verifica que el campo eemail se escriba correctamente con “@ “y un “.”
//para hacer la comprobación utilizaremos un método de los objetos string
//llamado IndeOf: indica la posición en que se encuentra una letra o grupo de letras
// si no la encuentra devuelve -1

if (eemail.text.indexOf(”@”) != -1 && eemail.text.indexOf(”.”) != -1) {
//Creamos dos variables de la clase LoadVaras “con”: para enviar datos al servidor
//y “recibe”: para recibir datos del servidor

con = new LoadVars();
recibe = new LoadVars();
//Asignamos las variables que se enviaran
con.nombre = nombre.text;
con.eemail = eemail.text;
con.asunto = asunto.text;
//Usamos la propiedad senAndLoad para enviar o recibir datos
//tiene tres parámetros el primero es la página que procesará los datos
//el segundo , es la variable que recibe el estado de envio de datos al servidor
//el tercero el método por el que pasarán las variables

con.sendAndLoad(”contactof.php”,recibe, “POST”);

//Esta función devuelve el estado de que efectivamente se procesaron los datos
//devuelve ok , si los datos fueron enviados correctamente y se muestra
// en mensaje la frase “Los datos fueron enviados”

recibe.onLoad = function() {

if (recibe.estado == “ok”) {

mensaje.text = “Los datos fueron enviados”;
//Llamamos a la función borrar para uqe deje limpias las cajas de texto
borrar();

}

else {
//si hubo algún error al enviar los datos
mensaje.text = “Error al enviar los datos”;

}

}//funcion recibe

}//fin segundo if

else{
//Si no se cumple el segundo if , es decir si no escribió el email correctamente
eemail.text=”E-mail incorrecto”;
}

}// fin primerif

else{
//Si no se cumple el primer if , si no hay datos
mensaje.text=”Faltan ampos por llenar”;

}//fin else

function borrar (){
nombre.text =”";
eemail.text =”";
asunto.text =”";

}

}//fin release

Y en el botón borrar en acciones escribimos:

on(release){
nombre.text = “”;
eemail.text = “”;

asunto.text = “”;
}

Por ultimo creamos la página contactof.php que procesara los datos.

<?php
$nombre=$_POST['nombre'];
$eemail=$_POST['eemail'];
$asunto=$_POST['asunto'];

//Correo donde llegaran los datos
$email=”alguien@servidor.com”;

$comentario=”Tienes un comentario”;

$mensaje=”Te ha llegado un comentario de $nombre con los siguientes datos:
Nombre: $nombre
E-mail: $eemail

Y te ha enviado el siguiente mensaje:

___________________________________________
$asunto
————————————–”;

mail($email,$comentario,$mensaje);
echo”estado=ok”;
?>

Aqui una prueba de que funciona el formulario.

1) Si hay un error

2) Si faltan campos por llenar

3) Si los datos se enviaron correctamente

Si no disponemos de un servidor que trabaje con php, para recoger los datos y procesarlos, podemos usar otro método más simple que usa el programa de correo electrónico instalado en la computadora del usuario.
Entonces sistituimos el código del botón enviar por el siguiente:

on(release){

if (nombre.text.length && eemail.text.length && asunto.text.length){
if (eemail.text.indexOf(”@”) != -1 && eemail.text.indexOf(”.”)
!= -1) {

//newline permite dejar saltos de línea cuando se muestra el mensaje
enviardatos=”alguien@servidor.com?subject=”+nombre+”&body=Nombre: “+nombre+newline+”E-mail:”+eemail+newline+”Asunto:”+asunto;

getURL(enviardatos);

}//fin segundo if

else{

//Si no se cumple el segundo if , es decir si no escribió el email correctamente

eemail.text=”E-mail incorrecto”;

}

}//fin primer if
else{

//Si no se cumple el primer if , si no hay datos
mensaje.text=”Faltan ampos por llenar”;

}//fin else

function borrar (){

nombre.text =”";

eemail.text =”";

asunto.text =”";

}
}// fin del release

La desventaja de usar este método es que se abrirá el programa al pulsar el botón enviar y el usuario tendría que llenar algunos datos.Dejo los archivos aquí.

Comunicar 2 PC´s por puerto serie con Visual Basic 2005

Vamos a comunicar a 2 PC´s por medio del Puerto Serie a travez de un sencillo programa hecho en Visual Basic 2005. Esta vez no utilizaré Java debido a que el api para manipular el puerto COM no trae soporte para Windows (ya saben como Windows le gusta bloquear y hacer las cosas más dificiles para otros que no sean de su familia), unicamente trae soporte para sistemas Linux, Solaris.

MATERIAL REQUERIDO

Para hacer esta comunicación, necesitaremos un cable serial hembra-hembra. Para conseguirlo, podemos hacerlo desde cero o si ya disponemos de un cable serie macho-hembra, podemos cortar el extremo macho. Posteriormente, es necesario hacer un cruce.

Tomamos un Multimetro para medir la continuidad del cable, tomamos una punta y la metemos en el pin numero 1 del conector hembra DB9, la otra punta del multimetro la probaremos en cada uno de los cables del otro extremo hasta que exista continuidad, de tal forma que en mi caso, obtuve:

  1. Negro
  2. Blanco
  3. Rojo
  4. Naranja
  5. Amarillo
  6. Verde
  7. Azul
  8. Morado
  9. Gris

En el extremo que cortamos, vamos a cruzar el cable 2 y 3. Entonces tomamos un conector DB9 y comenzamos a soldar los cables, teniendo en cuenta el cruce, es decir, el cable 2 lo soldaremos en el pin 3 del DB9 y el cable 3 en el pin 2. Por último medimos nuevamente la continuidad entre ambos extremos, pero ahora cuando en un extremo midamos el pin 2, en el otro extremo tendremos que medir el PIN 3 y viseverza.

Como una simple prueba, podemos enviar datos desde el DEBUG. Inicio–Ejecutar y escribimos DEBUG. Ahora escribiremos la Instrucción OUT:

- O 03F8 A5

Previamente deberemos verificar que 3F8 es en efecto la dirección del Puerto COM1. Una vez que ya estamos seguros en la dirección del Puerto, ya podemos probar con la instruccion anterior. A5 es un valor Hexadecimal que enviamos.

Luego, desde la otra PC, abrimos también el DEBUG y teclearemos la instruccion IN:

- I 03F8

Con esto, leeremos el valor que enviamos desde PC 1. Luego desde esta PC 2, enviamos un valor y ahora vamos a la otra PC 1 y recogemos el dato. Si todo salio correcto, ya estamos listos para pasar al siguiente paso.

El ejercicio consistirá en que desde la PC 1 enviemos datos aleatorios, con la particularidad de que se envie un cierto “codigo” que simule un equipo del 1 al 6 y que desde la PC 2 observemos el valor de ese equipo. Es decir, si desde la PC 1 enviamos el valor “5368″ en la PC 2 recogeremos ese valor y tomaremos el primer digito que es 5 correspondiente el Equipo 5 a simular con un valor de 368. Luego entonces, estableceremos el 368 como valor de un ProgressBar que corresponda al Equipo 5.

Entonces, necesitamos dos programas, uno que enviara los datos, y otro programa que los reciba. El que recibe los datos, constará de un formulario con 6 ProgressBar, de esta forma, la PC1 estará enviando datos cada segundo, la PC2 los estará recibiendo e ira “graficando” en los ProgressBar dicho valor, según el número de equipo corresponda.

El código referente al programa que enviará los datos es:

Ahora, el otro programa que deberemos ejecutar en la PC que reciba los datos, es como sigue:

Dicho código debe ir en el evento Tick de un Timer. Obviamente, en el evento Load y Closing del Formulario deberemos poner el mismo codigo para abrir el Puerto COM1. Ah y por si no se han dado cuenta, hay que agregar los 6 ProgressBar en el formulario.

Finalmente ya solo resta ejecutar el programa que enviará los datos y luego ejecutar el que los recibirá y listo!!! Ya tenemos a dos computadoras comunicandosé por el puerto serie mediante un sencillo programa que hemos hecho en Visual Basic 2005.

Reciban un cordial saludo!!

Windows Vista y Linux

La verdad no sabia que titulo poner y no se me ocurrio algo mejor.

Se tiene la idea no del todo cierta que Linux es un OS dificil. Hace unos días, observaba a unos compañeros mios que estan realizando su servicio social en el área de Mantenimiento del Centro de Computo de mi escuela, como estaban batallando con algunas portatiles que les llevaron y tenian Windows Vista.

Era algo gracioso que cada vez que volteaba a verlos, les aparecia un feo cuadro de error, al parecer tenian problemas con los controladores y no se que más cosas. Estaban batallando muy enserio, parece que su Windows Vista les estaba dando muchos problemas.

Afortunadamente en Linux cada vez existen menos problemas de este tipo, generalmente las distribuciones actuales, detectan casi todo el hardware, de hecho al instalar alguna distro de Linux en algúna portatil reciente, lo más probable es que Linux les detecte todo su HW y contrario a lo que pasa con Windows, no tienen que perder su tiempo en estar instalando controladores y si alguno faltará, muchas distros (como mandriva y ubuntu 7.10) traen un asistente de configuración con ndiswrapper en el cual unicamente deben seleccionar el controlador de windows (.inf ) y este programa les sacara el controlador para Linux y todo con un asistente!! Así que me parece que Linux ya comenzano a marcar una distancia importante en este aspecto frente a Windows, con todo y que los fabricantes NO ofrecen drivers para Linux, ah sido la comunidad de usuarios los encargados de crearse estos drivers open source.

Otra cosa graciosa que me paso es que algunos de mis compañeritos, se sienten muy bien con su Antivirus, hasta dejaban a la vista de todos la ventanita de su antivirus analizando su equipo con Vista, ya solo faltaba un letrero donde dijeran “hey miren todos que bonito se ve mi Antivirus corriendo en Windows VIsta y miren que efectivo es que me detecto más de 100 virus!!!!” No lo dijeron, pero estoy seguro que ganas no les faltaba de decirlo y lo peor es que de haberlo dicho, seguramente seria con gran euforia, emoción, orgullo!!!!… pero… orgulllo de que? de decir que su OS es tan vulnerable que tiene más de 100 virus?

No se por qué, pero he notado que algo les da por presumir sus Antivirus, cortafuegos, y toda una Suite de seguridad, como que al tener todas esas cosas, sienten que son todos unos conocedores y expertos en seguridad. Ya muchos de mis compañeros saben que uso Linux (aunque no estoy peleado con Windows, simplemente señalo sus carencias, pero no soy un fanático que me dedico a bombardear de criticas a este OS propietario).

En fin, ha sido una semana algo graciosa al ver como unos compañeros mios han tenido infinidad de problemas con Windows Vista. Yo el único problema que llegue a tener fué cuando recien inicie en Linux, use Ubuntu 6.10 y no me detecto mi inalambrica, fué un poco frustrante al principio por que no sabia que hacer, luego me enteré que existia ndiswrapper y más adelante supe que en Ubuntu 7.10 ya traia un asistente para esar el controlador de windows y todo de manera muy fácil, con puros simples clicks.

De ahi en fuera no he tenido problemas con drivers, ni con virus, ni con baja de rendimiento notable como sucede en windows que después de un tiempo el OS se vuelve muy lento. Hasta ahora Linux me ha funcionado muy bien y siempre he encontrado alternativas libres a los propgramas comerciales para la plataforma Windows.

Y claro, el hecho que Linux sea estable y seguro, no indica que tu sistema jamás te envie un error X o en algún momento determinado tu sistema se congele principalmente si estas usando efectos 3D, pero nada que ver con los errores frecuentes de Windows. Aunque he leido que Vista mejoro en cuanto a seguridad y estabilidad, si esto es cierto, pues que bueno!!

Estos últimos días, 3 compañeras y 2 compañeros, me pidieron el disco de Mandriva pues querian instalarlo en su máquina! Esperemos que su estancia en Linux sea agradable como lo ha sido la mia!

saludos!!

Parámetros en Java: ¿Valor o Referencia?

Hoy revisando algunos libros de Java, me encontré con algunos en donde sorprendentemente dicen una GRAN mentira. De hecho, muchos sitios en internet manejan que el paso de parámetros en Java se hace de dos formas:

  1. Si se tratan de tipos primitivos como int, double, etc. el paso se da por valor o copia.
  2. Si se tratan de Objetos (en realidad son referencias a objetos) entonces el paso de valor se hace por referencia.

NO hay nada más equivocado que esta idea, lo lamentable es que incluso sean los autores de libros, los “conocedores” y expertos de la materia los que caigan en tan infantil error. Uno de los autores de los que hablo es un Español muy conocido cuyo nombre empieza con F…. otro autor que me parece es mexicano y si bien recuerdo es de la misma editorial que el primer autor que menciono y cuyo apellido también empieza con la letra F afirma del mismo modo que Java hace el paso de parámetros por referencia y cuyo libro/tutorial esta pegado en la página de un Instituto Tecnológico de aqui en México.

Y bueno ni se digan de varias páginas en donde se habla de lo mismo, por ejemplo: http://es.wikibooks.org

En fin, encontré un artículo que me parecio interesante: http://jpangamarca.wordpress.com/cafe-java/en-java-el-paso-de-parametros-es-por-valor/

donde desmiente ese mito de que Java hace el paso de parámetros por Referencia, dejando en claro que únicamente se hace por VALOR.

Si alguno tiene dudas sobre este tema de las Referencias de Objetos, comentela aqui y en la medida de mi tiempo trataré de brindarle alguna explicación.

Saludos!!