|
Binary |
|
package ij.plugin.filter; import ij.*; import ij.gui.*; import ij.process.*; import java.awt.*; /** Implements the commands in the Process/Binary submenu. */ public class Binary implements PlugInFilter { String arg; ImagePlus imp; static int iterations = 1; static int count = 1; int foreground, background; public int setup(String arg, ImagePlus imp) { this.arg = arg; this.imp = imp; IJ.register(Binary.class); if (arg.equals("options")) { showDialog(); return DONE; } if (imp!=null && (imp.getType()==ImagePlus.GRAY8 || imp.getType()==ImagePlus.COLOR_256)) { ImageStatistics stats = imp.getStatistics(); if (stats.histogram[0]+stats.histogram[255]!=stats.pixelCount) { IJ.error("8-bit binary (black and white only) image required."); return DONE; } } return IJ.setupDialog(imp, DOES_8G+DOES_8C+SUPPORTS_MASKING); } public void run(ImageProcessor ip) { foreground = Prefs.blackBackground?255:0; if (ip.isInvertedLut()) foreground = 255 - foreground; background = 255 - foreground; ip.setSnapshotCopyMode(true); if (arg.equals("erode")) erode(ip); else if (arg.equals("dilate")) dilate(ip); else if (arg.equals("open")) open(ip); else if (arg.equals("close")) close(ip); else if (arg.equals("outline")) outline(ip); else if (arg.equals("skel")) skeletonize(ip); ip.setSnapshotCopyMode(false); } void erode(ImageProcessor ip) { for (int i=0; i<iterations; i++) ((ByteProcessor)ip).erode(count, background); } void dilate(ImageProcessor ip) { for (int i=0; i<iterations; i++) ((ByteProcessor)ip).dilate(count, background); } void open(ImageProcessor ip) { for (int i=0; i<iterations; i++) ((ByteProcessor)ip).erode(count, background); for (int i=0; i<iterations; i++) ((ByteProcessor)ip).dilate(count, background); } void close(ImageProcessor ip) { for (int i=0; i<iterations; i++) ((ByteProcessor)ip).dilate(count, background); for (int i=0; i<iterations; i++) ((ByteProcessor)ip).erode(count, background); } void outline(ImageProcessor ip) { if (Prefs.blackBackground) ip.invert(); ((ByteProcessor)ip).outline(); if (Prefs.blackBackground) ip.invert(); } void skeletonize(ImageProcessor ip) { if (Prefs.blackBackground) ip.invert(); boolean edgePixels = hasEdgePixels(ip); ImageProcessor ip2 = expand(ip, edgePixels); ((ByteProcessor)ip2).skeletonize(); ip = shrink(ip, ip2, edgePixels); if (Prefs.blackBackground) ip.invert(); } void showDialog() { GenericDialog gd = new GenericDialog("Binary Options"); gd.addNumericField("Iterations (1-25):", iterations, 0, 3, ""); gd.addNumericField("Count (1-8):", count, 0, 3, ""); gd.addCheckbox("Black Background", Prefs.blackBackground); gd.showDialog(); if (gd.wasCanceled()) return; int n = (int)gd.getNextNumber(); Prefs.blackBackground = gd.getNextBoolean(); if (n>25) n = 25; if (n<1) n = 1; iterations = n; count = (int)gd.getNextNumber(); if (count<1) count = 1; if (count>8) count = 8; } boolean hasEdgePixels(ImageProcessor ip) { int width = ip.getWidth(); int height = ip.getHeight(); boolean edgePixels = false; for (int x=0; x<width; x++) { // top edge if (ip.getPixel(x, 0)==foreground) edgePixels = true; } for (int x=0; x<width; x++) { // bottom edge if (ip.getPixel(x, height-1)==foreground) edgePixels = true; } for (int y=0; y<height; y++) { // left edge if (ip.getPixel(0, y)==foreground) edgePixels = true; } for (int y=0; y<height; y++) { // right edge if (ip.getPixel(height-1, y)==foreground) edgePixels = true; } return edgePixels; } ImageProcessor expand(ImageProcessor ip, boolean hasEdgePixels) { if (hasEdgePixels) { ImageProcessor ip2 = ip.createProcessor(ip.getWidth()+2, ip.getHeight()+2); if (foreground==0) { ip2.setColor(255); ip2.fill(); } ip2.insert(ip, 1, 1); //new ImagePlus("ip2", ip2).show(); return ip2; } else return ip; } ImageProcessor shrink(ImageProcessor ip, ImageProcessor ip2, boolean hasEdgePixels) { if (hasEdgePixels) { int width = ip.getWidth(); int height = ip.getHeight(); for (int y=0; y<height; y++) for (int x=0; x<width; x++) ip.putPixel(x, y, ip2.getPixel(x+1, y+1)); } return ip; } }
|
Binary |
|