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.transform;
31  
32  import java.util.HashMap;
33  import java.util.Map;
34  
35  import org.openimaj.image.FImage;
36  import org.openimaj.math.geometry.point.Point2d;
37  import org.openimaj.math.geometry.point.Point2dImpl;
38  import org.openimaj.math.geometry.shape.Shape;
39  
40  /**
41   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
42   * @author Sina Samangooei (ss@ecs.soton.ac.uk)
43   *
44   * Perform a set of matrix transforms on a set of images and construct a single image containing all the pixels (or a window of the pixels)
45   * in the projected space. 
46   */
47  public class FProjectionProcessor extends ProjectionProcessor<Float, FImage> {
48  	
49  	/**
50  	 * Perform projection but only request data for pixels within the windowed range provided. Specify the background colour, i.e. the value of pixels
51  	 * with no data post projection.
52  	 * @param windowMinC left X
53  	 * @param windowMaxC right X
54  	 * @param windowMinR top Y
55  	 * @param windowMaxR bottom Y
56  	 * @param backgroundColour background colour of pixels with no data
57  	 * @return projected image within the window
58  	 */
59  	@Override
60  	public FImage performProjection(int windowMinC , int windowMaxC , int windowMinR , int windowMaxR , Float backgroundColour) {
61  		FImage output = null;
62  		output = new FImage(windowMaxC-windowMinC,windowMaxR-windowMinR);
63  		if(backgroundColour!=null)
64  			output.fill(backgroundColour);
65  		Shape[][] shapeRects = this.getCurrentShapes();
66  		for(int y = 0; y < output.getHeight(); y++)
67  		{
68  			for(int x = 0; x < output.getWidth(); x++){
69  				Point2d realPoint = new Point2dImpl(windowMinC + x,windowMinR + y);
70  				int i = 0;
71  				for (int j = 0; j < shapeRects.length; j++) {
72  					if(backgroundColour == null || isInside(j,shapeRects,realPoint)){
73  						double[][] transform = this.transformsInverted.get(i).getArray();
74  						
75  						float xt = (float)transform[0][0] * realPoint.getX() + (float)transform[0][1] * realPoint.getY() + (float)transform[0][2];
76  						float yt = (float)transform[1][0] * realPoint.getX() + (float)transform[1][1] * realPoint.getY() + (float)transform[1][2];
77  						float zt = (float)transform[2][0] * realPoint.getX() + (float)transform[2][1] * realPoint.getY() + (float)transform[2][2];
78  						
79  						xt /= zt;
80  						yt /= zt;
81  						FImage im = this.images.get(i);
82  						if(backgroundColour!=null)
83  							output.pixels[y][x] = im.getPixelInterp(xt, yt,backgroundColour);
84  						else
85  							output.pixels[y][x] = im.getPixelInterp(xt, yt);
86  					}
87  					i++;
88  				}
89  			}
90  		}
91  		return output;
92  	}
93  	
94  	/**
95  	 * Perform blended projection but only request data for pixels within the windowed range provided. Specify the background colour, i.e. the value of pixels
96  	 * with no data post projection. This blends any existing pixels to newly added pixels
97  	 * @param windowMinC left X
98  	 * @param windowMaxC right X
99  	 * @param windowMinR top Y
100 	 * @param windowMaxR bottom Y
101 	 * @param backgroundColour background colour of pixels with no data
102 	 * @return projected image within the window
103 	 */
104 	@Override
105 	public FImage performBlendedProjection(int windowMinC , int windowMaxC , int windowMinR , int windowMaxR , Float backgroundColour) {
106 		FImage output = null;
107 		output = new FImage(windowMaxC-windowMinC,windowMaxR-windowMinR);
108 		Map<Integer,Boolean> setMap = new HashMap<Integer,Boolean>();
109 		FImage blendingPallet = output.newInstance(2, 1);
110 		for(int y = 0; y < output.getHeight(); y++)
111 		{
112 			for(int x = 0; x < output.getWidth(); x++){
113 				Point2d realPoint = new Point2dImpl(windowMinC + x,windowMinR + y);
114 				int i = 0;
115 				for(Shape s : this.projectedShapes){
116 					if(s.isInside(realPoint)){
117 						double[][] transform = this.transformsInverted.get(i).getArray();
118 						
119 						float xt = (float)transform[0][0] * realPoint.getX() + (float)transform[0][1] * realPoint.getY() + (float)transform[0][2];
120 						float yt = (float)transform[1][0] * realPoint.getX() + (float)transform[1][1] * realPoint.getY() + (float)transform[1][2];
121 						float zt = (float)transform[2][0] * realPoint.getX() + (float)transform[2][1] * realPoint.getY() + (float)transform[2][2];
122 						
123 						xt /= zt;
124 						yt /= zt;
125 						Float toSet = null;
126 						if(backgroundColour!=null)
127 							toSet = this.images.get(i).getPixelInterp(xt, yt,backgroundColour);
128 						else
129 							if(setMap.get(y * output.getWidth() + x)!=null)
130 								toSet = this.images.get(i).getPixelInterp(xt, yt,output.getPixelInterp(x, y));
131 							else
132 								toSet = this.images.get(i).getPixelInterp(xt, yt);
133 						// Blend the pixel with the existing pixel
134 						if(setMap.get(y * output.getWidth() + x)!=null){
135 							blendingPallet.pixels[0][1] = toSet;
136 							blendingPallet.pixels[0][0] = output.getPixel(x, y);
137 							
138 							toSet = blendingPallet.getPixelInterp(0.1, 0.5);
139 						}
140 						setMap.put(y * output.getWidth() + x,true);
141 						output.pixels[y][x] = toSet;
142 					}
143 					i++;
144 				}
145 			}
146 		}
147 		return output;
148 	}
149 
150 }