-
Primer esbozo de caracterización
Publicado el 5 05Europe/Berlin Mayo 05Europe/Berlin 2009 Sin comentarios aún ...Acabamos de terminar un primer esbozo del módulo de caracterización de imágenes. Actualmente, la aplicación incluye sólo dos operaciones de caracterización, a saber, media e histograma de una imagen sobre una región de interés.
El funcionamiento de la aplicación a la hora de caracterizar imágenes es muy similar al funcionamiento del procesamiento de paquetes de imágenes.
En primer lugar, se debe crear un paquete de imágenes que contenga las imágenes a caracterizar. Esto ya lo hemos explicado con anterioridad.
Posteriormente, el usario debe crear un generador de vector de caracterización. ¿Qué es un generador de vector de caracterización?
La caracterización de una imagen no es más que un vector de caracterización, el cual almacena medidas de caracterización. Una medida de caracterización es una propiedad numérica atribuible a una imagen, como, por ejemplo, la media de los valores de los píxeles de la imagen, o su histograma. Cuando se caracteriza una imagen, interesa calcular sobre ella diversas medidas de caracterización, para así aglutinar una mayor cantidad de información de ésta. Una vez creadas las medidas de caracterización, éstas son agrupadas en un vector de caracterización, que se asocia a la imagen, y que representa toda la información extraída de ella.
Un generador de vector de caracterización permite al usuario especificar cuál es la estructura del vector de caracterización que se genere al caracterizar una imagen. Por ejemplo, un generador de vector de caracterización podría especificar que el vector de caracterización generado contuviera dos medidas de caracterización, la media y el histograma.
Así pues, el siguiente paso es la creación de un generador de vector de caracterización. Para ello, el usuario accede a la vista de Caracterización de Imágenes, donde puede crear un generador de vector de caracterización pulsando el botón correspondiente, e introduciendo su nombre.
Tras crear el generador, el usuario debe insertar las operaciones que calcularán las medidas de caracterización del respectivo vector de caracterización. Si el usuario quiere que el vector de caracterización generado por un generador de vector de caracterización contenga, por ejemplo, la media y el histograma, el usuario deberá insertar dichas operaciones en el generador. El procedimiento es sencillo: del árbol de operaciones de caracterización, se selecciona la operación en cuestión, se introducen sus parámetros, y se inserta en un generador de vector de caracterización (proceso análogo al de la inserción de las cadenas de operaciones en el procesamiento de paquetes de imágenes).
Tras definir los paquetes de imágenes a caracterizar y los generadores de vector de caracterización, se configura la ejecución de la caracterización. La vista Caracterización de Imágenes permite lanzar un diálogo de configuración, desde el cual se configura y ejecuta la caracterización.
Tras presionar el botón Caracterizar, se desencadena la caracterización. Los datos generados de la caracterización son visualizados en un editor.
Actualmente, sólo se pueden visualizar los datos generados durante la caracterización. Insistimos, esto es un primer esbozo de la caracterización.
Por ahora, nos centraremos en crear más operaciones de caracterización, así como en permitir manipular los vectores de caracterización y guardar los informes de caracterización generados en ficheros persistentes.
-
Diálogo “de detalles” JFace
Publicado el 28 28Europe/Berlin Abril 28Europe/Berlin 2009 Sin comentarios aún ...Desde hace unas semanas, y sólo por curiosidad, decidimos buscar una clase de tipo Dialog del JFace o del SWT que implementara el clásico diálogo que:
- Muestra un icono.
- Muestra un mensaje principal.
- Muestra un botón de “detalles”. Si dicho botón es pulsado, se expande una región, debajo del diálogo, que muestra un texto predefinible por el usuario. Esta región viene a ser un “área de detalles” donde al usuario se le puede especificar un mensaje más explicativo que el mero mensaje principal del diálogo. Si el botón de “detalles” se vuelve a pulsar, este área de detalles es colapsada.
Eclipse muestra este tipo de diálogos en múltiples ocasiones. Así por ejemplo, cuando se está ejecutando una tera de larga duración, se muestra un diálogo como el siguiente:
Cuando se pulsa el botón “Details >>”, el diálogo se expande, mostrando el área de detalles en cuestión:
Por desgracia, tras diversas búsquedas, no pudimos dar con un código fuente que lo implementara. Con el deseo de ayudar a aquellos que, como nosotros, no encontraron este tipo de diálogo implementado, hemos decidido crear una clase propia que lo implemente.
Actualmente esta clase permite definir un área de detalles que está formada sólo por texto no editable. Esto, por supuesto, es una limitación, pero también es cierto que es trivial abstraer esta clase para que, en el área de detalles, se pueda mostrar cualquier tipo de contenido. Por falta de tiempo, sólo hemos implementado la clase que define un diálogo con un área de detalles de tipo textual. Esta clase, además, permite definir el tipo de icono mostrado en el diálogo. La clase, DialogoDetalles, puede ser accedida desde este link. Su aspecto es el que se muestra a continuación:
El código fuente de la clase es el siguiente:
[sourcecode language='java']
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IconAndMessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;/**
*
* La clase DialogoDetalles representa un diálogo emergente que muestra un
* icono, un mensaje, y un área de detalles donde se puede mostrar texto plano.
*
* Está clase está pensada para mostrar al usuario el clásico diálogo en el que
* puede pulsar un botón de “detalles” para así visualizar un informe detallado
* del mensaje transmitido por el diálogo.
*
* Este diálogo consta de dos botones, uno de “cerrar” y otro de “detalles”. El
* botón de detalles permite hacer visible u ocultar el área de detalles del
* diálogo. El icono visualizado en el diálogo también puede ser especificado
* por el usuario.
*
* @author L.A González Jaime
* @author R.J Palma Durán
*/
public class DialogoDetalles extends IconAndMessageDialog{
/*
* Tipo de icono a usar. Es una de las constantes ERROR,
* WARNING,INFORMATIO,QUESTION.
*/
protected int tipoIcono;
/*
* Detalles del diálogo. Este texto es el mostrado en el área de detalles.
*/
protected String detalles;
/*
* Área de texto donde se muestran los detalles.
*/
protected Text textoDetalles;
/*
* Booleano que indica si el área de texto de los detalles (textoDetalles)
* está creada o no. La visualización y el ocultamiento del área de detalles
* se gestiona creando y destrullendo el textoDetalles. Este flag nos indica
* si, en efecto, el textoDetalles está o no creado.
*/
protected boolean textoDetallesCreado = false;
/**
* Constante que indica que el icono visualizado en el diálogo es de error.
*/
public static final int ERROR = 0;
/**
* Constante que indica que el icono visualizado en el diálogo es de
* advertencia.
*/
public static final int WARNING = 1;
/**
* Constante que indica que el icono visualizado en el diálogo es de
* información.
*/
public static final int INFORMATION = 2;
/**
* Constante que indica que el icono visualizado en el diálogo es de
* pregunta.
*/
public static final int QUESTION = 3;
/*
* Botón que permite mostrar y ocultar los detalles del diálogo.
*/
protected Button botonDetalles;
/*
* Título del diálogo.
*/
protected String titulo;/**
* Cosntruye un DialogoDetalles. El estilo del diálogo creado (el estilo de
* la shell) es
*SWT.CLOSE | SWT.RESIZE | SWT.MAX | SWT.MODELESS.
*
* @param titulo título del diálogo.
* @param mensaje mensaje principal mostrado en el diálogo.
* @param detalles texto que se muestra en el área de detalles.
* @param tipoIcono tipo de icono a mostrar en el diálogo. Puede ser alguna de las constantes
*DialogoDetalles.ERROR,DialogoDetalles.WARNING,DialogoDetalles.INFORMATION
* ,DialogoDetalles.QUESTION.
* @param parentShell la Shell padre de este diálogo. Si es null, se creará una shell de alto nivel.
*/
public DialogoDetalles(String titulo, String mensaje, String detalles, int tipoIcono, Shell parentShell){
this(titulo,mensaje,detalles,tipoIcono,parentShell,SWT.CLOSE | SWT.RESIZE | SWT.MAX | SWT.MODELESS);
}/**
* Cosntruye un DialogoDetalles. Permite crear el estilo (estilo de la Shell) del
* diálogo creado.
*
* @param titulo título del diálogo.
* @param mensaje mensaje principal mostrado en el diálogo.
* @param detalles texto que se muestra en el área de detalles.
* @param tipoIcono tipo de icono a mostrar en el diálogo. Puede ser alguna de las constantes
*DialogoDetalles.ERROR,DialogoDetalles.WARNING,DialogoDetalles.INFORMATION
* ,DialogoDetalles.QUESTION.
* @param parentShell la Shell padre de este diálogo. Si es null, se creará una shell de alto nivel.
* @param estiloShell el estilo de la Shell del diálogo.
*/
public DialogoDetalles(String titulo, String mensaje, String detalles, int tipoIcono, Shell parentShell,
int estiloShell){
super(parentShell);
if(mensaje == null){
throw new IllegalArgumentException(”The input message cannot be null”);
}
this.message = mensaje;
if(tipoIcono < 0 || tipoIcono > 3){
throw new IllegalArgumentException(”Invalid image type”);
}
if(detalles == null){
throw new IllegalArgumentException(”Details cannot be null”);
}
if(titulo == null){
throw new IllegalArgumentException(”Title cannot be null”);
}
this.detalles = detalles;
this.tipoIcono = tipoIcono;
this.titulo = titulo;
this.setBlockOnOpen(false);
this.setShellStyle(estiloShell);
}/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
protected Control createDialogArea(Composite parent){
return createMessageArea(parent);
}/*
* (non-Javadoc)
* @see
* org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse
* .swt.widgets.Composite)
*/
protected void createButtonsForButtonBar(Composite parent){
createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
this.botonDetalles = createButton(parent, IDialogConstants.DETAILS_ID, IDialogConstants.SHOW_DETAILS_LABEL,
false);
}/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
*/
protected void buttonPressed(int buttonId){
if(buttonId == IDialogConstants.DETAILS_ID){
/*
* Si se ha pulsado el botón de “detalles”, se debe mostrar u ocultar el área de
* detalles, dependiendo de que estuviera o no oculta. Además, tras ocultar el
* área o visualizarla, se debe redimensionar el diálogo, para que así se ajuste
* al nuevo tamaño provocado por la aparición o desaparición del área de detalles.
*/
Point dimensionAnteriorDialogo = getShell().getSize();
if(this.textoDetallesCreado){
/*
* Si el área de texto está actualmente siendo mostrada, la eliminamos. Además,
* cambiamos la etiqueta del botón de “mostrar detalles”.
*/
this.botonDetalles.setText(IDialogConstants.SHOW_DETAILS_LABEL);
this.textoDetalles.dispose();
}
else{
/*
* Si el área de texto actualmente no está siendo visualizada, la mostramos. Para
* ello, iniciamos a this.textoDetalles. Además, debemos cambiar la etiqueta
* del botón de “mostrar detalles”.
*/
this.botonDetalles.setText(IDialogConstants.HIDE_DETAILS_LABEL);
this.textoDetalles = new Text((Composite)getContents(), SWT.BORDER | SWT.READ_ONLY | SWT.MULTI
| SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL);
this.textoDetalles.setText(this.detalles);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
this.textoDetalles.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
data.horizontalSpan = 2;
this.textoDetalles.setLayoutData(data);
}
getContents().getShell().layout();
this.textoDetallesCreado = !this.textoDetallesCreado;/*
* Se redimensiona el diálogo.
*/
Point dimensionNuevaDialogo = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
int altoPantalla = Display.getCurrent().getClientArea().height;
getShell().setSize(new Point(dimensionAnteriorDialogo.x, Math.min(dimensionNuevaDialogo.y, altoPantalla)));
}
else{
/*
* Si se pulsa el botón de “cerrar”, cerramos la ventana.
*/
close();
}
setReturnCode(buttonId);
}/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IconAndMessageDialog#getImage()
*/
protected Image getImage(){
switch(this.tipoIcono){
case ERROR:
return getErrorImage();
case WARNING:
return getWarningImage();
case INFORMATION:
return getInfoImage();
case QUESTION:
return getQuestionImage();
default:
throw new RuntimeException(”Invalid image type”);
}
}/*
* (non-Javadoc)
* @see
* org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
* .Shell)
*/
protected void configureShell(Shell shell){
super.configureShell(shell);
// Título del diálogo
shell.setText(this.titulo);
}
}[/sourcecode]
-
Procesamiento de paquetes de imágenes
Publicado el 15 15Europe/Berlin Abril 15Europe/Berlin 2009 1 comentarioTomando la sugerencia que jbelon hizo en una entrada anterior, hemos implementado un nuevo menú que permite llevar a cabo procesmiento de paquetes de imágenes.
La idea es que el usuario pueda definir paquetes de imágenes y cadenas de operaciones.
Un paquete de imágenes no es más que un conjunto de imágenes especificado por el usuario: el usuario puede, fácilmente, crear paquetes de imágenes.
Crear un paquete de imágenes es trivial, y se puede hacer a través de la vista Paquetes de Imagenes. Esta vista ofrece funcionalidad adicional para poder insertar cualesquiera imágenes en uno o varios paquetes de imágenes.
Una cadena de operaciones es una serie ordenada de operaciones de tratamiento de imágenes. Por ejemplo, el usuario puede crear una cadena de operaciones formada por una rotación, seguida de un filtrado gaussiano y seguida de una exponenciación.
Definir una cadena de operaciones se bien sencillo: basta crear una cadena en la vista de Cadenas de Operaciones.
Creada la cadena de operaciones, toda operación puede insertarse en ella, lo cual puede hacerse directamente sobre el panel de cada operación.
Definida la cadena de operaciones, el usuario puede seleccionar un paquete o paquetes de imágenes a los que aplicarla, todo ello en la vista Cadenas de Operaciones. Dicha vista permite, finalmente, lanzar un diálogo de configuración de la ejecución de las cadenas de operaciones, y, posteriormente, ejecutarlas.
-
Nueva versión de los ejecutables (con manual de ayuda y plugins de operaciones)
Publicado el 8 08Europe/Berlin Abril 08Europe/Berlin 2009 Sin comentarios aún ...Hola a tod@s,
Pues simplemente decir que hemos generado unos nuevos ejecutables de la aplicación.
Estos incluyen dos grandes diferencias (además de nuevas operaciones para la caracterización):
- Parte del manual de ayuda (aunque esperamos tener terminado lo principal en un par de días)
- Extensión mediantes plugins.
¿Que quiere decir extensión mediante plugins? Pues que ahora nuestra aplicación la tenemos dividida en componentes (plugins). En concreto cuatro (por ahora):
- com.coolimagingproject.coolimaging (la aplicación principal)
- com.coolimagingproject.colorOperations (Operaciones para cambio de espacios de color)
- com.coolimagingproject.basicImageProcessingOperations (Operaciones basicas de tratamiento de imágenes)
- com.coolimagingproject.help (manual de ayuda)
Estos componentes se encuentran en la carpeta plugins dentro de la carpeta coolimaging.
¿Que ventaja aporta esto? Pues una vez terminada la aplicación principal podemos implementar nuevas operaciones sin tener que tocar la aplicación principal. Incluso mejor, un usuario con conocimientos de programación puede añadir nuevas operaciones sin saber nada de nuestra aplicación. U otras, como que cuando terminemos el manual de ayuda solo habrá que sustituir el plugin com.coolimagingproject.help por el nuevo que generemos, sin tener que volver a generar todo el ejecutable.
Para poder descargarlos aquí.
-
Añadido punto de extensión
Publicado el 28 28Europe/Berlin Marzo 28Europe/Berlin 2009 Sin comentarios aún ...Siempre hemos hablado de darle soporte a la aplicación para que ésta sea ampliable facilmente con nuevas operaciones. !Hoy es el día en el se ha convertido en realidad!
Ahora podemos desarrollar plugins externos a nuestra aplicación a partir de un punto de extensión y añadir nuevas operaciones de forma fácil.
Esto tiene la gran ventaja, que la persona que programe estas nuevas operaciones no tiene porque tener conocimiento del resto de la aplicación, sino que sólo se deberá centrar en la implementación de la misma.Ahora que ya lo tenemos hecho, vamos a centrar nuestros esfuerzos en hacer manuales y pruebas para que quien quiera pueda colaborar en el proyecto creando nuevas y mejores operaciones.
-
Creados ejecutables Alpha
Publicado el 17 17Europe/Berlin Marzo 17Europe/Berlin 2009 4 comentariosHemos creado los primeros ejecutables de la aplicación cool Imaging.
No tienen toda la funcionalidad que nos gustaría, pero se puede empezar a trastear.
Aquí se pueden encontrar los ejecutables
Los ejecutables de linux presentan problemas en la presentación de los nombres (Lo solventaremos lo antes posible).
Puede ser que si tienes la configuración del ordenador en inglés aparezca media aplicación en inglés y la otra media en español (Debido a que no tenemos la internacionalización acabada)Si presenta algún problema en la instalación, aquí puedes encontrar una pequeña ayuda INSTALL
Para cualquier duda, sugerencia… agradeceríamos que se hiciera a través de este post o a la dirección de correo coolimaging@gmail.com
-
Trabajando en la Caracterización
Publicado el 4 04Europe/Berlin Marzo 04Europe/Berlin 2009 Sin comentarios aún ...Tras los exámenes y más tranquilos, estamos ahora más centrados en la caracterización.
Hicimos un primer diseño para la caracterización, que no fue tan bueno como pensabamos, y lo tuvimos que rehacer.
Ahora mismo nos encontramos implementando el nuevo diseño para poder almacenar los datos de caracterización de las imágenes. Aunque gracias al diseño inicial del menú que realizamos para las operaciones de tratamiento de imágenes, hemos podido reutilizar practicamente todo el código (haciendo algunos cambios) para la caracterización.
Hemos intentando que el modo de trabajar con las operaciones de caracterización sea el mismo que el que usamos para las operaciones de tratamiento de imágenes, así la homogeneidad de la aplicación es mayor haciendose más fácil de usar. Como resultado, tenemos el menú de operaciones creado y la carga de operaciones, aunque todavía no tenemos ninguna operación creada.Además, hemos realizado una vista de thumbnails que aprovechará la caracterización cuando esté terminada. En un futuro, el usuario podrá seleccionar desde esta pantalla las imágenes sobre las que quiere realizar una batería de operaciones de caracterización.
Mostramos algunas capturas de pantalla de la aplicación (también mostramos la funcionalidad de los histogramas):
-
Seguimos añadiendole Funcionalidad a la aplicación
Publicado el 3 03Europe/Berlin Febrero 03Europe/Berlin 2009 1 comentarioAunque como ya dijimos en la entrada anterior (nos encontramos en una nueva fase del proyecto), no dejamos de lado el añadirle nueva funcionalidad a la aplicación para que la haga más completa y atractiva.
Algunas de las nuevas funcionalidades están relacionadas con la internacionalización, aunque no está terminada aún, o la insercción de nuevos menús.
Aquí dejamos unas capturas de pantalla de la aplicación, esperemos que os gusten.
-
Comienza la siguiente fase
Publicado el 26 26Europe/Berlin Enero 26Europe/Berlin 2009 Sin comentarios aún ...Tras estos tres primeros meses dándonos tortas contra el Eclipse RCP, JAI y Java2D, hemos llegado a un primer modelo de nuestra aplicación, dando ya por finalizado, salvo detalles menores, la parte relativa al tratamiento digital de imágenes.
Actualmente, Cool Imaging es una aplicación que, dentro de un entorno bastante intuitivo, permite al usuario manipular imágenes mediante clásicos operadores de tratamiento de imágenes.
Además, actualmente, la aplicación está diseñada de tal modo que el añadir nuevas operaciones de tratamiento de imágenes puede hacerse sin excesiva dificultad, y, mejor aún, sin necesidad de modificar los archivos binarios (es decir, puede hacerse de forma “externa”). Basta que el usuario proporcione el archivo binario .class de la clase que implementa dicha operación, y ésta es automáticamente añadida a la aplicación.
El siguiente paso, que será el último y el más duro, es el relacionado con la caracterización de imágenes. Ahora toca diseñar todo aquello relativo a la caracterización de imágenes digitales. Ésta es, supuestamente, la parte más dura, pero partiendo de la base de que la arquitectura actualmente creada es bastante simple y flexible, no debería suponer un gran problema el llevarla a cabo.
En este enlace se encuentra disponible la última versión de la documentación.
Mostramos capturas de pantalla de la aplicación:
-
Problemas creando una imagen con una región de interés asociada
Publicado el 19 19Europe/Berlin Enero 19Europe/Berlin 2009 2 comentariosTras ir creando la aplicación con bastante soltura a pesar de los problemas encontrados anteriormente, nos hemos topado con un problema que es crucial en el desarrollo de nuestra aplicación.
El problema se ha encontrado en la selección de una región de interés en una imagen. La solución que habíamos decidido adoptar era la de seleccionar la región de interés sobre una imagen y que a partir de ésta imagen se generara una nueva imagen donde solo se mostrara la región de interés, y el resto de la imagen en negro (por ejemplo).
Nos hemos encontrado que no éramos capaces de generar esta nueva imagen, o al menos generarla para cualquier tipo de imagen, no importando, por ejemplo, el sistema de color utilizado o el número de bandas que contenga un pixel.
Viendo que los conocimientos sobre JAI y JAVA 2D no eran los adecuados, nos hemos dedicado a aprender como se almacena una imagen en JAI y como se utiliza ésta.
Al final, hemos conseguido llegar a una solución que parece factible y generalizado a cualquier imagen (falta probar esta parte de forma exhaustiva), aunque pensamos que no es lo más óptimo a lo que podemos llegar, puesto que en nuestra aplicación es bastante importante el tiempo de respuesta al usuario.
Ahora, estamos estudiando como mejorar esta parte e integrarla en el resto de la aplicación.
Os mantendremos informado con nuevas noticias.

















Comentarios recientes