001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.pub.morphology.old; 011 012import ij.*; 013import ij.process.Blitter; 014import ij.process.ByteProcessor; 015import ij.process.ImageProcessor; 016 017/** 018 * This class is obsolete (replaced by {@link imagingbook.pub.morphology.BinaryMorphologyFilter}). 019 * 020 */ 021@Deprecated 022public class BinMorpher { 023 024 int[][] se; //structuring element 025 026 public static enum Operation { 027 Dilation, Erosion, Opening, Closing, Outline; 028 } 029 030 public static String[] getOpNames() { 031 Operation[] ops = Operation.values(); 032 String[] strgs = new String[ops.length]; 033 int i = 0; 034 for (Operation op: ops) { 035 strgs[i++] = op.name(); 036 } 037 return strgs; 038 } 039 040 041 // constructor methods 042 043 BinMorpher(){ 044 } 045 046 public BinMorpher(int[][] structuringElement){ 047 se = (int[][]) structuringElement.clone(); 048 } 049 050 // utility methods 051 public void showFilter() { 052 showFilter(se, "Structuring Element"); 053 } 054 055 public void showFilter(int[][] filter, String title){ 056 int w = filter[0].length; 057 int h = filter.length; 058 ImageProcessor ip = new ByteProcessor(w,h); 059 for (int v = 0; v < h; v++) { 060 for (int u = 0; u < w; u++) { 061 if (filter[v][u] == 1) 062 ip.putPixel(u, v, 255); 063 else 064 ip.putPixel(u, v, 0); 065 } 066 } 067 ip.invertLut(); 068 ImagePlus win = new ImagePlus(title,ip); 069 win.show(); 070 } 071 072 public void apply(ImageProcessor ip, Operation op){ 073 switch(op) { 074 case Dilation: this.dilate(ip,se); break; 075 case Erosion: this.erode(ip,se); break; 076 case Opening: this.open(ip,se); break; 077 case Closing: this.close(ip,se); break; 078 case Outline: this.outline(ip); break; 079 default: throw new Error("BinMorpher: unknown operation " + op); 080 } 081 } 082 083 // morphology methods 084 085 void dilate(ImageProcessor ip, int[][] H){ 086 if (H == null) { 087 IJ.error("no structuring element"); 088 return; 089 } 090 091 //assume that the hot spot of se is at its center (ic,jc) 092 int ic = (H[0].length - 1) / 2; 093 int jc = (H.length - 1) / 2; 094 int N = H.length * H[0].length; 095 096 ImageProcessor tmp = ip.createProcessor(ip.getWidth(),ip.getHeight()); 097 098 int k = 0; 099 IJ.showProgress(k,N); 100 for (int j = 0; j < H.length; j++) { 101 for (int i = 0; i < H[j].length; i++) { 102 if (H[j][i] > 0) { // this pixel is set 103 // copy image into position (u-ch,v-cv) 104 tmp.copyBits(ip, i - ic, j - jc, Blitter.MAX); 105 } 106 IJ.showProgress(k++, N); 107 } 108 } 109 ip.copyBits(tmp, 0, 0, Blitter.COPY); 110 111 } 112 113 void erode(ImageProcessor ip, int[][] H){ 114 //dilates the background 115 ip.invert(); 116 dilate(ip,reflect(H)); 117 ip.invert(); 118 } 119 120 void open(ImageProcessor ip, int[][] H){ 121 erode(ip,H); 122 dilate(ip,H); 123 } 124 125 void close(ImageProcessor ip, int[][] H){ 126 dilate(ip,H); 127 erode(ip,H); 128 } 129 130 void outline(ImageProcessor ip){ 131 int[][] H = {{0,1,0}, 132 {1,1,1}, 133 {0,1,0} 134 }; 135 ImageProcessor foreground = ip.duplicate(); 136 erode(foreground,H); 137 ip.copyBits(foreground,0,0,Blitter.DIFFERENCE); 138 } 139 140 int[][] reflect(int[][] se) { 141 // mirrors the structuring element around the center (hot spot) 142 // used to implement erosion by a dilation 143 int N = se.length; // number of rows 144 int M = se[0].length; // number of columns 145 int[][] fse = new int[N][M]; 146 for (int j = 0; j < N; j++) { 147 for (int i = 0; i < M; i++) { 148 fse[j][i] = se[N - j - 1][M - i - 1]; 149 } 150 } 151 return fse; 152 } 153 154} 155 156 157 158 159