UNIVERSIDADE FEDERAL DE MINAS GERAIS INSTITUTO DE CIÊNCIAS EXATAS DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO NÚCLEO DE PROCESSAMENTO DIGITAL DE IMAGENS (NPDI) Tutorial Implementando plugins para o ImageJ Flávio Augusto Rocha Bertholdo Versão 1.1 Belo Horizonte, 22 de abril de 2007 1. Introdução O ImageJ [1] é um programa de domínio público, desenvolvido em Java, que permite exibir, analisar, processar, salvar e imprimir imagens digitais. Ele pode ser executado em qualquer computador que tenha uma máquina virtual Java instalada. Ele pode trabalhar com imagens de 8, 16 ,e 32 bits e nos mais variados formatos como TIFF, GIF, JPEG, BMP, DICOM, FITS e "raw". O sistema pode trabalhar com diversas imagens simultaneamente, limitado apenas pela quantidade de memória disponível. Ele também pode executar diversas funções de processamento nas imagens como alterações de contraste, suavização, aguçamento, detecção de bordas, aplicação de filtros. Também suporta transformações geométricas e possui diversos recursos para analise. As imagens podem ser ampliadas até 32:1 ou reduzidas até 1:32. Uma das características mais interessantes do ImageJ é ter sido implementado através de uma arquitetura aberta. Desta forma, novas funcionalidades podem ser adicionadas ao sistema através da implementação de plugins escritos em Java. O sistema possui seu próprio editor Java, porém o código pode ser escrito utilizando qualquer editor. A compilação dos plugins é bastante simples e pode ser realizadas com qualquer compilador Java. O desenvolvimento de novos plugins permite aos usuários utilizar o ImageJ como uma plataforma de PDI, onde podese implementar e testar novos algoritmos. Desta forma, pode-se resolver diversos problemas de analise e processamento de imagens de forma simples e rápida. 2. Sobre este tutorial Este tutorial é uma breve introdução sobre a implementação de plugins no ImageJ e foi baseado no excelente trabalho de Werner Bailer, intitulado “Writing ImageJ Plugins–A Tutorial” [2]. Nosso objetivo é apresentar de forma rápida e prática os conhecimentos básicos para a implementação de plugins. Vale destacar que conhecimentos em programação Java e sobre a utilização do ImageJ são pré-requisitos de suma importância. A documentação do ImageJ pode ser encontrada no seguinte endereço: http://rsb.info.nih.gov/ij/docs/index.html. 3. Plugins do ImageJ As funcionalidades oferecidas pelo ImageJ, em seus menus, podem ser ampliadas através da utilização de plugins. Aliás, muitas das funcionalidades padrão do programa são implementadas através de plugins. Um plugin é uma classe Java implementando prédeterminadas interfaces. Além disto, todos os plugins devem ser colocados na pasta “plugins”, que é uma sub-pasta da pasta onde está instalado o ImageJ. Mas para serem exibidas automaticamente no menu “Plugins”, o arquivo da classe deve possuir pelo menos uma sublinhado (underscore) no seu nome, sugerimos utilizar o sublinhado no final do nome da classe. Desde a versão 1.20, é possível criar sub-pastas dentro da pasta “plugins” e colocar os plugins nelas. Desta forma, pode-se simplificar e melhorar a organização dos plugins. Os plugins podem ser escritos no editor próprio do ImageJ (que pode ser acessado através do menu “Plugins/New” ou “Plugins/Edit”) ou com o seu editor de texto preferido. Em qualquer um dos casos, os plugins podem ser compilados e executados através do ImageJ. Se o Implementando Plugins para o ImageJ – Versão 1.1 2 seu sistema operacional já possui um compilador Java instalado, você poderá compilar seus plugins diretamente do ImageJ. A forma mais simples é utilizar o menu “Plugins/Compile and Run”, que abre uma caixa de dialogo para selecionar um arquivo .java, que será compilado em um arquivo class e executado como um plugin. Para instalar novos plugins (por exemplo algum plugin que você baixou da Internet), basta copiar o arquivo .class para a pasta plugins ou para uma sub-pasta dela. O plugin irá aparecer no menu plugins ou em um de seus sub-menus na próxima vez que você iniciar o ImageJ. Ou seja, após instalar um novo plugin é necessário reiniciar o programa para que o mesmo seja exibido no menu. 3.1 Tipos de plugins Existem basicamente dois tipos de plugins: os que não precisam de uma imagem de entrada (implementam a interface PlugIn) e os chamados “plugins filters”, que precisam de uma imagem como entrada (implementam a interface PlugInFilter). Neste tutorial, vamos nos concentrar apenas em exemplos do segundo tipo, por serem os mais utilizados. 4. Exemplos de código Após instalar o ImageJ, se você procurar na pasta de Plugins, você encontrará exemplos que vem com o ImageJ. Vale a pena conferir a analise do código do plugin Inverter_ apresentada em [2]. A seguir, apresentamos dois exemplos de código que ilustram características básicas dos plugins do ImageJ. 4.1 Exemplo 1: Limiarização Simples Este exemplo realiza uma limiarização simples em imagens de 8 bits (tons de cinza), utilizando como limiar o tom de cinza 128. /** Aqui você deve inserir os pacotes necessários */ import ij.*; import ij.plugin.filter.PlugInFilter; import ij.process.*; import ij.gui.*; import ij.plugin.frame.PlugInFrame; import java.awt.*; /** Este ImageJ plugin implementa uma limiarização simples em imagens de 8 bits. Considerações: 1) Filter plug-ins devem implementar a interface PlugInFilter. 2) Plugins que são colocados na pasta "plugins" do ImageJ e possuem pelo menos um underscore no seu nome são instalados automaticamente no menu de Plugins. 3) O nome da classe e o nome do arquivo devem ser os mesmos. 4) Tome cuidado para o nome do plugin não entrar em conflito com plugins já existentes. */ public class Ex1_ implements PlugInFilter { public int setup(String arg, ImagePlus imp) { if (arg.equals("about")) {showAbout(); return DONE;} Implementando Plugins para o ImageJ – Versão 1.1 3 } return DOES_8G+DOES_STACKS; public void run(ImageProcessor ip) { int limiar = 128; byte[] pixels = (byte[])ip.getPixels(); int width = ip.getWidth(); int height = ip.getHeight(); int offset, i, pixel; } } for (int y=0; y<height; y++) { offset = y*width; for (int x=0; x<width; x++) { i = offset + x; pixel = (int) (pixels[i] & 0xff); if (pixel<limiar) pixels[i] = (byte)(0); else pixels[i] = (byte)(255); } } void showAbout() { IJ.showMessage("About Ex1_...", "Este plugin implementa uma limiarização simples\n" + "em imagens de 8 bits." ); } 4.2 Exemplo 2: Equalização de histograma Este plugin implementa uma equalização de histograma em imagens de 8 bits (tons de cinza). Vale destacar a utilização da classe ContrastEnhancer para realizar a equalização do histograma. A utilização desta classe exemplifica a grande capacidade de reutilização de código disponível na arquitetura do ImageJ. Além disto, as alterações não são realizadas na própria imagem de entrada, ou seja, é criada uma nova imagem para exibir os resultados. /** Aqui você deve inserir os pacotes necessários */ import ij.*; import ij.plugin.filter.PlugInFilter; import ij.process.*; import ij.gui.*; import ij.plugin.frame.PlugInFrame; import java.awt.*; import ij.plugin.ContrastEnhancer; /** Este ImageJ plugin implementa uma equalização de histograma em imagens de 8 bits. Considerações: 1) Filter plug-ins devem implementar a interface PlugInFilter. 2) Plugins que são colocados na pasta "plugins" do ImageJ e possuem pelo menos um underscore no seu nome são instalados automaticamente no menu de Plugins. 3) O nome da classe e o nome do arquivo devem ser os mesmos. 4) Tome cuidado para o nome do plugin não entrar em conflito com plugins já existentes. */ Implementando Plugins para o ImageJ – Versão 1.1 4 public class Ex2_ implements PlugInFilter { public int setup(String arg, ImagePlus imp) { if (arg.equals("about")) {showAbout(); return DONE;} return DOES_8G+DOES_STACKS; } public void run(ImageProcessor ip) { byte[] pixels = (byte[])ip.getPixels(); int width = ip.getWidth(); int height = ip.getHeight(); int offset, i, pixel; int limiar = 64; /* Objeto para realizar a equalização do histograma */ ContrastEnhancer CP = new ContrastEnhancer(); ImagePlus imp = NewImage.createByteImage height, 1, NewImage.FILL_WHITE); ImageProcessor nip = imp.getProcessor(); ("Ex2", width, for (int y=0; y<height; y++) { offset = y*width; for (int x=0; x<width; x++) { i = offset + x; pixel = (int) (limiar + (pixels[i] & 0xff)); nip.putPixel(x, y, pixel); } } /* Realizar a equalização do histograma da imagem */ CP.equalize(nip); } /* Exibir a nova imagem */ imp.show(); void showAbout() { IJ.showMessage("About Ex2_...", "Este plugin implementa histograma\n" + "em imagens de 8 bits." ); } } uma equalização de 5. Referências Bibliográficas [1] Introdução ao ImageJ http://rsb.info.nih.gov/ij/docs/intro.html [2] BAILER, Weler. Writing ImageJ Plugins–A Tutorial http://mtd.fh-hagenberg.at/depot/imaging/imagej/ [3] ImageJ Developer Resources http://rsb.info.nih.gov/ij/developer/index.html Implementando Plugins para o ImageJ – Versão 1.1 5