Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionMapping.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <Base/Common/BIASpragmaStart.hh>
26 
27 #ifndef __ProjectionMapping_hh__
28 #define __ProjectionMapping_hh__
29 
30 #include <Image/BackwardMapping.hh>
31 #include <Geometry/HMatrix.hh>
32 #include <Geometry/Projection.hh>
33 #include <Base/Geometry/HomgPlane3D.hh>
34 
35 
36 namespace BIAS {
37 
38  /** @class ProjectionMapping
39  @ingroup g_filter
40  @brief Maps source pixel to sink pixel of given projections.
41 
42  This class uses backward mapping to convert an image taken by a certain
43  camera src (specified as BIAS::Projection) into an image that another
44  camera sink would have seen at the same time. The original idea was that
45  the two camera share the same pose and that this class handles
46  tasks like fisheye to perspective or radial (un-)distortion. However,
47  meanwhile you can as well change the orientation (e.g. to get a certain
48  perspective cutout of a very wide field of view fisheye). Since all rays
49  still intersect at the same camera center, no scene information is
50  required.
51 
52  If however, your sink has a different camera center than the source you
53  can either assume that all pixels have infinite depth (which actually
54  means that the distance of your cameras can be ignored in comparison to
55  the distance to the scene), which leads to a mapping via the plane at
56  infinity (infinite homography for perspective cameras).
57  Or, you can specify your scene by providing depth information. In that
58  case your scene is assumed to be a textured 2.5D mesh (fully connected),
59  i.e. a single continuous surface in 3D space. You may as well specify
60  that your scene is a single plane in space.
61 
62  This class is an example of the need for adaptive trilinear or even
63  anisotropic filtering, because typically, the local sampling frequency
64  varies and aliasing will occur.
65  Unfortunately, the unproject/project calls within the most inner loop
66  make the whole mapping quite slow. If your mapping is constant (e.g. you
67  want to radial-undistort 1000 images with the same parameters),
68  consider using the prepared lookup table mapping interface
69  (see BackwardMapping).
70 
71 
72  @author Oliver Niemann, koeser
73  @date 2006
74  */
75  template <class InputStorageType, class OutputStorageType>
76  class BIASImage_EXPORT ProjectionMapping
77  : public BackwardMapping<InputStorageType, OutputStorageType> {
78 
79  public:
80 
81  virtual ~ProjectionMapping();
82 
84 
85  /** required because assignment is
86  @author Jan Woetzel */
88 
89  /** required because of const members
90  @author Jan Woetzel */
92  operator=(const ProjectionMapping & src);
93 
94  /** @brief Set your source projection before calling Map() */
95  inline void SetSourceCam(const Projection& P) {
96  SourceP_ = P;
97  calcRelativeRSinkToSource_();
98  }
99 
100  /** @brief Set your sink projection before calling Map(),
101 
102  optional: if your sink has a different camera center it may make sense
103  to pass a depth map for your sink image which is used during mapping.
104  Otherwise infinite depth is assumed for every pixel.
105 
106  @param sinkdepth only pointer is stored, must be valid all time !
107  */
108  inline void SetSinkCam(const Projection& P,
109  const Image<float>* sinkdepth = NULL) {
110  SinkP_ = P;
111  calcRelativeRSinkToSource_();
112  depthMapSink_ = sinkdepth;
113  if (depthMapSink_!=NULL) accountForDifferentCameraCenters_ = true;
114  }
115 
116  /** @brief sets the scene to be a plane */
117  inline void SetPlane(const BIAS::HomgPlane3D& plane) {
118  mappingPlane_ = plane;
119  depthMapSink_ = NULL;
120  accountForDifferentCameraCenters_ = true;
121  }
122 
123  /** @brief uses forward mapping to calculate the bounding box in sink image,
124  where to actually do the backward mapping (only needed for speed up).
125 
126  The resulting coordinates can be negative !
127  The br position is the first pixel outside the region(as for a ROI).
128  @author koeser
129  */
130  virtual int GetBoundingBox(unsigned int srcwidth,
131  unsigned int srcheight,
132  unsigned int sinkwidth,
133  unsigned int sinkheight,
134  int &tlx, int &tly,
135  int &brx, int &bry);
136 
137 
138  protected:
139 
141 
143  if (SourceP_.PoseValid() && SinkP_.PoseValid())
144  relativeRSinkToSource_ = SourceP_.GetR().Transpose()*SinkP_.GetR();
145  }
146 
147  /** @brief Reimplementation for Pixel transformation,
148  takes sink and computes coordinates in source.
149  */
150  virtual int GetSourceCoordinates_(const HomgPoint2D& sink,
151  HomgPoint2D& source) const;
152 
154  return SourceP_;
155  };
156 
158  return SinkP_;
159  };
160 
161  /// Projections for backward mapping: Run over sink and compute source
162  Projection SourceP_, SinkP_;
163 
164  /// depth map used for sink if camera centers differ
166 
167  /// map via this plane
169 
170  /// dont map across plane at infinity
172 
173  };
174 
175 } // namespace
176 
177 #endif
178 
179 #include <Base/Common/BIASpragmaEnd.hh>
180 
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
BIAS::Projection GetSourceCam()
const Image< float > * depthMapSink_
depth map used for sink if camera centers differ
void SetSinkCam(const Projection &P, const Image< float > *sinkdepth=NULL)
Set your sink projection before calling Map(),.
void SetSourceCam(const Projection &P)
Set your source projection before calling Map()
Abstract base class to map an image (texture) src to an image sink with an arbitrary continuous funct...
Maps source pixel to sink pixel of given projections.
HomgPlane3D mappingPlane_
map via this plane
bool accountForDifferentCameraCenters_
dont map across plane at infinity
3D rotation matrix
Definition: RMatrix.hh:49
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
BIAS::Projection GetSinkCam()
void SetPlane(const BIAS::HomgPlane3D &plane)
sets the scene to be a plane
A homogeneous plane (in P^3) All points X on the plane p fulfill p &#39; * X = 0.
Definition: HomgPlane3D.hh:46