Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ImageBlenderIncremental.hh
1 #ifndef __ImageBlenderIncremental_hh__
2 #define __ImageBlenderIncremental_hh__
3 
4 #include <Base/Image/Image.hh>
5 #include <Image/Camera.hh>
6 #include <Base/Image/ImageConvert.hh>
7 #include <Filter/Gauss.hh>
8 #include <Geometry/ProjectionParametersCylindric.hh>
9 #include <Geometry/ProjectionParametersPerspective.hh>
10 #include <Image/ProjectionMapping.hh>
11 #include <Geometry/Projection.hh>
12 #include <Base/Math/RGBA.hh>
13 
14 #define WEIGHT_TYPE_NONE 0
15 #define WEIGHT_TYPE_CIRCULAR 1
16 #define WEIGHT_TYPE_CIRCULAR_FIT 2
17 #define WEIGHT_TYPE_RECTANGULAR 3
18 #define WEIGHT_TYPE_RECT_NONLINEAR 4
19 #define WEIGHT_TYPE_MIX 5 // mix between rectangular and circular
20 #define WEIGHT_TYPE_USERIMAGE 6
21 
22 
23 // these defines steer the orientaion of the cylinder with X/Y/Z-axes of the
24 // cameras or automatically
25 #define HORIZON_ALIGNMENT_X 0
26 #define HORIZON_ALIGNMENT_Y 1
27 #define HORIZON_ALIGNMENT_UNKNOWN 2
28 #define HORIZON_ALIGNMENT_AUTO 3
29 
30 // DEBUG LEVELS:
31 // gives some output about the whole progress
32 #define D_IMAGEBLENDER_MINIMAL 1
33 // gives some output about geometry calculation
34 #define D_IMAGEBLENDER_GEOMETRY 2
35 // gives some output about the filtering process
36 #define D_IMAGEBLENDER_FILTERING 4
37 // gives some output about the blending
38 #define D_IMAGEBLENDER_BLENDING 8
39 
40 
41 namespace BIAS {
42 
43  /** @class ImageBlenderIncremental
44  * @brief maps several images into a common mosaic and blends them seamlessly
45  *
46  * Blends a bunch of images seamlessly either in incremental or batch mode
47  * (in any case 64 byte RAM per output pixel are required, plus some constant,
48  * i.e. for a 10000x10000 pano you will need 6.4GB RAM). If you dont have
49  * enough RAM, tile your output image and run multiple times.
50  *
51  * General usage of this class:
52  * First, specify the output parameters. For a rectilinear panorama
53  * this is a simple ProjectionParametersPerspective with wide field of view
54  * or for cylindrical panorama use BIAS::ProjectionParametersCylindric.
55  * However, you can also blend multiple textures for surfaces by providing
56  * the depth map of the output image.
57  *
58  * When you specify the output parameters by SetOutputParameters(),
59  * a compatible output image will be generated internally.
60  * Then, for each input image (the photos you want to stitch),
61  * call Blend(image). Internally, the output image will be
62  * updated (a Kalman filter on the low frequency intensity plus the most
63  * reliable (winner-takes-all) laplacian of all images).
64  * Finally, call GetImage to obtain the resulting image.
65  *
66  * Originally this class was written for panoramic image stitiching and
67  * computes a cylindrical geometry automatically from the different
68  * images. However, you can specify any projection you want as an output.
69  * In case your input images do not have the same camera center as your
70  * output image and you want this to be considered, you have to provide
71  * an output depth map, which can be used for the mapping in 3D.
72  *
73  * Blending is done by separating the image into high-pass and low-pass
74  * parts, where each part is blended over one wavelength, i.e. sharp edges
75  * are blended within 2 pixels, while the image mean is blended over
76  * the whole image size.
77  * @author Robert Wulff, kkoeser
78  * @date 07/2007, 06/2014
79  **/
80  class BIASImage_EXPORT ImageBlenderIncremental : public BIAS::Debug {
81 
82  public:
83 
84  /** @brief constructor
85  * @param blendIncremental set to true if you want to blend each added
86  * camera right away, rather than in (traditional) batch mode
87  * @author Robert Wulff
88  * @date 07/2007
89  **/
90  ImageBlenderIncremental(bool blendIncremental = false);
91 
92 
93  /** @brief resets internal mosaic
94  @param imagegeometry projectionparameters of output mosaic
95  @param bgcolor initial background color of empty mosaic (e.g. black)
96  @param pDepthmap if != NULL, this enables 3D stitching mode and
97  the camera centers of the image and the final mosaic will be
98  considered
99  */
100  void SetOutputParameters(const BIAS::ProjectionParametersBase& imagegeometry,
101  const BIAS::RGBAuc bgcolor=RGBAuc(0,0,0,0));
102 
103  /** @brief set a weight image (e.g. to ignore certain pixels or to account
104  * for funny illumination and confidence in pixel color
105  *
106  * specify WEIGHT_TYPE_USERIMAGE to use this in AddCamera
107  * @param weights must be of same size as next user input image */
108  void SetUserWeightImage(const BIAS::Image<float>& weights);
109 
110  /** @brief In incremental mode, the mosaic is updated using the image and
111  * the contained projection, in batch mode the image is simply added
112  * to the database and must contain a valid projection and a valid UUID.
113  @return 0 = OK, -1 = error
114  **/
115  int AddCamera(const BIAS::Camera<unsigned char>& camera,
116  unsigned int weightType = WEIGHT_TYPE_CIRCULAR_FIT);
117 
118  /** @brief returns (current) mosaic image in incremental mode */
119  void GetMosaicRGBA(Image<unsigned char>& mosaic);
120 
121  /** @brief returns (current) mosaic image in incremental mode */
122  void GetMosaicRGBA(Image<float>& mosaic);
123 
124  /** @brief returns (current) mosaic image in incremental mode */
125  void GetMosaicRGB(Image<unsigned char>& mosaic);
126 
127  /** @brief returns (current) mosaic image in incremental mode */
128  void GetMosaicRGB(Image<float>& mosaic);
129 
130  /** @brief for interadctive visualization, show current buffer (read only) */
132  return &latestMosaicLow_;
133  }
134 
135 
136  /** @brief compute cylindrical geometry from added images and blend all
137  added images
138 
139  This function is only available in batch mode.
140  wrapper function only, calls other BlendImages
141  @param destination result image
142  @return true iff blending succeeded or false otherwise
143  @author Robert Wulff
144  @date 07/2007
145  **/
146  inline bool BlendImages(BIAS::Camera<unsigned char> &destination,
147  double gaussSigma = 1.2) {
148  // compute cyl geometry
149  ProjectionParametersCylindric ppc(-cylinderHeight_, cylinderHeight_,
150  -M_PI, M_PI,
151  outputImageWidth_,
152  outputImageHeight_);
153  ComputeCylCamGeometry_(ppc);
154  return BlendImages(destination, ppc, NULL, gaussSigma);
155  }
156 
157 
158  /** @brief Blends all added images into destination with ppOut projection
159  *
160  * This function is only available in batch mode.
161  * @param destination output image
162  * @param ppOut desired projection for output
163  * @param depthmap of destination, needed if input cameras do not have the
164  * same center as output camera, ignored if NULL
165  * @return true iff blending succeeded or false otherwise
166  * @author Robert Wulff
167  * @date 07/2007
168  **/
169  bool BlendImages(BIAS::Camera<unsigned char> &destination,
170  const ProjectionParametersBase& ppOut,
171  const BIAS::Image<float>* depthmap = NULL,
172  double gaussSigma = 1.2);
173 
174  void SetDepthMap(const BIAS::Image<float>& depthmap) {
175  Depth_ = depthmap;
176  plane_.SetZero();
177  }
178  void SetPlane(const HomgPlane3D& theplane) {
179  plane_ = theplane;
180  if (!Depth_.IsEmpty()) Depth_.Release();
181  }
182 
183 
184  /** @brief
185  @author Robert Wulff
186  @date 10/2007
187  **/
188  inline void SetOuputImageSize(const unsigned int &newSize) {
189  outputImageHeight_ = newSize;
190  outputImageWidth_ =
191  (unsigned int)(outputImageHeight_ * cylinderHeight_ / M_PI);
192  };
193 
194  /** @brief
195  @author Robert Wulff
196  @date 10/2007
197  **/
198  inline unsigned int GetOuputImageSize() {
199  return outputImageWidth_;
200  };
201 
202  // creates a 3d model of image planes and cyl cam
203  inline void SetWriteVrml(bool flag) {writeVrml_ = flag;}
204 
205  inline void SetDrawImageBorders(bool flag) {drawImageBorders_ = flag;}
206 
207  // here come the public member variables
208 
209  /** @brief determines the alignment of the horizon
210  possible values are:
211  HORIZON_ALIGNMENT_X - horizon is in x direction (default value)
212  HORIZON_ALIGNMENT_X - horizon is in y direction
213  HORIZON_ALIGNMENT_UNKNOWN - horizon alignment is unknown
214  or mixed
215  @date 12/07
216  **/
217  inline void SetHorizonAlignment(unsigned int val) {horizonAlignment_ = val;};
218 
219  protected:
220  /** @brief helper function for simple laplacian pyramid */
221  void GetLowPassAndHighPassImage_(const Image<float>& camCyl,
222  Image<float>& lowPassCam,
223  Image<float>& highPassCam);
224 
225  /** @brief helper function for incremental fusion */
226  void LowPassFusiondAndHighPassMax_(Image<float>& destLow, Image<float>& destHigh,
227  Image<float>& lowPassCam, Image<float>& highPassCam);
228 
229  /** @brief helper function for extracting mosaic from laplacian pyramid */
230  void AddLowPassAndHighPassImage_(Image<float>& destLow, Image<float>& destHigh,
231  Image<unsigned char>& destination);
232 
233  /** @brief helper function for extracting mosaic from laplacian pyramid */
234  void AddLowPassAndHighPassImage_(Image<float>& destLow, Image<float>& destHigh,
235  Image<float>& destination);
236 
237  /** @brief helper for filling an image with rgba data */
238  void FillBGImage_(Image<float>& BGImage, const RGBAuc& color);
239 
240  /** @brief copies alpha channel from first RGBA image into second */
241  void CopyAlphaChannel_(const Image<float>& camCyl,
242  Image<float>& lowPassCam);
243 
244  /** @brief adds an alpha channel to RGB image, alpha can be e.g. radial
245  symmetric from image center*/
246  void ComputeAlphaChannelWeight_(BIAS::Image<float> &image,
247  unsigned int weightType =
248  WEIGHT_TYPE_RECTANGULAR);
249 
250  void ConvertImageToRGBA_(BIAS::Image<float> &image);
251 
252  void ComputeCylCamGeometry_(BIAS::ProjectionParametersCylindric &ppc);
253 
254  double CalcAngleToYAxis_(const BIAS::Vector2<double> &v,
255  bool wantDegrees = false);
256 
257  double CalcAngleToXAxis_(const BIAS::Vector2<double> &v,
258  bool wantDegrees = false);
259 
260  /** @brief Checks FOV of each cam and computes the cylinder's FOV
261  If mapper tries to access pixel outside of image, nasty
262  distortion effects occur. This method checks the FOV of each cam
263  and blocks access to pixels that are out of scope.
264  @author Robert Wulff
265  @date 11/07
266  **/
267  void CheckFov_(BIAS::ProjectionParametersCylindric &ppc);
268 
269  // here come the protected member variables
271  unsigned int outputImageWidth_;
272  unsigned int outputImageHeight_;
273  unsigned int horizonAlignment_;
274 
275  std::vector<BIAS::UUID> imageIDs_;
276  std::map<BIAS::UUID, BIAS::Camera<float> > inputImages_;
277 
279 
282  bool blendIncremental_; ///< incremental or batchmode
283 
284  /// weight image for user specified weighting
286  /// output image in incremental mode
288  /// output projection
290  /// output depth
292  /// plane (alternative to depth)
294  /// the actual worker:
296 
297 
298  };
299 }
300 #endif // __ImageBlender_hh__
BIAS::ProjectionParametersBase * ppOutput_
output projection
void SetDepthMap(const BIAS::Image< float > &depthmap)
BIAS::HomgPlane3D plane_
plane (alternative to depth)
std::vector< BIAS::UUID > imageIDs_
bool BlendImages(BIAS::Camera< unsigned char > &destination, double gaussSigma=1.2)
compute cylindrical geometry from added images and blend all added images
BIAS::Gauss< float, float > gaussFilter_
BIAS::ProjectionMapping< float, float > pm_
the actual worker:
maps several images into a common mosaic and blends them seamlessly
void SetHorizonAlignment(unsigned int val)
determines the alignment of the horizon possible values are: HORIZON_ALIGNMENT_X - horizon is in x di...
const Image< float > * GetLowPassPointer()
for interadctive visualization, show current buffer (read only)
BIAS::Vector4< unsigned char > RGBAuc
Definition: RGBA.hh:47
bool blendIncremental_
incremental or batchmode
BIAS::Image< float > weightimage_
weight image for user specified weighting
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void SetPlane(const HomgPlane3D &theplane)
void SetOuputImageSize(const unsigned int &newSize)
BIAS::Image< float > Depth_
output depth
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
std::map< BIAS::UUID, BIAS::Camera< float > > inputImages_
void SetZero()
zeroes the image
Definition: ImageBase.hh:83
A homogeneous plane (in P^3) All points X on the plane p fulfill p &#39; * X = 0.
Definition: HomgPlane3D.hh:46