Informe_Procesador_Imagenes

119
FACULTAD DE CIENCIAS FISICAS, QUIMICAS Y MATEMATICAS CARRERA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS TEMA: CURSO : Robótica y Procesamiento de Señal DOCENTE : Ing. José Pillco ALUMNOS : - Rivero Túpac Edith Pamela 062854 - Flores Carbajal José Carlos Envío de un fotografía a través de una comunicación de Celular a PC

Transcript of Informe_Procesador_Imagenes

Page 1: Informe_Procesador_Imagenes

FACULTAD DE CIENCIAS FISICAS, QUIMICAS Y MATEMATICAS

CARRERA PROFESIONAL DE INGENIERÍA INFORMATICA Y DE SISTEMAS

TEMA:

CURSO : Robótica y Procesamiento de Señal

DOCENTE : Ing. José Pillco ALUMNOS :

- Rivero Túpac Edith Pamela 062854

- Flores Carbajal José Carlos 062842

- Álvarez Carbajal Giomar 060564

CUSCO – PERÚ

2012

Envío de un fotografía a través de una comunicación de Celular a PC

Page 2: Informe_Procesador_Imagenes

BLUETOOTH

Bluetooth es un estándar de factor global que identifica un conjunto de protocolos que facilitan la comunicación inalámbrica entre diferentes tipos de dispositivos electrónicos.

Bluetooth es una tecnología de radio de corto alcance, que permite conectividad inalámbrica entre dispositivos remotos. Se diseñó pensando básicamente en tres objetivos:

• Pequeño tamaño.• Mínimo consumo.• Bajo precio.

Bluetooth opera en la banda libre de radio ISM a 2.4 Ghz. Su máxima velocidad de transmisión de datos es de 1 Mbps. El rango de alcance Bluetooth depende de la potencia empleada en la transmisión. La mayor parte de los dispositivos que usan Bluetooth transmiten con una potencia nominal de salida de 0 dBm, lo que permite un alcance de unos 10 metros en un ambiente libre de obstáculos.

Los paquetes de datos están protegidos por un esquema ARQ (repetición automática de consulta), en el cual los paquetes perdidos son automáticamente retransmitidos.

Page 3: Informe_Procesador_Imagenes

CLASIFICACIÓN

Estos dispositivos se clasifican en referencia a su potencia de transmisión, siendo totalmente compatibles los dispositivos de una clase con los de las otras.

ClasePotencia máxima permitida(mW)

Potencia máxima permitida(dBm)

Rango(aproximado)

Clase 1 100 mW 20 dBm ~100 metrosClase 2 2.5 mW 4 dBm ~25 metrosClase 3 1 mW 0 dBm ~1 metro

Versiones

Bluetooth v.1.1.- En 1994, Ericsson inició un estudio para investigar la viabilidad de una nueva interfaz de bajo costo y consumo para la interconexión vía radio (eliminando así cables) entre dispositivos como teléfonos móviles y otros accesorios.

Bluetooth v.1.2.- A diferencia de la 1.1, provee una solución inalámbrica complementaria para co-existir Bluetooth y Wi-Fi en el espectro de los 2.4 GHz, sin interferencia entre ellos. La versión 1.2 usa la técnica "Adaptive Frequency Hopping (AFH)", que ejecuta una transmisión más eficiente y un cifrado más seguro.

Bluetooth v.2.0.- Creada para ser una especificación separada, principalmente incorpora la técnica "Enhanced Data Rate" (EDR) que le permite mejorar las velocidades de transmisión en hasta 3Mbps a la vez que intenta solucionar algunos errores de la especificación 1.2.

Bluetooth v.2.1.- simplifica los pasos para crear la conexión entre dispositivos, además el consumo de potencia es 5 veces menor.

Bluetooth v3.0.- Aumenta considerablemente la velocidad de transferencia. La idea es que el nuevo Bluetooth trabaje con WiFi, de tal manera que sea posible lograr mayor velocidad en los smartphones.

Pila de Protocolos

Uno de los principales objetivos de la tecnología bluetooth es conseguir que aplicaciones de fabricantes mantengan una comunicación fluida. Para diferentes conseguirlo, receptor y transmisor deben ejecutarse sobre la misma pila de protocolos.

Page 4: Informe_Procesador_Imagenes

Figura 1. Pila de Protocolos

La pila está constituida por dos clases de protocolos. Una primera clase llamada de protocolos específicos que implementa los protocolos propios de Bluetooth. Y una segunda clase formada por el conjunto de protocolos adoptados de otras especificaciones. Esta división en clases en el diseño de la pila de protocolos de Bluetooth permite aprovechar un conjunto muy amplio de ventajas de ambas. Por un lado, al implementar protocolos específicos de Bluetooth permite utilizar los beneficios que aporta la adopción de la tecnología Bluetooth. Por otro lado la utilización de protocolos no específicos ofrece la ventaja de la interacción de esta tecnología con protocolos comerciales ya existentes. Así como la posibilidad de que Bluetooth este abierto a implementaciones libres o nuevos protocolos de aplicación de uso común. La pila de protocolos se puede dividir en cuatro capas lógicas:

Núcleo de Bluetooth: Radio, Banda Base, LMP, L2CAP, SDP Sustitución de cable: RFCOMM Protocolos adoptados: PPP, UDP, TCP, IP, OBEX, WAP, IRMC, WAE Control de telefonía: TCS-binary, AT-Commands Pese a que el núcleo de bluetooth fue desarrollado en su totalidad por la

SIG, algunos protocolos como RFCOMM y TCS-binary han sido desarrollados siguiendo las recomendaciones de otras instituciones de telecomunicaciones.

EL CANAL

Bluetooth utiliza un sistema FH/TDD (salto de frecuencia/división de tiempo duplex), en el que el canal queda dividido en intervalos de 625 μs, llamados slots, donde cada salto de frecuencia es ocupado por un slot.

Dos o más unidades Bluetooth pueden compartir el mismo canal dentro de una piconet (pequeña red que establecen automáticamente los terminales Bluetooth para comunicarse entre si), donde una unidad actúa como maestra, controlando el tráfico de datos en la piconet que se genera entre las demás unidades, donde éstas actúan como esclavas, enviando y recibiendo señales hacia el maestro.

Page 5: Informe_Procesador_Imagenes

DATAGRAMA BLUETOOTH

La información que se intercambia entre dos unidades Bluetooth se realiza mediante un conjunto de slots que forman un paquete de datos. Cada paquete comienza con un código de acceso de 72 bits, que se deriva de la identidad maestra, seguido de un paquete de datos de cabecera de 54 bits. Éste contiene importante información de control, como tres bits de acceso de dirección, tipo de paquete, bits de control de flujo, bits para la retransmisión automática de la pregunta, y chequeo de errores de campos de cabecera. La dirección del dispositivo es en forma hexadecimal. Finalmente, el paquete que contiene la información, que puede seguir al de la cabecera, tiene una longitud de 0 a 2745 bits.

Datagramas Bluetooth

En cualquier caso, cada paquete que se intercambia en el canal está precedido por el código de acceso. Los receptores de la piconet comparan las señales que reciben con el código de acceso, si éstas no coinciden, el paquete recibido no es considerado como válido en el canal y el resto de su contenido es ignorado.

PICONETS

Como hemos citado anteriormente si un equipo se encuentra dentro del radio de cobertura de otro, éstos pueden establecer conexión entre ellos. Cada dispositivo tiene una dirección única de 48 bits, basada en el estándar IEEE 802.11 para WLAN. En principio sólo son necesarias un par de unidades con las mismas características de hardware para establecer un enlace. Dos o más unidades Bluetooth que comparten un mismo canal forman una piconet.

JAVA

Sun, dispuesto a proporcionar las herramientas necesarias para cubrir las necesidades de todos los usuarios, creó distintas versiones de Java de acuerdo a las necesidades de cada uno. Según esto nos encontramos con que el paquete Java 2 lo podemos dividir en 3 ediciones distintas. J2SE (Java Standard Edition) orientada al desarrollo de aplicaciones

Page 6: Informe_Procesador_Imagenes

independientes de la plataforma, J2EE (Java Enterprise Edition) orientada al entorno empresarial y J2ME (Java Micro Edition) orientada a dispositivos con capacidades restringidas. Veamos cuáles son las características de cada una de las versiones:

Java 2 Platform, Standard Edition (J2SE):

Esta edición de Java es la que en cierta forma recoge la iniciativa original del lenguaje Java.

Esta versión de Java contiene el conjunto básico de herramientas usadas para desarrollar Java Applets, así como las APIs orientadas a la programación de aplicaciones de usuario final: Interfaz gráfica de usuario, multimedia, redes de comunicación, etc.

Java 2 Platform, Enterprise Edition (J2EE):

Esta versión está orientada al entorno empresarial. El software empresarial tiene unas características propias marcadas: está pensado no para ser ejecutado en un equipo, sino para ejecutarse sobre una red de ordenadores de manera distribuida y remota mediante EJBs (Enterprise Java Beans).

Java 2 Platform, Micro Edition (J2ME):

Esta versión de Java está enfocada a la aplicación de la tecnología Java en dispositivos electrónicos con capacidades computacionales y gráficas muy reducidas, tales como teléfonos móviles, PDAs o electrodomésticos inteligentes. Esta edición tiene unos componentes básicos que la diferencian de las otras versiones, como el uso de una máquina virtual denominada KVM (Kilo Virtual Machine, debido a que requiere sólo unos pocos Kilobytes de memoria para funcionar) en vez del uso de la JVM clásica, inclusión de un pequeño y rápido recolector de basura.

Page 7: Informe_Procesador_Imagenes

Figura 1.1 Arquitectura de la plataforma Java 2 de Sun

ESTABLECIMIENTO DE LA CONEXIÓN

La conexión con un dispositivo, se hace mediante un mensaje page. Si la dirección es desconocida, antes del mensaje page se necesitara un mensaje inquiry. Antes de que se produzca ninguna conexión, se dice que todos los dispositivos están en modo standby.

Un dispositivo en modo standby se despierta cada 1.28 segundos para escuchar posibles mensajes page/inquiry. Cada vez que un dispositivo se despierta, escucha una de las 32 frecuencias de salto definidas. Un mensaje de tipo page, será enviado en 32 frecuencias diferentes. Primero el mensaje es enviado en las primeras 16 frecuencias (128 veces), y si no se recibe respuesta, el maestro mandará el mensaje page en las 16 frecuencias restantes (128 veces). El tiempo máximo de intento de conexión es de 2.56 segundos.

Estados

En el estado conectado, el dispositivo Bluetooth puede encontrarse en varios modos de operación:

Active mode

En este modo, el dispositivo Bluetooth participa activamente en el canal.

Sniff mode

En este modo, el tiempo de actividad durante el cual el dispositivo esclavo escucha se reduce. Esto significa que el maestro sólo puede iniciar una transmisión en unos slots de tiempo determinados.

Hold mode

En el estado conectado, el enlace con el esclavo puede ponerse en espera. Durante este modo, el esclavo puede hacer otras cosas, como escanear en busca de otros dispositivos, atender otra piconet, etc.

Park mode

En este estado, el esclavo no necesita participar en la piconet, pero aún quiere seguir sincronizado con el canal. Deja de ser miembro de la piconet. Esto es

Page 8: Informe_Procesador_Imagenes

útil por si hay más de siete dispositivos que necesitan participar ocasionalmente en la piconet.

APIs JAVA PARA BLUETOOTH

Mientras que el hardware Bluetooth había avanzado mucho, hasta hace relativamente poco no había manera de desarrollar aplicaciones java Bluetooth hasta que apareció JSR 82, que estandarizó la forma de desarrollar aplicaciones Bluetooth usando Java. Ésta esconde la complejidad del protocolo Bluetooth detrás de unos APIs que permiten centrarse en el desarrollo en vez de los detalles de bajo nivel del Bluetooth.

Estos APIs para Bluetooth están orientados para dispositivos que cumplan las siguientes características:

Al menos 512K de memoria libre (ROM y RAM) (las aplicaciones necesitan memoria adicional).

Conectividad a la red inalámbrica Bluetooth. Que tengan una implementación del J2ME CLDC.

JSR 82

El objetivo de ésta especificación era definir un API estándar abierto, no propietario que pudiera ser usado en todos los dispositivos que implementen J2ME. Por consiguiente fue diseñado usando los APIs J2ME y el entorno de trabajo CLDC/MIDP.

Page 9: Informe_Procesador_Imagenes

Los APIs JSR 82 son muy flexibles, ya que permiten trabajar tanto con aplicaciones nativas Bluetooth como con aplicaciones Java Bluetooth.

El API intenta ofrecer las siguientes capacidades:

• Registro de servicios.• Descubrimiento de dispositivos y servicios.• Establecer conexiones RFCOMM, L2CAP y OBEX entre dispositivos.• Usar dichas conexiones para mandar y recibir datos (las comunicaciones

de voz no• están soportadas).• Manejar y controlar las conexiones de comunicación.• Ofrecer seguridad a dichas actividades.

Los APIs Java para Bluetooth definen dos paquetes que dependen del paquete CLDC javax.microedition.io:

javax.bluetooth. javax.obex.

PROGRAMACION DE APLICACIONES PARA BLUETOOTH

La anatomía de una aplicación Bluetooth está dividida en cuatro partes:

• Inicialización de la pila.• Descubrimiento de dispositivos y servicios.• Manejo del dispositivo.• Comunicación.

INICIALIZACION

B CC (Bluetooth Control Center)

El BCC previene que una aplicación pueda perjudicar a otra. El BCC es un conjunto de capacidades que permiten al usuario o al OEM2 resolver peticiones conflictivas de aplicaciones definiendo unos valores específicos para ciertos parámetros de la pila Bluetooth.

El BCC puede ser una aplicación nativa, una aplicación en un API separado, o sencillamente un grupo de parámetros fijados por el proveedor que no pueden ser cambiados por el usuario. Hay que destacar, que el BCC no es una clase o un interfaz definido en esta especificación, pero es una parte importante de su arquitectura de seguridad.

Inicialización de la pila

La pila Bluetooth es la responsable de controlar el dispositivo Bluetooth, por lo que es necesario inicializarla antes de hacer cualquier otra cosa. El proceso de

Page 10: Informe_Procesador_Imagenes

inicialización consiste en un número de pasos cuyo propósito es dejar el dispositivo listo para la comunicación inalámbrica.

Desafortunadamente, la especificación deja la implementación del BCC a los vendedores, y cada vendedor maneja la inicialización de una manera diferente. En un dispositivo puede haber una aplicación con un interfaz GUI, y en otra puede ser una serie de configuraciones que no pueden ser cambiados por el usuario.

DISCOVERY

Dado que los dispositivos inalámbricos son móviles, necesitan un mecanismo que permita encontrar, conectar, y obtener información sobre las características de dichos dispositivos.

En este apartado, vamos a tratar como el API de Bluetooth permite realizar todas estas tareas.

Descubrir Dispositivos (Device discovery)

Cualquier aplicación puede obtener una lista de dispositivos a los que es capaz de encontrar, usando, o bien startInquiry() (no bloqueante) o retrieveDevices() (bloqueante). startInquiry() requiere que la aplicación tenga especificado un listener, el cual es notificado cuando un nuevo dispositivo es encontrado después de haber lanzado un proceso de búsqueda. Por otra parte, si la aplicación no quiere esperar a descubrir dispositivos (o a ser descubierta por otro dispositivo) para comenzar, puede utilizar retrieveDevices(), que devuelve una lista de dispositivos encontrados en una búsqueda previa o bien unos que ya conozca por defecto.

Descubrir Servicios (Service Discovery)

Este API no da soporte para buscar servicios que estén ubicados en el propio dispositivo.

Para descubrir los servicios disponibles en un dispositivo servidor, el cliente primero debe recuperar un objeto que encapsule funcionalidad SDAP5 (SDP6 + GAP7, se verá más adelante). Este objeto es del tipo DiscoveryAgent, cuyo pseudocódigo viene dado por:

DiscoveryAgent da = LocalDevice.getLocalDevice().getDiscoveryAgent();

Clases del Service Discovery:

class javax.bluetooth.UUID

Esta clase encapsula enteros sin signo que pueden ser de 16, 32 ó 128 bits de longitud. Estos enteros se usan como un identificador universal cuyo valor representa un atributo del servicio.

Page 11: Informe_Procesador_Imagenes

sólo los atributos de un servicio representados con UUID están representados en la Bluetooth SDP.

class javax.bluetooth.DataElement

Esta clase contiene varios tipos de datos que un atributo de servicio Bluetooth puede usar. Algunos de estos son:

• String

• boolean

• UUID

• Enteros con signo y sin signo, de uno, dos, cuatro o seis bytes de longitud

• Secuencias de cualquiera de los tipos anteriores.

Esta clase además presenta una interfaz que permite construir y recuperar valores de un atributo de servicio.

class javax.bluetooth.DiscoveryAgent

Esta clase provee métodos para descubrir servicios y dispositivos.

interface javax.bluetooth.ServiceRecord

Este interfaz define el Service Record de Bluetooth, que contiene los pares (atributo ID, valor). El atributo ID es un entero sin signo de 16 bits, y valor es de tipo DataElement. Además, este interfaz tiene un método populateRecord() para recuperar los atributos de servicio deseados (pasando como parámetro al método el ID del atributo deseado).

interface javax.bluetooth.DiscoveryListener

Este interfaz permite a una aplicación especificar un listener que responda a un evento del tipo Service Discovery o Device Discovery. Cuando un nuevo servicio es descubierto, se llama al método servicesDiscovered(), y cuando la transacción ha sido completada o cancelada se llama a serviceSearchCompleted().

Registro del Servicio

Las responsabilidades de una aplicación servidora de Bluetooth son:

1. Crear un Service Record que describa el servicio ofrecido por la aplicación.

2. Añadir el Service Record al SDDB del servidor para avisar a los clientes potenciales de este servicio.

Page 12: Informe_Procesador_Imagenes

3. Registrar las medidas de seguridad Bluetooth asociadas a un servicio.

4. Aceptar conexiones de clientes que requieran el servicio ofrecido por la aplicación.

5. Actualizar el Service Record en el SDDB del servidor si las características del servicio cambian.

6. Quitar o deshabilitar el Service Record en el SDDB del servidor cuando el servicio no está disponible.

A las tareas 1, 2, 5 y 6 se las denominan registro del servicio (Service Registration), que comprenden unas tareas relacionadas con advertir al cliente de los servicios disponibles.

COMUNICACIÓN

Para usar un servicio en un dispositivo Bluetooth remoto, el dispositivo local debe comunicarse usando el mismo protocolo que el servicio remoto. Los APIs permiten usar RFCOMM, L2CAP u OBEX como protocolo de nivel superior El Generic Connection Framework (GFC) del CLDC rovee la conexión base para la implementación de protocolos de comunicación. CLDC provee de los siguientes métodos para abrir una conexión:

Connection Connector.open(String name);

Connection Connector.open(String name, int mode);

Connection Connector.open(String name, int mode, boolean timeouts);

La implementación debe soportar abrir una conexión con una conexión URL servidora o con una conexión URL cliente, con el modo por defecto READ_WRITE.

Perfil del puerto serie (SPP)

El protocolo RFCOMM provee múltiples emulaciones de los puertos serie RS-232 entre dos dispositivos Bluetooth. Las direcciones Bluetooth de los dos puntos terminales definen una sesión RFCOMM. Una sesión puede tener más de una conexión, el número de conexiones dependerá de la implementación. Un dispositivo podrá tener más de una sesión RFCOMM en tanto que esté conectado a más de un dispositivo.

PROTOCOLO DE INTERCAMBIO DE OBJETOS (OBEX)

Este es un protocolo diseñado por el IrDA (Infrared Data Association) para intercambiar objetos entre clientes y servidores, mediante el establecimiento de una sesión OBEX. En vez de incluir esta funcionalidad en el API Bluetooth, se ha optado por extender el API OBEX y dar soporte a Bluetooth. Nosotros vamos a centrarnos únicamente en el soporte Bluetooth.

Page 13: Informe_Procesador_Imagenes

Un vistazo al API

OBEX, como HTTP, tiene métodos que le permiten pasar información adicional entre el cliente y el servidor mediante el uso de cabeceras.

J2ME (Java 2 Platform, Micro Edition)

Esta versión de Java está enfocada a la aplicación de la tecnología Java en dispositivos electrónicos con capacidades computacionales y gráficas muy reducidas, tales como teléfonos móviles, PDAs o electrodomésticos inteligentes.

Nociones básicas de J2ME

Ya hemos visto qué es Java Micro Edition y la hemos enmarcado dentro de la plataforma Java2. En este apartado vamos a ver cuales son los componentes que forman parte de esta tecnología.

• Por un lado tenemos una serie de máquinas virtuales Java con diferentes requisitos, cada una para diferentes tipos de pequeños dispositivos.

• Configuraciones, que son un conjunto de clases básicas orientadas a conformar el corazón de las implementaciones para dispositivos de características específicas. Existen 2 configuraciones definidas en J2ME:

Connected Limited Device Configuration (CLDC) enfocada a dispositivos con restricciones de procesamiento y memoria, y Connected Device

Configuration (CDC) enfocada a dispositivos con más recursos.

• Perfiles, que son unas bibliotecas Java de clases específicas orientadas a implementar funcionalidades de más alto nivel para familias específicas de dispositivos.

Un entorno de ejecución determinado de J2ME se compone entonces de una selección de:

a) Máquina virtual.

b) Configuración.

c) Perfil.

d) Paquetes Opcionales.

La CDC está basada en J2SE v1.3 e incluye varios paquetes Java de la edición estándar. Las peculiaridades de la CDC están contenidas principalmente en el paquete javax.microedition.io, que incluye soporte para comunicaciones http y basadas en datagramas.

Page 14: Informe_Procesador_Imagenes

ARQUITECTURA DE LA APLICACIÓN

La aplicación está desarrollada en 2 plataformas java J2SE y J2ME:

J2SE no tiene disponible librerías para la utilización de bluetooth es por eso que se utilizará un driver que implementará la especificación JR82

ESQUEMA DEL PROYECTO

EL proyecto asignado básicamente manda señales del computador a un dispositivo móvil mediante un enlace inalámbrico, que en este caso el bluetooth estas señales son procesadas por el computador y envía mensajes al celular y viceversa, la aplicación hará que interactúen y que el celular pueda enviar la fotografía al computador para su analisis.

A continuación se muestra los patrones con los que se trabajo:

J2ME

J2SE y J2ME

PC

Page 15: Informe_Procesador_Imagenes

Primer patrón Segundo patrón Tercer patrón

Ahora se ejecuta el Procesador de Imágenes en el Servidor y luego se ejecuta SenClient en el celular .

En seguida se muestra la imagen que se tomo con el celular:

A continuación se muestra el programa en ejecución:

Page 16: Informe_Procesador_Imagenes

Luego realizamos la conexión del celular con la PC para que muestre la imagen tomada, la cual mostrará de la siguiente manera:

Luego la imagen binarizada se encuentra en la parte inferior del NetBeans y se mostraría de la siguiente manera:

Y por ultimo llega un mensaje al celular indicando que existen dos círculos e indicando los errores que tienen respecto de los patrones:

Page 17: Informe_Procesador_Imagenes

Nota: Todo el proceso se encuentra en la página: http://www.youtube.com/watch?v=WWj-4WCTN6U

A)El código para el servidor consta en 3 partes:

1.-ProcesadorImagenes:

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package procesadorimagenes;

/**

*

* @author Edith, Giomar,Jose

*/

public class ProcesadorImagenes {

/**

* @param args the command line arguments

Page 18: Informe_Procesador_Imagenes

*/

public static void main(String[] args) {

// TODO code application logic here

//llamar a la aplicacion servidor

frmMainServer server=new frmMainServer(null, true);

server.setVisible(true);

}

}

2.-ReconocerPatron:

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package procesadorimagenes;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.color.ColorSpace;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import javax.swing.JFrame;

import java.awt.Image;

Page 19: Informe_Procesador_Imagenes

import java.awt.Toolkit;

import java.awt.image.MemoryImageSource;

import java.awt.image.PixelGrabber;

import java.io.File;

import java.util.ArrayList;

import javax.imageio.ImageIO;

import javax.swing.ImageIcon;

import javax.swing.JFileChooser;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.filechooser.FileFilter;

/**

*

* @author Edith, Giomar,Jose

*/

public class ReconocerPatron extends JFrame{

private static Image destino = null;

private static Image imagen = null;

public static void main(String args[]) {

File file=null;

// Se carga la imagen del fichero

JFileChooser selector = new JFileChooser();

//selector.addChoosableFileFilter(new FileFilter("gif","Archivos Gif"));

String lista[] = {"jpeg","jpg"};

Page 20: Informe_Procesador_Imagenes

//selector.addChoosableFileFilter(new FiltroDeArchivo(lista,"Archivos JPEG"));

selector.setDialogTitle("Abrir archivo de imagen");

selector.setDialogType(JFileChooser.OPEN_DIALOG);

int resultado = selector.showOpenDialog(null);

if(resultado == JFileChooser.APPROVE_OPTION)

{

file = selector.getSelectedFile();

}

imagen=Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath());

Convetir n=new Convetir();

destino=n.ConvertirAGrises(destino, imagen);

ReconocerPatron2("0","9");

// ReconocerPatron();

}

private static void ReconocerPatron2(String PixelBuscado,String PixelNuevo)

{

JLabel Resultado= new JLabel();

String arreglo[][];

String PixelBuscar=PixelBuscado;

String Pixelnuevo=PixelNuevo;

int contador=0;

Coversion C = new Coversion();

BufferedImage Nueva = C.toBufferedImage(destino);

Page 21: Informe_Procesador_Imagenes

Graphics g = Nueva.getGraphics();

//Agrupar

arreglo = new String[Nueva.getWidth()][Nueva.getHeight()];

for(int x=0;x<=Nueva.getWidth()-1 ;x++){

for(int y=0;y<=Nueva.getHeight()-1;y++){

String val= Integer.toHexString(Nueva.getRGB(x,y)).toString();

val=val.substring(2, val.length());

arreglo[x][y]=val;

}

}

Identificador ide=new Identificador();

String[][]MatrizSinRuidos=ide.LiberarRuidos2(arreglo);

//En esta matriz se tiene la imagen dividida en cuatro colores

// ide.Graficar(MatrizSinRuidos);

//fin de Agrupar

Grupos gr=new Grupos();

ArrayList grupos=gr.DevolverGrupos2(MatrizSinRuidos);

int NroCirculos=0;

//Analizamos cada grupos y verificamos si es un circulo

for(int i=0;i<grupos.size();i+=2)

{

String[]error=new String[1];

Circulo cir=new Circulo();

String[][] M=(String[][])grupos.get(i+1);

Page 22: Informe_Procesador_Imagenes

boolean circulo=cir.VerificarCirculo(M, PixelBuscar,error);

if(circulo)

{

NroCirculos++;

//PINTA DE COLOR AZUL LOS CIRCULOS

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);

g.setColor(Color.red);

g.drawString(error[0], A,H);

int ancho=A+M.length;

int alto=H+M[0].length;

//System.out.println("a "+ancho+" h "+alto);

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.blue);

g.fillRect(k, l, 1, 1);

}

}

}

}

//repitar si no es un circulo pero se encuentra en el area de un circulo

else

{

Page 23: Informe_Procesador_Imagenes

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);

int ancho=A+M.length;

int alto=H+M[0].length;

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.black);

g.fillRect(k, l, 1, 1);

}

}

}

}

}

JOptionPane.showMessageDialog(null,"Termino de Buscar en total fueron " + NroCirculos + " Circulos");

try {

ImageIO.write(Nueva, "jpg", new File("Resultado.png"));

} catch (IOException e) {

System.out.println("Error de escritura");

}

Resultado.setIcon(new ImageIcon("Resultado.png"));

JOptionPane.showMessageDialog(null,"Numero de Cuerpos Analizados " + grupos.size() );

Page 24: Informe_Procesador_Imagenes

JOptionPane.showMessageDialog(null,Resultado);

}

private static void ReconocerPatron()

{

JLabel Resultado= new JLabel();

String arreglo[][];

String PixelBuscar="0";

String Pixelnuevo="1";

int contador=0;

Coversion C = new Coversion();

BufferedImage Nueva = C.toBufferedImage(destino);

Graphics g = Nueva.getGraphics();

//Agrupar

arreglo = new String[Nueva.getWidth()][Nueva.getHeight()];

for(int x=0;x<=Nueva.getWidth()-1 ;x++){

for(int y=0;y<=Nueva.getHeight()-1;y++){

String val= Integer.toHexString(Nueva.getRGB(x,y)).toString();

val=val.substring(2, val.length());

arreglo[x][y]=val;

}

}

Page 25: Informe_Procesador_Imagenes

Identificador ide=new Identificador();

String[][]MatrizSinRuidos=ide.LiberarRuidos(arreglo);

//fin de Agrupar

Grupos gr=new Grupos();

ArrayList grupos=gr.DevolverGrupos(MatrizSinRuidos,PixelBuscar,Pixelnuevo);

int NroCirculos=0;

//Analizamos cada grupos y verificamos si es un circulo

for(int i=0;i<grupos.size();i+=2)

{

String[]error=new String[1];

Circulo cir=new Circulo();

String[][] M=(String[][])grupos.get(i+1);

boolean circulo=cir.VerificarCirculo(M, PixelBuscar,error);

if(circulo)

{

NroCirculos++;

//PINTA DE COLOR AZUL LOS CIRCULOS

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);//error aqui

g.setColor(Color.red);

g.drawString(error[0], A,H);

int ancho=A+M.length;

int alto=H+M[0].length;

Page 26: Informe_Procesador_Imagenes

//System.out.println("a "+ancho+" h "+alto);

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.blue);

g.fillRect(k, l, 1, 1);

}

}

}

}

//repitar si no es un circulo pero se encuentra en el area de un circulo

else

{

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);

int ancho=A+M.length;

int alto=H+M[0].length;

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.black);

g.fillRect(k, l, 1, 1);

Page 27: Informe_Procesador_Imagenes

}

}

}

}

}

JOptionPane.showMessageDialog(null,"Termino de Buscar en total fueron " + NroCirculos + " Circulos");

try {

ImageIO.write(Nueva, "jpg", new File("Resultado.png"));

} catch (IOException e) {

System.out.println("Error de escritura");

}

Resultado.setIcon(new ImageIcon("Resultado.png"));

JOptionPane.showMessageDialog(null,"Numero de Pixeles involucrados " + contador );

JOptionPane.showMessageDialog(null,Resultado);

}

}

class Reconocer{

public int ReconocerPatron(String PixelBuscado,String PixelNuevo,Image destino,JPanel panel)

{

JLabel Resultado= new JLabel();

Page 28: Informe_Procesador_Imagenes

String arreglo[][];

String PixelBuscar=PixelBuscado;

String Pixelnuevo=PixelNuevo;

int contador=0;

Coversion C = new Coversion();

BufferedImage Nueva = C.toBufferedImage(destino);

Graphics g = Nueva.getGraphics();

//Agrupar

arreglo = new String[Nueva.getWidth()][Nueva.getHeight()];

for(int x=0;x<=Nueva.getWidth()-1 ;x++){

for(int y=0;y<=Nueva.getHeight()-1;y++){

String val= Integer.toHexString(Nueva.getRGB(x,y)).toString();

val=val.substring(2, val.length());

arreglo[x][y]=val;

}

}

Identificador ide=new Identificador();

String[][]MatrizSinRuidos=ide.LiberarRuidos2(arreglo);

//En esta matriz se tiene la imagen dividida en cuatro colores

// ide.Graficar(MatrizSinRuidos);

//fin de Agrupar

Grupos gr=new Grupos();

ArrayList grupos=gr.DevolverGrupos2(MatrizSinRuidos);

Page 29: Informe_Procesador_Imagenes

int NroCirculos=0;

//Analizamos cada grupos y verificamos si es un circulo

for(int i=0;i<grupos.size();i+=2)

{

String[]error=new String[1];

Circulo cir=new Circulo();

String[][] M=(String[][])grupos.get(i+1);

boolean circulo=cir.VerificarCirculo(M, PixelBuscar,error);

if(circulo)

{

NroCirculos++;

//PINTA DE COLOR AZUL LOS CIRCULOS

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);

g.setColor(Color.red);

g.drawString(error[0], A,H);

int ancho=A+M.length;

int alto=H+M[0].length;

//System.out.println("a "+ancho+" h "+alto);

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.blue);

g.fillRect(k, l, 1, 1);

Page 30: Informe_Procesador_Imagenes

}

}

}

}

//repitar si no es un circulo pero se encuentra en el area de un circulo

else

{

String [] cood=grupos.get(i).toString().split(",");

int A= Integer.valueOf(cood[0]);

int H= Integer.valueOf(cood[1]);

int ancho=A+M.length;

int alto=H+M[0].length;

for(int k=A;k<ancho;k++){

for(int l=H;l<alto;l++){

String val= MatrizSinRuidos[k][l];

if(val.equals(PixelBuscar)){

contador++;

g.setColor(Color.black);

g.fillRect(k, l, 1, 1);

}

}

}

}

}

try {

ImageIO.write(Nueva, "jpg", new File("Resultado.png"));

} catch (IOException e) {

Page 31: Informe_Procesador_Imagenes

System.out.println("Error de escritura");

}

// Resultado.setIcon(new ImageIcon("Resultado.png"));

// JOptionPane.showMessageDialog(null,Resultado);

// mostrarImagen(new File("Resultado.png"),panel);

return NroCirculos;

}

}

class Identificador{

String MATRIZ[][];

public String[][] LiberarRuidos(String[][]matriz)

{

MATRIZ=matriz;

//ConvertirAInt();

String[][]aux=new String[MATRIZ.length][MATRIZ[0].length];

for(int i=0;i<MATRIZ.length;i++){

for(int j=0;j<MATRIZ[0].length;j++){

String val=MATRIZ[i][j];

if(val.compareTo("7fffff")<0)

{aux[i][j]="0";}

else

{aux[i][j]="9";}

}}

//Graficar(MATRIZ);

//Graficar(aux);

return aux;

Page 32: Informe_Procesador_Imagenes

}

public String[][] LiberarRuidos2(String[][]matriz)

{

MATRIZ=matriz;

//ConvertirAInt();

String[][]aux=new String[MATRIZ.length][MATRIZ[0].length];

for(int i=0;i<MATRIZ.length;i++){

for(int j=0;j<MATRIZ[0].length;j++){

String val=MATRIZ[i][j];

if(val.compareTo("3fffff")<0)//negro

{aux[i][j]="0";}

else

{

if(val.compareTo("7fffff")<0)//gris oscuro

aux[i][j]="1";

else

{

if(val.compareTo("bffffd")<0)//gris claro

aux[i][j]="2";

else

aux[i][j]="3";//blanco

}

}

}}

//Graficar(MATRIZ);

//Graficar(aux);

return aux;

Page 33: Informe_Procesador_Imagenes

}

public void Graficar(String[][] M)

{

for(int i=0;i<M.length;i++){

for(int j=0;j<M[0].length;j++){

int val= Integer.valueOf(M[i][j]);

System.out.print(val+" ");

}

System.out.print("\n");

}

}

}

class Circulo{

String [][]Matriz;

String Pixel;

String[][]Patron;

ArrayList nuevo;

ArrayList Error;

boolean VerificarCirculo(String[][]matriz,String PixelBuscado,String[]err)

{

Error=new ArrayList();

Matriz=matriz;

Pixel=PixelBuscado;

EliminarBlancos();

// Graficar(Matriz);

if(nuevo.isEmpty()||((ArrayList)nuevo.get(0)).isEmpty())

{return false;}

Page 34: Informe_Procesador_Imagenes

else

{

int ancho=nuevo.size();

int alto=((ArrayList)nuevo.get(0)).size();

File in=null;

try{in = new File("patron.png");}

catch(Exception e){JOptionPane.showConfirmDialog(null, "No se encuetra el patron");

}

Image patron=Toolkit.getDefaultToolkit().getImage(in.getAbsolutePath());

patron=patron.getScaledInstance(ancho,alto,1);

Patron=new String[ancho][alto];

ObtenerMatrizPatron(patron);

boolean p1=CompararPatron(15);

try{in = new File("patron3.png");}

catch(Exception e){JOptionPane.showConfirmDialog(null, "No se encuetra el patron");

}

patron=Toolkit.getDefaultToolkit().getImage(in.getAbsolutePath());

patron=patron.getScaledInstance(ancho,alto,1);

Patron=new String[ancho][alto];

ObtenerMatrizPatron(patron);

boolean p3=CompararPatron(5);

p1=p1!=p3;

p1=p3?p3:p1;

try{in = new File("patron2.png");}

Page 35: Informe_Procesador_Imagenes

catch(Exception e){JOptionPane.showConfirmDialog(null, "No se encuetra el patron");

}

patron=Toolkit.getDefaultToolkit().getImage(in.getAbsolutePath());

patron=patron.getScaledInstance(ancho,alto,1);

Patron=new String[ancho][alto];

ObtenerMatrizPatron(patron);

boolean p2=CompararPatron(5);

err[0]=Error.get(0).toString()+"%, "+Error.get(1).toString()+"%, "+Error.get(2).toString()+"%";

return p1!=p2;

}

}

private void EliminarBlancos()

{

nuevo=new ArrayList();

for(int i=0;i<Matriz.length;i++){

ArrayList aux=new ArrayList();

int NroPixel=0;

for(int j=0;j<Matriz[0].length;j++){

if(Matriz[i][j].equals(Pixel))

{

NroPixel++;

}

}

if(NroPixel>5)

{

Page 36: Informe_Procesador_Imagenes

for(int j=0;j<Matriz[0].length;j++){

aux.add(Matriz[i][j]);

}

nuevo.add(aux);

}

}

if(nuevo.isEmpty()||((ArrayList)nuevo.get(0)).isEmpty())

{}

else

ReagruparMatriz(nuevo);

nuevo=new ArrayList();

for(int i=0;i<Matriz[0].length;i++){

ArrayList aux=new ArrayList();

int NroPixel=0;

for(int j=0;j<Matriz.length;j++){

if(Matriz[j][i].equals(Pixel))

{

NroPixel++;

}

}

if(NroPixel>5)

{

for(int j=0;j<Matriz.length;j++){

aux.add(Matriz[j][i]);

Page 37: Informe_Procesador_Imagenes

}

nuevo.add(aux);

}

}

if(nuevo.isEmpty()||((ArrayList)nuevo.get(0)).isEmpty())

{}

else

ReagruparMatriz(nuevo);

//Graficar(Matriz);

}

private void ObtenerMatrizPatron(Image patron)

{

String arreglo[][];

Coversion C = new Coversion();

BufferedImage Nueva = C.toBufferedImage(patron);

Graphics g = Nueva.getGraphics();

//Agrupar

arreglo = new String[Nueva.getWidth()][Nueva.getHeight()];

for(int x=0;x<=Nueva.getWidth()-1 ;x++){

for(int y=0;y<=Nueva.getHeight()-1;y++){

String val= Integer.toHexString(Nueva.getRGB(x,y)).toString();

val=val.substring(2, val.length());

arreglo[x][y]=val;

}

Page 38: Informe_Procesador_Imagenes

}

Identificador ide=new Identificador();

Patron=ide.LiberarRuidos(arreglo);

//Graficar(Patron);

}

private void Graficar(String[][] M)

{

for(int i=0;i<M.length;i++){

for(int j=0;j<M[0].length;j++){

int val= Integer.valueOf(M[i][j]);

System.out.print(val+" ");

}

System.out.print("\n");

}

}

private void ReagruparMatriz(ArrayList matriz)

{

int ancho=matriz.size();

int alto=((ArrayList)matriz.get(0)).size();

Matriz=new String[ancho][alto];

for(int i=0;i<ancho;i++)

{

for(int j=0;j<alto;j++)

{

String elem=((ArrayList)matriz.get(i)).get(j).toString();

Matriz[i][j]=elem;

}

Page 39: Informe_Procesador_Imagenes

}

}

private boolean CompararPatron(int GradoDeError)

{

int Erro=0;

int NroPixels=Patron.length*Patron[0].length;

for(int i=0;i<Patron.length;i++)

{

for(int j=0;j<Patron[0].length;j++)

{

// if(Matriz[i][j].equals(Pixel)&&Patron[i][j].equals("0"))

// {

// }

// else

// {

// if(!Patron[i][j].equals("0"))

// {Erro++;}

// }

if(!Patron[i][j].equals(Matriz[i][j]))

{Erro++;}

}

}

int ErrorPorcentual=((Erro*100)/NroPixels);

Error.add(ErrorPorcentual);

// JOptionPane.showMessageDialog(null, "Grado de Error :"+ErrorPorcentual+"%");

// System.out.println("Grado de Error :"+ErrorPorcentual+"%");

Page 40: Informe_Procesador_Imagenes

if(ErrorPorcentual>GradoDeError)

return false;

else

return true;

}

}

class Coversion {

BufferedImage toBufferedImage(Image image) {

if( image instanceof BufferedImage ) {

return( (BufferedImage)image );

} else {

image = new ImageIcon(image).getImage();

BufferedImage bufferedImage = new BufferedImage(

image.getWidth(null),

image.getHeight(null),

BufferedImage.TYPE_INT_RGB );

Graphics g = bufferedImage.createGraphics();

g.drawImage(image,0,0,null);

g.dispose();

return( bufferedImage );

}

}

}

Page 41: Informe_Procesador_Imagenes

class Grupos{

String[][] MATRIZ;

boolean[][] recorrido;

ArrayList Grupos=new ArrayList();

ArrayList Grupo=new ArrayList();

public ArrayList DevolverGrupos(String[][] Matriz,String PixelBuscado,String PixelNuevo)

{

Copiar(Matriz);

recorrido=new boolean[MATRIZ.length][MATRIZ[0].length];

for(int i=0;i<MATRIZ.length;i++)

{

for(int j=0;j<MATRIZ[0].length;j++)

{

if(MATRIZ[i][j].equals(PixelBuscado)&&!recorrido[i][j])

{

// Graficar(MATRIZ);

BuscarVecinos(i, j, PixelNuevo, PixelBuscado);

String[][] aux=AnalizarRecorrido(PixelNuevo,PixelBuscado);

if(aux.length>3&&aux[0].length>3)

{

AnalizarPuntoInicial(i, j, aux,PixelBuscado, Grupos);

Grupos.add(aux);

}

recorrido=new boolean[MATRIZ.length][MATRIZ[0].length];

}

}

Page 42: Informe_Procesador_Imagenes

}

return Grupos;

}

public ArrayList DevolverGrupos2(String[][] Matriz)

{

String PixelNuevo="9";

String PixelBuscado="0";

Copiar(Matriz);

for(int x=0;x<4;x++)

{

recorrido=new boolean[MATRIZ.length][MATRIZ[0].length];

PixelBuscado= String.valueOf(x);

for(int i=0;i<MATRIZ.length;i++)

{

for(int j=0;j<MATRIZ[0].length;j++)

{

if(MATRIZ[i][j].equals(PixelBuscado)&&!recorrido[i][j])

{

BuscarVecinos(i, j, PixelNuevo, PixelBuscado);

String[][] aux=AnalizarRecorrido(PixelNuevo,"0");

if(aux.length>3&&aux[0].length>3)

{

AnalizarPuntoInicial(i, j, aux,"0", Grupos);

Grupos.add(aux);

}

recorrido=new boolean[MATRIZ.length][MATRIZ[0].length];

}

Page 43: Informe_Procesador_Imagenes

}

}

}

return Grupos;

}

private void Copiar(String [][] g)

{

MATRIZ=new String[g.length][g[0].length];

for(int i=0;i<g.length;i++)

{

for(int j=0;j<g[0].length;j++)

{

MATRIZ[i][j]=g[i][j];

}

}

}

private void AnalizarPuntoInicial(int x,int y,String[][] matriz,String ValorBuscado,ArrayList gru)

{

if(matriz[0][0].equals(ValorBuscado))

{gru.add(x+","+y);}

else

{

int nroespacios=0;

for(int i=0;i<matriz[0].length;i++)

{

Page 44: Informe_Procesador_Imagenes

if(matriz[0][i].equals(ValorBuscado))

{break;}

else

nroespacios++;

}

y=y-nroespacios;

gru.add(x+","+y);

}

}

private String[][] AnalizarRecorrido(String ValNuevo,String ValBuscado)

{

recorrido=EliminarBlancos(recorrido);

int ancho=recorrido.length;

int alto=recorrido[0].length;

String[][] grupo=new String[ancho][alto];

for(int i=0;i<ancho;i++)

{

for(int j=0;j<alto;j++)

{

if(recorrido[i][j])

{grupo[i][j]=ValBuscado;}

else{grupo[i][j]=ValNuevo;}

}

}

return grupo;

}

private boolean [][] EliminarBlancos(boolean [][] Matriz)

Page 45: Informe_Procesador_Imagenes

{

ArrayList nuevo=new ArrayList();

for(int i=0;i<Matriz.length;i++){

ArrayList aux=new ArrayList();

int NroPixel=0;

for(int j=0;j<Matriz[0].length;j++){

if(Matriz[i][j]==true)

{

NroPixel++;

}

}

if(NroPixel>0)

{

for(int j=0;j<Matriz[0].length;j++){

aux.add(Matriz[i][j]);

}

nuevo.add(aux);

}

}

Matriz=ReagruparMatriz(nuevo,Matriz);

nuevo=new ArrayList();

for(int i=0;i<Matriz[0].length;i++){

ArrayList aux=new ArrayList();

Page 46: Informe_Procesador_Imagenes

int NroPixel=0;

for(int j=0;j<Matriz.length;j++){

if(Matriz[j][i]==true)

{

NroPixel++;

}

}

if(NroPixel>0)

{

for(int j=0;j<Matriz.length;j++){

aux.add(Matriz[j][i]);

}

nuevo.add(aux);

}

}

Matriz=ReagruparMatriz2(nuevo,Matriz);

return Matriz;

//Graficar(Matriz);

}

private boolean [][] ReagruparMatriz(ArrayList matriz,boolean [][] Matriz)

{

int ancho=matriz.size();

int alto=((ArrayList)matriz.get(0)).size();

Matriz=new boolean[ancho][alto];

for(int i=0;i<ancho;i++)

Page 47: Informe_Procesador_Imagenes

{

for(int j=0;j<alto;j++)

{

String s=((ArrayList)matriz.get(i)).get(j).toString();

if(s.equals("true"))

Matriz[i][j]=true;

else

Matriz[i][j]=false;

}

}

return Matriz;

}

private boolean [][] ReagruparMatriz2(ArrayList matriz,boolean [][] Matriz)

{

int ancho=((ArrayList)matriz.get(0)).size();

int alto=matriz.size();

Matriz=new boolean[ancho][alto];

for(int i=0;i<ancho;i++)

{

for(int j=0;j<alto;j++)

{

String s=((ArrayList)matriz.get(j)).get(i).toString();

if(s.equals("true"))

Matriz[i][j]=true;

else

Matriz[i][j]=false;

}

Page 48: Informe_Procesador_Imagenes

}

return Matriz;

}

private void Graficar(String[][] M)

{

for(int i=0;i<M.length;i++){

for(int j=0;j<M[0].length;j++){

System.out.print(M[i][j]+" ");

}

System.out.print("\n");

}

System.out.print("\n");

}

// private void BuscarVecino(int x,int y,String ValorNuevo,String ValorBuscado){

// if(!recorrido[x][y]&&MATRIZ[x][y].equals(ValorBuscado))

// {

// MATRIZ[x][y]=ValorNuevo;

// recorrido[x][y]=true;

// if(y>0&&!recorrido[x][y-1]){

// BuscarVecino(x,y-1,ValorNuevo,ValorBuscado);

// }

// if(y>0&&x>0&&!recorrido[x-1][y-1]){

// BuscarVecino(x-1,y-1,ValorNuevo,ValorBuscado);

// }

// if(x>0&&!recorrido[x-1][y]){

// BuscarVecino(x-1,y,ValorNuevo,ValorBuscado);

// }

Page 49: Informe_Procesador_Imagenes

// if(x>0&&(y+1)<MATRIZ[0].length&&!recorrido[x-1][y+1]){

// BuscarVecino(x-1,y+1,ValorNuevo,ValorBuscado);

// }

// if((y+1)<MATRIZ[0].length&&!recorrido[x][y+1]){

// BuscarVecino(x,y+1,ValorNuevo,ValorBuscado);

// }

// if((y+1)<MATRIZ[0].length&&(x+1)<MATRIZ.length&&!recorrido[x+1][y+1]){

// BuscarVecino(x+1,y+1,ValorNuevo,ValorBuscado);

// }

// if((x+1)<MATRIZ.length&&!recorrido[x+1][y]){

// BuscarVecino(x+1,y,ValorNuevo,ValorBuscado);

// }

// if((x+1)<MATRIZ.length&&y>0&&!recorrido[x+1][y-1]){

// BuscarVecino(x+1,y-1,ValorNuevo,ValorBuscado);

// }

// }

// }

private void BuscarVecinos(int a,int b,String ValorNuevo,String ValorBuscado){

Grupo=new ArrayList();

Grupo.add(a+","+b);

MATRIZ[a][b]=ValorNuevo;

recorrido[a][b]=true;

int i=0;

int nroPixeles=1;

while(i<nroPixeles)

Page 50: Informe_Procesador_Imagenes

{

String[] cord=Grupo.get(i).toString().split(",");

int x= Integer.valueOf(cord[0]);

int y= Integer.valueOf(cord[1]);

if(y>0&&!recorrido[x][y-1]&&MATRIZ[x][y-1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x][y-1]=ValorNuevo;

recorrido[x][y-1]=true;

Grupo.add(x+","+(y-1));

}

if(y>0&&x>0&&!recorrido[x-1][y-1]&&MATRIZ[x-1][y-1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x-1][y-1]=ValorNuevo;

recorrido[x-1][y-1]=true;

Grupo.add((x-1)+","+(y-1));

}

if(x>0&&!recorrido[x-1][y]&&MATRIZ[x-1][y].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x-1][y]=ValorNuevo;

recorrido[x-1][y]=true;

Grupo.add((x-1)+","+y);

}

if(x>0&&(y+1)<MATRIZ[0].length&&!recorrido[x-1][y+1]&&MATRIZ[x-1][y+1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x-1][y+1]=ValorNuevo;

Page 51: Informe_Procesador_Imagenes

recorrido[x-1][y+1]=true;

Grupo.add((x-1)+","+(y+1));

}

if((y+1)<MATRIZ[0].length&&!recorrido[x][y+1]&&MATRIZ[x][y+1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x][y+1]=ValorNuevo;

recorrido[x][y+1]=true;

Grupo.add(x+","+(y+1));

}

if((y+1)<MATRIZ[0].length&&(x+1)<MATRIZ.length&&!recorrido[x+1][y+1]&&MATRIZ[x+1][y+1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x+1][y+1]=ValorNuevo;

recorrido[x+1][y+1]=true;

Grupo.add((x+1)+","+(y+1));

}

if((x+1)<MATRIZ.length&&!recorrido[x+1][y]&&MATRIZ[x+1][y].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x+1][y]=ValorNuevo;

recorrido[x+1][y]=true;

Grupo.add((x+1)+","+y);

}

if((x+1)<MATRIZ.length&&y>0&&!recorrido[x+1][y-1]&&MATRIZ[x+1][y-1].equals(ValorBuscado)){

nroPixeles++;

MATRIZ[x+1][y-1]=ValorNuevo;

recorrido[x+1][y-1]=true;

Page 52: Informe_Procesador_Imagenes

Grupo.add((x+1)+","+(y-1));

}

i++;

}

}

}

class Convetir extends JFrame

{

public Image ConvertirAGrises(Image destino,Image imagen)

{

if (destino == null) {

try {

int p, promedio, rojo, verde, azul;

Coversion C = new Coversion();

BufferedImage Nueva = C.toBufferedImage(imagen);

int a = Nueva.getWidth(); //Ancho

int h = Nueva.getHeight(); //Alto

int totalDePixeles = a * h;

int pixeles[] = new int[totalDePixeles]; //Arreglo de pixeles

PixelGrabber pg = new PixelGrabber(imagen,0,0,a,h,pixeles,0,a);

try

{

pg.grabPixels();

for(int i = 0; i < totalDePixeles; i++)

{

p = pixeles[i]; //Valor de un pixel

Page 53: Informe_Procesador_Imagenes

rojo = (0xff & (p>>16)); //Desplaza el entero p 16 bits a la derecha y aplica la operacion AND a los primeros 8 bits

verde = (0xff & (p>>8)); //Desplaza el entero p 8 bits a la derecha y aplica la operacion AND a los siguientes 8 bits

azul = (0xff & p) ; //Aplica la operacion AND a los siguientes 8 bits

promedio = (int) ((rojo+verde+azul)/3);

pixeles[i]=(0xff000000|promedio<<16|promedio<<8|promedio);

}

destino = createImage(new MemoryImageSource(a,h,pixeles,0,a));

}catch(InterruptedException e)

{

JOptionPane.showMessageDialog(null,"Error del sistema : "+e.getMessage(),"Error de Imagen",JOptionPane.OK_OPTION);

//this.mensajeDeError = e.getMessage();

}

}

catch(Exception e){System.out.println(e);

}

}

return destino;

}

}

3.- frmMainServer:

/*

* frmMainServer.java

*

Page 54: Informe_Procesador_Imagenes

* Created on 30/10/2011, 10:27:31 PM

*/

package procesadorimagenes;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import javax.bluetooth.*;

import java.io.*;

import javax.microedition.io.*;

import java.util.logging.*;

import java.awt.image.*;

import java.util.ArrayList;

import java.util.Arrays;

import javax.imageio.*;

import sun.awt.image.ToolkitImage;

/**

*

* @author jose

*/

public class frmMainServer extends javax.swing.JDialog {

/*ATRIBUTOS*/

protected String UUID = new UUID("1101", true).toString();

protected int discoveryMode = DiscoveryAgent.GIAC; // no paring needed

Page 55: Informe_Procesador_Imagenes

public static InputStream in;

public static OutputStream out;

StreamConnectionNotifier noti=null;

private static boolean ServerRun = true;

Image imagenTomada;// imagen recibida

String mensajeenviar="";

boolean entro=false;

/*METODOS*/

/*Este metodo envia el mensaje de respuesta*/

private void sendMessage(StreamConnection conn, String msgCliente) {

try {

//abrimos el canal de salida

out = conn.openOutputStream();

//Escribimos el mensaje

out.write(msgCliente.getBytes());

} catch (IOException ex) {

ex.printStackTrace();

}

}

//Este metodo recibe el notificador cuando se abre la conexion

private void serverLoop(final StreamConnectionNotifier notifier) {

Thread handler = new Thread() {

@Override

public void run() {

try {

while (ServerRun) { //bucle infinito que acepta conexiones

Page 56: Informe_Procesador_Imagenes

// Si esta esperando por conexiones entonces envia

if (!entro){

log("Esperando por conexion...");

handleConnection(notifier.acceptAndOpen());

}else{//Ahora envia el mensaje de respuesta

log("Enviando mensaje...");

sendMessage(notifier.acceptAndOpen(), mensajeenviar);

}

}

} catch (Exception e) {

log(e);

}

try {

Thread.sleep(300);

} catch (InterruptedException ex) {

Logger.getLogger(frmMainServer.class.getName()).log(Level.SEVERE, null, ex);

}

}

};

handler.start();

}

private void startReadThread2(final InputStream in) {

Thread reader = new Thread() {

Page 57: Informe_Procesador_Imagenes

@Override

public void run() {

try {

// Copiamos la direccion a un directorio establecido

File miImagen = new File("D:/Image/image.jpg");

//Lo Convertimos en el buffer con Image.IO

BufferedImage bufIma = ImageIO.read(in);

//Escribimos en la imagen lo que esta en el buffer

ImageIO.write(bufIma, "jpg", miImagen);

//Creamos la imagen

imagenTomada = jpImagen.createImage(bufIma.getSource());

//obtenemos el graphics del panel para poder pintarlo

Graphics g=jpImagen.getGraphics();

//dibjamos con el graphics

g.drawImage(imagenTomada, 0, 0, bufIma.getWidth(),bufIma.getHeight(),jpImagen);

jpImagen.setOpaque(false);

jpImagen.paint(g);

//Creamos la clase patron

Reconocer recoPatro=new Reconocer();

//Le damos la imagen y recuperamos el numero de circulos

int nrocirc=recoPatro.ReconocerPatron("0", "9", imagenTomada, jpImagen);

String msg="";

if (nrocirc > 0){ // agregar errores

msg="la imagen contiene "+nrocirc+" circulos";

}else

Page 58: Informe_Procesador_Imagenes

msg="La imagen no contiene circulos";

System.out.println(msg);

//asignamos al mensaje para ser enviado y esperamos que el celular pida la respuesta

mensajeenviar=msg;

log(mensajeenviar);

entro=true;

} catch (Throwable e) {

log(e);

} finally {

if (in != null) {

try {

//mostramos el mensaje

log("Transferencia de imagen realizada");

in.close();

} catch (IOException e) {

}

}

}

}

};

reader.start();

}

//este metodo acepta la conexion y abre la cadena

private void handleConnection(StreamConnection conn) throws IOException {

Page 59: Informe_Procesador_Imagenes

//abre la cadena

in = conn.openInputStream();

//en este metodo recibimos la imagen

startReadThread2(in);

//mostramos mensaje de conexion encontrada

log("Conexion encontrada..");

}

private void log(String msg) {

txtaMensajes.append(msg + "\n");

}

private void log(Throwable e) {

log(e.getMessage());

e.printStackTrace();

}

/** Creates new form frmMainServer */

public frmMainServer(java.awt.Frame parent, boolean modal) {

super(parent, modal);

initComponents();

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

Page 60: Informe_Procesador_Imagenes

*/

@SuppressWarnings("unchecked")

// <editor-fold defaultstate="collapsed" desc="Generated Code">

private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();

txtaMensajes = new javax.swing.JTextArea();

jLabel1 = new javax.swing.JLabel();

jpImagen = new javax.swing.JPanel();

jbtnConectar = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

txtaMensajes.setColumns(20);

txtaMensajes.setRows(5);

jScrollPane1.setViewportView(txtaMensajes);

jLabel1.setFont(new java.awt.Font("Tempus Sans ITC", 3, 24));

jLabel1.setText("Mensajes");

jpImagen.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

javax.swing.GroupLayout jpImagenLayout = new javax.swing.GroupLayout(jpImagen);

jpImagen.setLayout(jpImagenLayout);

jpImagenLayout.setHorizontalGroup(

Page 61: Informe_Procesador_Imagenes

jpImagenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGap(0, 171, Short.MAX_VALUE)

);

jpImagenLayout.setVerticalGroup(

jpImagenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGap(0, 209, Short.MAX_VALUE)

);

jbtnConectar.setText("Conectar");

jbtnConectar.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jbtnConectarActionPerformed(evt);

}

});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addComponent(jpImagen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

Page 62: Informe_Procesador_Imagenes

.addGap(80, 80, 80)

.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE))

.addGroup(layout.createSequentialGroup()

.addGap(302, 302, 302)

.addComponent(jLabel1))

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addComponent(jbtnConectar)))

.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addComponent(jbtnConectar)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addComponent(jLabel1)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE))

.addGroup(layout.createSequentialGroup()

.addGap(45, 45, 45)

Page 63: Informe_Procesador_Imagenes

.addComponent(jpImagen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))

.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

pack();

}// </editor-fold>

private void jbtnConectarActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

ServerRun = true;

try {

LocalDevice device = LocalDevice.getLocalDevice();

device.setDiscoverable(DiscoveryAgent.GIAC);

//le asignamos la direccion del servidor

String url = "btspp://localhost:" + UUID + ";name=grover-PC";

// mostramos el mensaje

log("Create server by uri: " + url);

//abrimos la conexion con la direccion url

StreamConnectionNotifier notifier = (StreamConnectionNotifier) Connector.open(url);

StreamConnectionNotifier noti=notifier;

//llamamos al metodo que escucha las conexiones

serverLoop(notifier);

} catch (Throwable e) {

Page 64: Informe_Procesador_Imagenes

log(e);

}

}

/**

* @param args the command line arguments

*/

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

frmMainServer dialog = new frmMainServer(new javax.swing.JFrame(), true);

dialog.addWindowListener(new java.awt.event.WindowAdapter() {

public void windowClosing(java.awt.event.WindowEvent e) {

System.exit(0);

}

});

dialog.setVisible(true);

}

});

}

// Variables declaration - do not modify

private javax.swing.JLabel jLabel1;

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JButton jbtnConectar;

Page 65: Informe_Procesador_Imagenes

private javax.swing.JPanel jpImagen;

private javax.swing.JTextArea txtaMensajes;

// End of variables declaration

}

B)El código para el cliente consta en 2 partes:

1.-CameraCanvas:

import javax.microedition.lcdui.*;

import javax.microedition.media.MediaException;

import javax.microedition.media.control.VideoControl;

public class CameraCanvas

extends Canvas implements CommandListener {

private ClientChatMIDlet mClientMIDlet;

private Command mBackCommand = new Command("Back", Command.BACK, 0);

private Command mCaptureCommand = new Command("Capture", Command.SCREEN, 0);

public CameraCanvas(ClientChatMIDlet midlet, VideoControl videoControl) {

int width = getWidth();

int height = getHeight();

addCommand(mBackCommand);

addCommand(mCaptureCommand);

setCommandListener(this);

mClientMIDlet = midlet;

Page 66: Informe_Procesador_Imagenes

videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);

try {

videoControl.setDisplayLocation(2, 2);

videoControl.setDisplaySize(width - 4, height - 4);

} catch (MediaException me) {

try {

videoControl.setDisplayFullScreen(true);

} catch (MediaException me2) {

}

}

videoControl.setVisible(true);

}

public void paint(Graphics g) {

int width = getWidth();

int height = getHeight();

// Draw a green border around the VideoControl.

g.setColor(0x00ff00);

g.drawRect(0, 0, width - 1, height - 1);

g.drawRect(1, 1, width - 3, height - 3);

}

public void commandAction(Command c, Displayable d) {

if (c == mBackCommand) {

mClientMIDlet.getDisplay().setCurrent(mClientMIDlet.getCliente());

Page 67: Informe_Procesador_Imagenes

}else if (c==mCaptureCommand){

mClientMIDlet.capture();

}

}

public void keyPressed(int keyCode) {

int action = getGameAction(keyCode);

String boton = getKeyName(keyCode);

boton += String.valueOf(action);

if (action == FIRE) {

// mClientMIDlet.capture();

Alert a = new Alert("Exception", "Fuego" + boton, null, null);

mClientMIDlet.getDisplay().setCurrent(a, this);

} else {

Alert a = new Alert("Exception", "Tomando foto" + boton, null, null);

mClientMIDlet.getDisplay().setCurrent(a, this);

}

}

}

2.-ClientChatMIDlet:

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

Page 68: Informe_Procesador_Imagenes

import java.io.ByteArrayOutputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Vector;

import javax.bluetooth.BluetoothStateException;

import javax.bluetooth.DeviceClass;

import javax.bluetooth.DiscoveryAgent;

import javax.bluetooth.DiscoveryListener;

import javax.bluetooth.LocalDevice;

import javax.bluetooth.RemoteDevice;

import javax.bluetooth.ServiceRecord;

import javax.bluetooth.UUID;

import javax.microedition.io.Connector;

import javax.microedition.io.StreamConnection;

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.media.*;

import javax.microedition.media.control.*;

/**

* @author jose

*/

public class ClientChatMIDlet extends MIDlet implements CommandListener, DiscoveryListener {

Page 69: Informe_Procesador_Imagenes

private boolean midletPaused = false;

/* Atributos

*

*/

protected UUID uuid = new UUID(0x1101); // serial port profile

protected int inquiryMode = DiscoveryAgent.GIAC; // no pairing is needed

protected int connectionOptions = ServiceRecord.NOAUTHENTICATE_NOENCRYPT;

protected Vector deviceList = new Vector();

private boolean ListoParaEnviar = false;

private boolean Retornar = false;

private boolean Encontradaconexion = false;

TextField msg;

String url = "";

//atributos para la camara

private Player mPlayer;

private VideoControl mVideoControl;

private boolean Accioncamera = false;

private String getDeviceStr(RemoteDevice btDevice) {

return getFriendlyName(btDevice) + " - 0x" + btDevice.getBluetoothAddress();

}

private String getFriendlyName(RemoteDevice btDevice) {

try {

return btDevice.getFriendlyName(false);

} catch (IOException e) {

Page 70: Informe_Procesador_Imagenes

return "no name available";

}

}

public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {

log("A device discovered (" + getDeviceStr(btDevice) + ")");

deviceList.addElement(btDevice);

}

private void log(Throwable e) {

log(e.getMessage());

}

synchronized private void log(String msg) {

Cliente.append(msg);

Cliente.append("\n\n");

}

private DiscoveryAgent getAgent() {

try {

return LocalDevice.getLocalDevice().getDiscoveryAgent();

} catch (BluetoothStateException e) {

throw new Error(e.getMessage());

}

}

private void startDeviceInquiry() {

Page 71: Informe_Procesador_Imagenes

try {

log("Empezando la deteccion - esto va tomar unos segundos...");

DiscoveryAgent agent = getAgent();

agent.startInquiry(inquiryMode, this);

} catch (Exception e) {

log(e);

}

}

public void serviceSearchCompleted(int transID, int respCode) {

String messg = null;

switch (respCode) {

case SERVICE_SEARCH_COMPLETED:

messg = "El servicio de busqueda termino";

Encontradaconexion = true;

break;

case SERVICE_SEARCH_TERMINATED:

messg = "the service search request was cancelled by a call to DiscoveryAgent.cancelServiceSearch()";

break;

case SERVICE_SEARCH_ERROR:

messg = "an error occurred while processing the request";

break;

case SERVICE_SEARCH_NO_RECORDS:

messg = "no records were found during the service search";

break;

Page 72: Informe_Procesador_Imagenes

case SERVICE_SEARCH_DEVICE_NOT_REACHABLE:

messg = "the device specified in the search request could not be reached or the local device could not establish a connection to the remote device";

break;

}

log("Busqueda completada - " + messg);

}

//<editor-fold defaultstate="collapsed" desc=" Generated Fields ">

private Form Cliente;

private Form ChatRoom;

private Command backCommand;

private Command exitCommand;

private Command okCommand;

private Command receiveMsg;

private Command Iniciar;

private Command Camara;

private Command cmdCapturar;

private Command cmdAtras;

private Command cmdAtras1;

private Command mBack;

//</editor-fold>

/**

* The ClientChatMIDlet constructor.

*/

public ClientChatMIDlet() {

}

Page 73: Informe_Procesador_Imagenes

//<editor-fold defaultstate="collapsed" desc=" Generated Methods ">

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">

/**

* Initializes the application.

* It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.

*/

private void initialize() {

// write pre-initialize user code here

// write post-initialize user code here

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">

/**

* Performs an action assigned to the Mobile Device - MIDlet Started point.

*/

public void startMIDlet() {

// write pre-action user code here

switchDisplayable(null, getCliente());

// write post-action user code here

}

//</editor-fold>

Page 74: Informe_Procesador_Imagenes

//<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">

/**

* Performs an action assigned to the Mobile Device - MIDlet Resumed point.

*/

public void resumeMIDlet() {

// write pre-action user code here

// write post-action user code here

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">

/**

* Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.

* @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately

* @param nextDisplayable the Displayable to be set

*/

public void switchDisplayable(Alert alert, Displayable nextDisplayable) {

// write pre-switch user code here

Display display = getDisplay();

if (alert == null) {

display.setCurrent(nextDisplayable);

} else {

display.setCurrent(alert, nextDisplayable);

}

Page 75: Informe_Procesador_Imagenes

// write post-switch user code here

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Method: commandAction for Displayables ">

/**

* Called by a system to indicated that a command has been invoked on a particular displayable.

* @param command the Command that was invoked

* @param displayable the Displayable where the command was invoked

*/

public void commandAction(Command command, Displayable displayable) {

// write pre-action user code here

if (displayable == Cliente) {

if (command == Camara) {

// write pre-action user code here

// write post-action user code here

if (Accioncamera) {

String supports = System.getProperty("video.snapshot.encodings");

if (supports != null && supports.length() > 0) {

Cliente.append("Ready to take pictures.");

Cliente.addCommand(Iniciar);

} else {

Cliente.append("No se puede usar el dispositivo para tomar imagenes ");

}

}

Page 76: Informe_Procesador_Imagenes

} else if (command == Iniciar) {

// write pre-action user code here

showCamera();

// write post-action user code here

} else if (command == cmdCapturar) {

// write pre-action user code here

Alert a = new Alert("Exception", "Fuego", null, null);

Display.getDisplay(this).setCurrent(a, Cliente);

//capture();

// write post-action user code here

} else if (command == exitCommand) {

// write pre-action user code here

exitMIDlet();

// write post-action user code here

} else if (command == mBack) {

// write pre-action user code here

Alert a = new Alert("Exception", "Fuego", null, null);

Display.getDisplay(this).setCurrent(a, Cliente);

// write post-action user code here

Display.getDisplay(this).setCurrent(Cliente);

} else if (command == okCommand) {

// write pre-action user code here

// write post-action user code here

Page 77: Informe_Procesador_Imagenes

if (ListoParaEnviar) {

//enviar al servidor

StreamConnection stream = null;

OutputStream out = null;

try {

stream = (StreamConnection) Connector.open(url);

log("Bluetooth stream open.");

if (stream == null) {

log("No se reconoce");

} else {

out = stream.openOutputStream();

out.write(msg.getString().getBytes());

}

} catch (IOException e) {

log(e);

} finally {

log("Bluetooth stream closed.");

if (out != null) {

try {

out.close();

stream.close();

logSet("Mensaje enviado\n");

Retornar = true;

ListoParaEnviar = false;

} catch (IOException e) {

Page 78: Informe_Procesador_Imagenes

log(e);

}

}

}

}

if (Retornar) {

Cliente.deleteAll();

Display.getDisplay(this).setCurrent(Cliente);

msg = new TextField("Mensaje", "", 10, 0);

Cliente.append(msg);

ListoParaEnviar = true;

Retornar = false;

}

} else if (command == receiveMsg) {

// write pre-action user code here

if (Encontradaconexion) {

StreamConnection stream = null;

InputStream ingreso = null;

log("Bluetooth stream open.");

try {

stream = (StreamConnection) Connector.open(url);

if (stream == null) {

log("No se reconoce");

} else {

boolean algo = true;

while (algo) {

Page 79: Informe_Procesador_Imagenes

ingreso = stream.openInputStream();

if (ingreso != null) {

algo = false;

}

}

StringItem pau = new StringItem("Esperando mensaje", " ");

Cliente.append(pau);

StringItem msgrecibido = new StringItem("Mensaje Recibido", " ");

byte[] s = new byte[512];

ingreso.read(s);

String recibido = new String(s);

msgrecibido.setText(url);

Cliente.append(recibido);

}

} catch (IOException e) {

log(e);

} finally {

log("Bluetooth stream closed.");

if (ingreso != null) {

try {

ingreso.close();

stream.close();

Retornar = true;

ListoParaEnviar = false;

} catch (IOException e) {

Page 80: Informe_Procesador_Imagenes

log(e);

}

}

}

}

// write post-action user code here

}

}

// write post-action user code here

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: Cliente ">

/**

* Returns an initiliazed instance of Cliente component.

* @return the initialized component instance

*/

public Form getCliente() {

if (Cliente == null) {

// write pre-init user code here

Cliente = new Form("Cliente");

Cliente.addCommand(getExitCommand());

Cliente.addCommand(getOkCommand());

Cliente.addCommand(getReceiveMsg());

Cliente.addCommand(getCamara());

Cliente.addCommand(getIniciar());

Page 81: Informe_Procesador_Imagenes

Cliente.addCommand(getCmdCapturar());

Cliente.addCommand(getMBack());

Cliente.setCommandListener(this);

// write post-init user code here

Cliente = new Form("Cliente");

Cliente.addCommand(getExitCommand());

Cliente.addCommand(getOkCommand());

Cliente.addCommand(getReceiveMsg());

Cliente.addCommand(getCamara());

Cliente.setCommandListener(this);

}

return Cliente;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommand ">

/**

* Returns an initiliazed instance of backCommand component.

* @return the initialized component instance

*/

public Command getBackCommand() {

if (backCommand == null) {

// write pre-init user code here

backCommand = new Command("Back", Command.BACK, 0);

// write post-init user code here

}

return backCommand;

Page 82: Informe_Procesador_Imagenes

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand ">

/**

* Returns an initiliazed instance of exitCommand component.

* @return the initialized component instance

*/

public Command getExitCommand() {

if (exitCommand == null) {

// write pre-init user code here

exitCommand = new Command("Exit", Command.EXIT, 0);

// write post-init user code here

}

return exitCommand;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: ChatRoom ">

/**

* Returns an initiliazed instance of ChatRoom component.

* @return the initialized component instance

*/

public Form getChatRoom() {

if (ChatRoom == null) {

// write pre-init user code here

ChatRoom = new Form("Chat Room");

Page 83: Informe_Procesador_Imagenes

// write post-init user code here

}

return ChatRoom;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommand ">

/**

* Returns an initiliazed instance of okCommand component.

* @return the initialized component instance

*/

public Command getOkCommand() {

if (okCommand == null) {

// write pre-init user code here

okCommand = new Command("Ok", Command.OK, 0);

// write post-init user code here

}

return okCommand;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: receiveMsg ">

/**

* Returns an initiliazed instance of receiveMsg component.

* @return the initialized component instance

*/

public Command getReceiveMsg() {

Page 84: Informe_Procesador_Imagenes

if (receiveMsg == null) {

// write pre-init user code here

receiveMsg = new Command("Recibir mensaje", Command.OK, 0);

// write post-init user code here

}

return receiveMsg;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: Camara ">

/**

* Returns an initiliazed instance of Camara component.

* @return the initialized component instance

*/

public Command getCamara() {

if (Camara == null) {

// write pre-init user code here

Camara = new Command("Camara", Command.OK, 0);

// write post-init user code here

}

return Camara;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: Iniciar ">

/**

* Returns an initiliazed instance of Iniciar component.

Page 85: Informe_Procesador_Imagenes

* @return the initialized component instance

*/

public Command getIniciar() {

if (Iniciar == null) {

// write pre-init user code here

Iniciar = new Command("Iniciar Camara", Command.OK, 0);

// write post-init user code here

}

return Iniciar;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: cmdAtras ">

/**

* Returns an initiliazed instance of cmdAtras component.

* @return the initialized component instance

*/

public Command getCmdAtras() {

if (cmdAtras == null) {

// write pre-init user code here

cmdAtras = new Command("Atras", Command.OK, 0);

// write post-init user code here

}

return cmdAtras;

}

//</editor-fold>

Page 86: Informe_Procesador_Imagenes

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: cmdCapturar ">

/**

* Returns an initiliazed instance of cmdCapturar component.

* @return the initialized component instance

*/

public Command getCmdCapturar() {

if (cmdCapturar == null) {

// write pre-init user code here

cmdCapturar = new Command("take", Command.OK, 0);

// write post-init user code here

cmdCapturar = new Command("take", Command.SCREEN, 0);

}

return cmdCapturar;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: cmdAtras1 ">

/**

* Returns an initiliazed instance of cmdAtras1 component.

* @return the initialized component instance

*/

public Command getCmdAtras1() {

if (cmdAtras1 == null) {

// write pre-init user code here

cmdAtras1 = new Command("Back", Command.BACK, 0);

// write post-init user code here

}

Page 87: Informe_Procesador_Imagenes

return cmdAtras1;

}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: mBack ">

/**

* Returns an initiliazed instance of mBack component.

* @return the initialized component instance

*/

public Command getMBack() {

if (mBack == null) {

// write pre-init user code here

mBack = new Command("Back", Command.BACK, 0);

// write post-init user code here

}

return mBack;

}

//</editor-fold>

/**

* Returns a display instance.

* @return the display instance.

*/

public Display getDisplay() {

return Display.getDisplay(this);

}

Page 88: Informe_Procesador_Imagenes

public void recibirMensajeHilo(){

Thread hilorecv=new Thread(){

public void run() {

try{

StreamConnection stream = null;

InputStream ingreso = null;

log("Bluetooth stream open.");

try {

stream = (StreamConnection) Connector.open(url);

if (stream == null) {

log("No se reconoce");

} else {

boolean algo = true;

while (algo) {

ingreso = stream.openInputStream();

if (ingreso != null) {

algo = false;

}

}

StringItem msgrecibido = new StringItem("Mensaje Recibido", " ");

byte[] s = new byte[512];

ingreso.read(s);

String recibido = new String(s);

Cliente.append(recibido);

}

} catch (IOException e) {

Page 89: Informe_Procesador_Imagenes

log(e);

} finally {

log("Bluetooth stream closed.");

if (ingreso != null) {

try {

ingreso.close();

stream.close();

} catch (IOException e) {

log(e);

}

}

}

}catch(Exception e){

}

}

};hilorecv.start();

}

/**

* Exits MIDlet.

*/

public void exitMIDlet() {

switchDisplayable(null, null);

destroyApp(true);

notifyDestroyed();

}

Page 90: Informe_Procesador_Imagenes

/**

* Called when MIDlet is started.

* Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.

*/

public void startApp() {

if (midletPaused) {

resumeMIDlet();

} else {

initialize();

startMIDlet();

startDeviceInquiry();

}

midletPaused = false;

}

/**

* Called when MIDlet is paused.

*/

public void pauseApp() {

midletPaused = true;

}

/**

* Called to signal the MIDlet to terminate.

* @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.

*/

Page 91: Informe_Procesador_Imagenes

public void destroyApp(boolean unconditional) {

}

public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

log("Service discovered.");

for (int i = 0; i < servRecord.length; i++) {

ServiceRecord rec = servRecord[i];

url = rec.getConnectionURL(connectionOptions, false);

Cliente.append(url);

Cliente.deleteAll();

Display.getDisplay(this).setCurrent(Cliente);

msg = new TextField("Mensaje", "", 10, 0);

Cliente.append(msg);

ListoParaEnviar = true;

Accioncamera = true;

}

}

synchronized private void logSet(String msg) {

Cliente.deleteAll();

Cliente.append(msg);

Cliente.append("\n\n");

}

private void makeInformationAreaGUI(int nro, RemoteDevice device) {

Cliente.deleteAll();

Page 92: Informe_Procesador_Imagenes

Display.getDisplay(this).setCurrent(Cliente);

Cliente.append(String.valueOf(nro));

Cliente.append(getDeviceStr(device));

UUID uuids[] = new UUID[]{uuid};

try {

getAgent().searchServices(null, uuids, device, this);

} catch (Exception e) {

log(e);

}

}

public void inquiryCompleted(int discType) {

final List devices = new List("Seleccione un dispositivo", List.IMPLICIT);

Cliente.append("Numero de Dispositivos: " + deviceList.size());

for (int i = 0; i < deviceList.size(); i++) {

devices.append(getDeviceStr((RemoteDevice) deviceList.elementAt(i)), null);

}

devices.setCommandListener(new CommandListener() {

public void commandAction(Command arg0,

Displayable arg1) {

int nro = devices.getSelectedIndex();

makeInformationAreaGUI(nro, (RemoteDevice) deviceList.elementAt(nro));

}

});

Display.getDisplay(this).setCurrent(devices);

Page 93: Informe_Procesador_Imagenes

}

/*METODOS PARA CAPTURAR IMAGEN*/

private Image createThumbnail(Image image) {

int sourceWidth = image.getWidth();

int sourceHeight = image.getHeight();

int thumbWidth = 64;

int thumbHeight = -1;

if (thumbHeight == -1) {

thumbHeight = thumbWidth * sourceHeight / sourceWidth;

}

Image thumb = Image.createImage(thumbWidth, thumbHeight);

Graphics g = thumb.getGraphics();

for (int y = 0; y < thumbHeight; y++) {

for (int x = 0; x < thumbWidth; x++) {

g.setClip(x, y, 1, 1);

int dx = x * sourceWidth / thumbWidth;

int dy = y * sourceHeight / thumbHeight;

g.drawImage(image, x - dx, y - dy, Graphics.LEFT | Graphics.TOP);

}

}

Page 94: Informe_Procesador_Imagenes

Image immutableThumb = Image.createImage(thumb);

return immutableThumb;

}

public void capture() {

try {

// Get the image.

byte[] raw = mVideoControl.getSnapshot(null);

Image image = Image.createImage(raw, 0, raw.length);

Image thumb = createThumbnail(image);

Cliente.deleteAll();

Cliente.append(thumb);

// Flip back to the main form.

Display.getDisplay(this).setCurrent(Cliente);

// Shut down the player.

mPlayer.close();

/*enviar via bluetoo*/

enviar2(raw);

recibirMensajeHilo();

//mVideoControl = null;

} catch (MediaException me) {

handleException(me);

}

}

Page 95: Informe_Procesador_Imagenes

private void enviar2(byte [] img) {

StreamConnection stream = null;

OutputStream out = null;

try {

stream = (StreamConnection) Connector.open(url);

if (stream == null) {

log("No se reconoce");

} else {

out = stream.openOutputStream();

out.write(img);

}

} catch (IOException e) {

log(e);

} finally {

log("Bluetooth stream closed.");

if (out != null) {

try {

out.close();

stream.close();

logSet("Imagen enviada\n");

Retornar = true;

ListoParaEnviar = false;

} catch (IOException e) {

log(e);

Page 96: Informe_Procesador_Imagenes

}

}

}

}

private void showCamera() {

try {

mPlayer = Manager.createPlayer("capture://image");

mPlayer.realize();

mVideoControl = (VideoControl) mPlayer.getControl("VideoControl");

Canvas canvas = new CameraCanvas(this, mVideoControl);

Display.getDisplay(this).setCurrent(canvas);

mPlayer.start();

} catch (IOException ioe) {

handleException(ioe);

} catch (MediaException me) {

handleException(me);

}

}

private void handleException(Exception e) {

Alert a = new Alert("Exception", e.toString(), null, null);

a.setTimeout(Alert.FOREVER);

Display.getDisplay(this).setCurrent(a, Cliente);

Page 97: Informe_Procesador_Imagenes

}

}