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.camera;
31  
32  import org.openimaj.math.geometry.point.Point2d;
33  import org.openimaj.math.geometry.point.Point2dImpl;
34  import org.openimaj.math.geometry.point.Point3d;
35  import org.openimaj.math.matrix.MatrixUtils;
36  
37  import Jama.Matrix;
38  
39  /**
40   * A model of the extrinsic parameters of a pinhole (projective) camera
41   * (translation in 3d space, and 3d rotation matrix), coupled with the camera's
42   * intrinsic parameters.
43   * 
44   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
45   */
46  public class Camera {
47  	/**
48  	 * The intrinsic parameters of this camera
49  	 */
50  	public CameraIntrinsics intrinsicParameters;
51  
52  	/**
53  	 * The rotation of this camera in world coordinates
54  	 */
55  	public Matrix rotation;
56  
57  	/**
58  	 * The position of this camera in world coordinates
59  	 */
60  	public Point3d translation;
61  
62  	/**
63  	 * Compute the homography of this camera to the z=0 plane based on it's
64  	 * parameters: H = KA, where A = [r1 r2 t] and r1 and r2 are the first and
65  	 * second columns of the rotation matrix, and K is the calibration matrix.
66  	 * 
67  	 * @return the camera's homography
68  	 */
69  	public Matrix computeHomography() {
70  		final Matrix A = rotation.copy();
71  		A.set(0, 2, translation.getX());
72  		A.set(1, 2, translation.getY());
73  		A.set(2, 2, translation.getZ());
74  
75  		final Matrix H = intrinsicParameters.calibrationMatrix.times(A);
76  		MatrixUtils.times(H, 1.0 / H.get(2, 2));
77  
78  		return H;
79  	}
80  
81  	/**
82  	 * Project a 2d point (technically a 3d point on the z=0 world plane)
83  	 * 
84  	 * @param pt
85  	 *            the point to project in world coordinates
86  	 * @return the image coordinates
87  	 */
88  	public Point2d project(Point2d pt) {
89  		final Matrix H = this.computeHomography();
90  
91  		final Point2d p = pt.transform(H);
92  
93  		return intrinsicParameters.applyDistortion(p);
94  	}
95  
96  	/**
97  	 * Project a 3d point onto the image plane
98  	 * 
99  	 * @param pt
100 	 *            the point to project in world coordinates
101 	 * @return the image coordinates
102 	 */
103 	public Point2d project(Point3d pt) {
104 		final Matrix ptm = new Matrix(new double[][] { { pt.getX() }, { pt.getY() }, { pt.getZ() }, { 1 } });
105 		final double[][] rv = rotation.getArray();
106 		final Matrix Rt = new Matrix(new double[][] {
107 				{ rv[0][0], rv[0][1], rv[0][2], translation.getX() },
108 				{ rv[1][0], rv[1][1], rv[1][2], translation.getY() },
109 				{ rv[2][0], rv[2][1], rv[2][2], translation.getZ() },
110 		});
111 		final Matrix ARt = intrinsicParameters.calibrationMatrix.times(Rt);
112 
113 		final Matrix pr = ARt.times(ptm);
114 
115 		final Point2dImpl p = new Point2dImpl(pr.get(0, 0) / pr.get(2, 0), pr.get(1, 0) / pr.get(2, 0));
116 
117 		return intrinsicParameters.applyDistortion(p);
118 	}
119 }