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