View Javadoc

1   /**
2    * Copyright (c) 2011, The University of Southampton and the individual contributors.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification,
6    * are permitted provided that the following conditions are met:
7    *
8    *   * 	Redistributions of source code must retain the above copyright notice,
9    * 	this list of conditions and the following disclaimer.
10   *
11   *   *	Redistributions in binary form must reproduce the above copyright notice,
12   * 	this list of conditions and the following disclaimer in the documentation
13   * 	and/or other materials provided with the distribution.
14   *
15   *   *	Neither the name of the University of Southampton nor the names of its
16   * 	contributors may be used to endorse or promote products derived from this
17   * 	software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package org.openimaj.image.processing.edges;
31  
32  import org.openimaj.image.FImage;
33  import org.openimaj.image.combiner.ImageCombiner;
34  
35  /**
36   * Non-maximum suppression using magnitude and orientation images.
37   * 
38   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
39   */
40  public class NonMaximumSuppression implements ImageCombiner<FImage, FImage, FImage> {
41  	/**
42  	 * Perform non-maximum suppression.
43  	 * 
44  	 * @param mag Gradient magnitudes
45  	 * @param ori Gradient orientations
46  	 * @return non-maximum suppressed magnitude image.
47  	 */
48  	public static FImage computeSuppressed(FImage mag, FImage ori) {
49  		int height = mag.getHeight(), width = mag.getWidth();
50  	
51  		FImage suppressed = new FImage(width, height);
52  
53  		float p8 = (float) (Math.PI / 8.0);
54  		
55  		//Compute max suppresion	
56  		for (int y=1; y<height-1; y++) {
57  			for (int x=1; x<width-1; x++) {
58  				if (mag.pixels[y][x] > 0) {
59  					float t = (float) (ori.pixels[y][x] - Math.PI/2);   //angle of edge in -pi to pi
60  					
61  					if ((t>=-p8 && t<=p8) || (t<=-7*p8 || t>=7*p8)) { //zero degrees or 180 degrees
62  						if (mag.pixels[y][x] > mag.pixels[y+1][x] && mag.pixels[y][x] >= mag.pixels[y-1][x]) {
63  							suppressed.pixels[y][x] = mag.pixels[y][x];
64  						}
65  					} else if ((t>=3*p8 && t<=5*p8) || (t>=-5*p8 && t<=-3*p8)) { //+/-90 degrees
66  						if (mag.pixels[y][x] >= mag.pixels[y][x+1] && mag.pixels[y][x] > mag.pixels[y][x-1]) {
67  							suppressed.pixels[y][x] = mag.pixels[y][x];
68  						}
69  					} else if ((t>=p8 && t<=3*p8) || (t>=-7*p8 && t<=-5*p8)) { //+45 degrees or -135 degrees
70  						if (mag.pixels[y][x] > mag.pixels[y+1][x-1] && mag.pixels[y][x] >= mag.pixels[y-1][x+1]) {
71  							suppressed.pixels[y][x] = mag.pixels[y][x];
72  						}
73  					} else {
74  						if (mag.pixels[y][x] > mag.pixels[y-1][x-1] && mag.pixels[y][x] >= mag.pixels[y+1][x+1]) {
75  							suppressed.pixels[y][x] = mag.pixels[y][x];
76  						}
77  					}
78  				}
79  			}
80  		}
81  		
82  		return suppressed;
83  	}
84  
85  	/**
86  	 * Perform non-maximum suppression.
87  	 * 
88  	 * @param mag Gradient magnitudes
89  	 * @param ori Gradient orientations
90  	 * @return non-maximum suppressed magnitude image.
91  	 * 
92  	 * @see org.openimaj.image.combiner.ImageCombiner#combine(org.openimaj.image.Image, org.openimaj.image.Image)
93  	 */
94  	@Override
95  	public FImage combine(FImage mag, FImage ori) {
96  		return computeSuppressed(mag, ori);
97  	}
98  }