1 package ij.plugin.filter;
12 static int iterations = 1;
21 if (arg.equals(
"options")) {
26 if (arg.equals(
"outline") || arg.equals(
"skel")) {
29 if (stats.histogram[0]+stats.histogram[255]!=stats.pixelCount) {
30 IJ.
error(
"8-bit binary (black and white only) image required.");
39 public void run(ImageProcessor ip) {
40 if (arg.equals(
"erode")) erode(ip);
41 else if (arg.equals(
"dilate")) dilate(ip);
42 else if (arg.equals(
"open")) open(ip);
43 else if (arg.equals(
"close")) close(ip);
44 else if (arg.equals(
"outline")) outline(ip);
45 else if (arg.equals(
"skel")) skeletonize(ip);
49 void erode(ImageProcessor ip) {
50 boolean edgePixels = hasEdgePixels(ip);
52 ImageProcessor ip2 = expand(ip, edgePixels);
53 for (
int i=0; i<iterations; i++)
54 if (blackBackground) ip2.dilate();
else ip2.erode();
55 ip = shrink(ip, ip2, edgePixels);
58 void dilate(ImageProcessor ip) {
59 boolean edgePixels = hasEdgePixels(ip);
60 ImageProcessor ip2 = expand(ip, edgePixels);
61 for (
int i=0; i<iterations; i++)
62 if (blackBackground) ip2.erode();
else ip2.dilate();
63 ip = shrink(ip, ip2, edgePixels);
67 void open(ImageProcessor ip) {
68 boolean edgePixels = hasEdgePixels(ip);
69 ImageProcessor ip2 = expand(ip, edgePixels);
70 for (
int i=0; i<iterations; i++)
71 if (blackBackground) ip2.dilate();
else ip2.erode();
72 for (
int i=0; i<iterations; i++)
73 if (blackBackground) ip2.erode();
else ip2.dilate();
74 ip = shrink(ip, ip2, edgePixels);
77 void close(ImageProcessor ip) {
78 boolean edgePixels = hasEdgePixels(ip);
79 ImageProcessor ip2 = expand(ip, edgePixels);
80 for (
int i=0; i<iterations; i++)
81 if (blackBackground) ip2.erode();
else ip2.dilate();
82 for (
int i=0; i<iterations; i++)
83 if (blackBackground) ip2.dilate();
else ip2.erode();
84 ip = shrink(ip, ip2, edgePixels);
87 void outline(ImageProcessor ip) {
88 if (blackBackground) ip.invert();
89 ((ByteProcessor)ip).outline();
90 if (blackBackground) ip.invert();
93 void skeletonize(ImageProcessor ip) {
94 if (blackBackground) ip.invert();
95 boolean edgePixels = hasEdgePixels(ip);
96 ImageProcessor ip2 = expand(ip, edgePixels);
97 ((ByteProcessor)ip2).skeletonize();
98 ip = shrink(ip, ip2, edgePixels);
99 if (blackBackground) ip.invert();
103 GenericDialog gd =
new GenericDialog(
"Binary Options");
104 gd.addNumericField(
"Iterations (1-25):", iterations, 0);
105 gd.addCheckbox(
"Black Background", blackBackground);
107 if (gd.wasCanceled())
return;
108 int n = (int)gd.getNextNumber();
109 Prefs.blackBackground = blackBackground = gd.getNextBoolean();
115 boolean hasEdgePixels(ImageProcessor ip) {
116 foreground = blackBackground?255:0;
117 if (ip.isInvertedLut())
118 foreground = 255 - foreground;
119 int width = ip.getWidth();
120 int height = ip.getHeight();
121 boolean edgePixels =
false;
122 for (
int x=0; x<width; x++) {
123 if (ip.getPixel(x, 0)==foreground)
126 for (
int x=0; x<width; x++) {
127 if (ip.getPixel(x, height-1)==foreground)
130 for (
int y=0; y<height; y++) {
131 if (ip.getPixel(0, y)==foreground)
134 for (
int y=0; y<height; y++) {
135 if (ip.getPixel(height-1, y)==foreground)
141 ImageProcessor expand(ImageProcessor ip,
boolean hasEdgePixels) {
143 ImageProcessor ip2 = ip.createProcessor(ip.getWidth()+2, ip.getHeight()+2);
148 ip2.insert(ip, 1, 1);
155 ImageProcessor shrink(ImageProcessor ip, ImageProcessor ip2,
boolean hasEdgePixels) {
157 int width = ip.getWidth();
158 int height = ip.getHeight();
159 for (
int y=0; y<height; y++)
160 for (
int x=0; x<width; x++)
161 ip.putPixel(x, y, ip2.getPixel(x+1, y+1));