Image J Plugin Writing 2 Muharrem Mercimek Lab
Image. J Plugin Writing 2 Muharrem Mercimek Lab Presentation 15 May 2009 1
Contents • • • Why Image. J? Image. J Plugins Plug writing samples 2
Why Image. J? • Image. J is a public domain Java image processing program. • Rather than using expensive, large size commercial image-processing tools developing your own software. • Interactivity and ease of use is are main concerns of software developers, scientists, engineers working with images. • Image. J is platform-independent. Image. J is pure Java application and can run on any computer with and JRE. Image. J also can be used as an applet within a browser though it is mostly run as a stand-alone application. • Dynamic execution model allows new modules (plugins). 3
Image. J Plugins • A basic knowledge of Java programming is required towards Image. J plugin writing. • Plugins can be created, edited, compiled, invoked, and organized through the Plugin menu of the Image. J’ s main menu. • JRE and a JDK are needed to be installed on your computer. • Plugins Folder Image. J user plugins have to be located in a sub-folder (since version 1. 20) or directly in the folder called “plugins”. The name of your plugin will be seen under the plugins menu. Sub-folder will be submenus of Plugins menu. 4
Image. J Plugins. java file name should contain under score _, to be automatically inserted to the plugin menu list C: Image. Jplugins Write Image. J code. java Reference to the plugin execution can be replaced manually to another place in the Image. J menu tree Plugins-Shortcuts-Install Plugin Edit, Compile and Run Plugins. class file . java file should be under plugins folder C: Image. Jplugins Image. J locates all the plugins related to their physical locations under Plugins folder automatically Plugin: requires no image to be open to start a plugin Plug. In. Filter: the currently active image is passed to the plugin when started. For image processing operations Plug. In. Filter is used mostly Plug. In. Filter must at least implement methods, setup(), and run(). int setup( String arg, Image. Plus imp) Image. J calls this method first to verify the capabilities of the plugin match the target image. void run (Image. Processor ip) Actual work is done here, It passed a single argument ip, an object of type Image. Processor 5
Image. J Plugins 6
Image. J Plugins 7
import import ij. *; Stack. Avarage application, averages the stack ij. gui. *; ij. plugin. filter. Plug. In. Filter; The java and Image. J class packages they ij. process. *; java. awt. *; are imported Name of the plugin is Stack. Average_ public class Stack. Average_ implements Plug. In. Filter { Plug. In. Filter type plugin, it protected Image. Plus imp; public int setup(String arg, Image. Plus imp){ this. imp=imp; return DOES_8 G+STACK_REQUIRED; Plugin can handle 8 bit } Plugin’s run method receives an Image. Processor object ip, public void run (Image. Processor ip){ Image. Stack stack=imp. get. Stack(); Image. Stack stack 2=imp. get. Stack(); needs an active, opened images, and image stack is required Image. Processor class holds the pixel array and does the actual work on the image In a Plug. In. Filter currently open stack can be retrieved from the current Image. Plus object int[] sum; byte[] pixels; int w=ip. get. Width(); int h=ip. get. Height(); int dimension =ip. get. Width()*ip. get. Height(); sum=new int[dimension]; Code-1 for (int i=1; i<=stack. get. Size(); i++){ pixels=(byte[]) stack. get. Pixels(i); for(int j=1; j<dimension; j++){ sum[j]+=0 xff&pixels[j]; } } To access the pixels get. Pixels(int slice. Number) are used byte[] average= new byte[dimension]; int[ ] pixels get. Pixels(), or for (int j=0; j<dimension; j++){ average[j]=(byte)((sum[j]/stack. get. Size()) & 0 xff); } Image. Plus imp 2=New. Image. create. Image("Average", w, h, 1, 8, New. Image. FILL_WHITE); Image. Processor ip 2=imp 2. get. Processor(); Each image is based on an image processor ip 2. set. Pixels(average); the type of it depends on the type of the image. int w 2=ip. get. Width(); set. Pixels(int[]) with an Image. Processor objects is int h 2=ip. get. Height(); imp 2. show(); to set the pixels using an array IJ. write((imp. get. Stack. Size())+""); IJ. write(stack. get. Height()+""); IJ. write(stack. get. Width()+""); } } 8 used
import ij. *; import ij. plugin. Plug. In; All we have to implement is the run method. We do not need the argument, so we ignore it. public class Message_Test implements Plug. In { We are going to use some utility functions, public void run(String arg) { which are mainly in ij. IJ. * package IJ. show. Status("Plugin Message Test started. "); IJ. show. Progress(0. 0); Progress bar on the main menu console IJ. error("I need user input!"); Code-2 String name = IJ. get. String("Please enter your name: ", "me"); IJ. show. Progress(0. 5); IJ. write(" Color Inverter. . . "); Runs another plugin IJ. run. Plug. In("Color. Inverter_", ""); IJ. show. Progress(1. 0); IJ. show. Message("Finished. ", name+", thank you for running this plugin"); } } 9
Byte. Processor img=new Byte. Processor(width, height); double value=0; double distance=0; int sizex=img. get. Width(); int sizey=img. get. Height(); import import int xcenter=(sizex)/2+1; int ycenter=(sizey)/2+1; ij. *; ij. process. *; ij. gui. *; ij. measure. *; ij. plugin. *; import java. awt. *; Code-3 public class Gaussian_Filter implements Plug. In { static double cutoff =50; static double dc_level =255; public void run(String arg) { if(!show. Dialog()) return; . . } for(int y=0; y<sizey; y++) { for (int x=0; x<sizex; x++) { distance=Math. abs(x-xcenter)*Math. abs(x-xcenter)+ Math. abs(y-ycenter)*Math. abs(y-ycenter); distance=Math. sqrt(distance); value=dc_level*Math. exp((-1*distance)/ (1. 4426925*cutoff)); img. put. Pixel. Value(x, y, value); } } Image. Plus img_filter 2=new Image. Plus("2 d_filter", img); img_filter 2. show(); Image. Stack stack 2=new Image. Stack(sizex, sizey); IJ. write(sizex+""); IJ. write(sizey+""); public boolean show. Dialog() { Generic. Dialog gd=new Generic. Dialog("parameters"); gd. add. Numeric. Field("Cutoff frequency: ", cutoff, 1); gd. add. Numeric. Field("DC-level: ", dc_level, 1); gd. add. Checkbox("reset", false); gd. show. Dialog(); if(gd. was. Canceled()) return false; cutoff=gd. get. Next. Number(); dc_level=gd. get. Next. Number(); boolean reset=gd. get. Next. Boolean(); return true; } } 10
import import ij. *; ij. gui. *; ij. process. *; java. awt. *; java. io. *; ij. plugin. Plug. In; public class Joint_Histogram implements Plug. In{ private static int index 1; private static int index 2; private static boolean create. File; private static String deault. Directory=""; public void run (String arg) { int[] w. List=Window. Manager. get. IDList(); if (w. List==null) { IJ. error("No windows open"); return; } String[] titles=new String[w. List. length]; for (int i=0; i<w. List. length; i++){ Image. Plus img= Window. Manager. get. Image(w. List[i]); Code-4 } if(img!=null) titles[i]=img. get. Title(); else titles[i]=""; IJ. write(index 1+" "+index 2+" "+titles. length); if (index 1>=titles. length) index 1=0; if (index 2>=titles. length) index 2=0; Generic. Dialog gd=new Generic. Dialog(" Joint Histogram", IJ. get. Instance()); gd. add. Choice("image #1: ", titles[index 1]); gd. add. Choice("image #2: ", titles[index 2]); gd. add. Checkbox("Create file: ", create. File); gd. show. Dialog(); if(gd. was. Canceled()) return; index 1=gd. get. Next. Choice. Index(); index 2=gd. get. Next. Choice. Index(); create. File=gd. get. Next. Boolean(); String title 1=titles[index 1]; String title 2=titles[index 2]; Image. Plus imp 1=Window. Manager. get. Image(w. List[index 1]); Image. Plus imp 2=Window. Manager. get. Image(w. List[index 2]); if(imp 1. get. Type()!=0 || imp 1. get. Type()!=imp 2. get. Type()) IJ. show. Message(“Joint Histogram", "both images should be 8 -bit grayscale"); } Joint_H(imp 1, imp 2); 11
public void Joint_H(Image. Plus imp 1, Image. Plus imp 2) { Image. Processor ip 1=imp 1. get. Processor(); Image. Processor ip 2=imp 2. get. Processor(); boolean unsigned=true; int width=imp 1. get. Width(); int height=imp 1. get. Height(); Float. Processor ip 3=new Float. Processor( 256, 256); int z 1, z 2, count=0; int value; int[] histogram; for (int y=0; y<height; y++) for (int x=0; x<width; x++) { z 1=ip 1. get. Pixel(x, y); z 2=ip 2. get. Pixel(x, y); value=ip 3. get. Pixel(z 1, z 2); value++; ip 3. put. Pixel. Value(z 1, 255 -z 2, value); } } Image. Plus img 3=new Image. Plus("histogram", ip 3); img 3. update. And. Draw(); img 3. show(); 12
import import ij. *; ij. process. *; ij. gui. *; ij. plugin. filter. Convolver; ij. plugin. filter. Plug. In. Filter; public class Image_filtering implements Plug. In. Filter { Image. Plus imp; public int setup(String arg, Image. Plus imp) { this. imp=imp; return DOES_8 G+NO_CHANGES; } Code-4 public void run(Image. Processor ip) { float[] h={-1, -1, 0, 0, 0, 1, 1, 1}; Convolver cv=new Convolver(); cv. convolve(ip, h, 3, 3); imp. update. And. Draw(); } } 13
- Slides: 13