1e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
2e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Copyright (C) 2011 The Android Open Source Project
3e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
4e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
5e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * you may not use this file except in compliance with the License.
6e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * You may obtain a copy of the License at
7e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
8e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
9e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
10e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software
11e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
12e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * See the License for the specific language governing permissions and
14e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * limitations under the License.
15e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */
16e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
17e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen///////////////////////////////////////////////////
18e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// Mosaic.h
19e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// S.O. # :
20e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// Author(s): zkira
21e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen// $Id: Mosaic.h,v 1.16 2011/06/24 04:22:14 mbansal Exp $
22e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
23e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#ifndef MOSAIC_H
24e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#define MOSAIC_H
25e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
26e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "ImageUtils.h"
27e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "AlignFeatures.h"
28e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "Blend.h"
29e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include "MosaicTypes.h"
30e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
31e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*! \mainpage Mosaic
32e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
33e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    \section intro Introduction
34e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    The class Mosaic provides a simple interface to the panoramic mosaicing algorithm. The class allows passing in individual image frames to be stitched together, computes the alignment transformation between them, and then stitches and blends them together into a single panoramic output which can then be accessed as a single image. \
35e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
36e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    \section usage Usage
37e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    The class methods need to be called as outlined in the sample application which is created from the mosaic_main.cpp file in the directory src/mosaic/. A brief snapshot of the flow is given below:
38e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
39e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    \code
40e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    Mosaic mosaic;
41e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // Define blending types to use, and the frame dimensions
42e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int blendingType = Blend::BLEND_TYPE_CYLPAN;
43b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    int stripType = Blend::STRIP_TYPE_THIN;
44e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int width = 640;
45e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int height = 480;
46e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
47e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    while (<image frames are available>)
48e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    {
49e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        // Check for initialization and if not, initialize
50e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        if (!mosaic.isInitialized())
51e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        {
52e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen          // Initialize mosaic processing
53b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal          mosaic.initialize(blendingType, stripType, width, height, -1, false, 5.0f);
54e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        }
55e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
56e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        // Add to list of frames
57e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        mosaic.addFrameRGB(imageRGB);
58e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
59e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        // Free image
60e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen        ImageUtils::freeImage(imageRGB);
61e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    }
62e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
63e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // Create the mosaic
64e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    ret = mosaic.createMosaic();
65e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
66e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // Get back the result
67e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    resultYVU = mosaic.getMosaic(mosaicWidth, mosaicHeight);
68e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
69e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    printf("Got mosaic of size %d,%d\n", mosaicWidth, mosaicHeight);
70e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
71e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    \endcode
72e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen*/
73e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
74e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*!
75e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *  Main class that creates a mosaic by creating an aligner and blender.
76e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */
77e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenclass Mosaic
78e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
79e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
80e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenpublic:
81e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
82e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Mosaic();
83e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ~Mosaic();
84e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
85e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   /*!
86e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Creates the aligner and blender and initializes state.
87e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param blendingType Type of blending to perform
88b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    *   \param stripType    Type of strip to use. 0: thin, 1: wide. stripType
89b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    *                       is effective only when blendingType is CylPan or
90b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    *                       Horz. Otherwise, it is set to thin irrespective of the input.
91e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param width        Width of input images (note: all images must be same size)
92e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param height       Height of input images (note: all images must be same size)
93e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param nframes      Number of frames to pre-allocate; default value -1 will allocate each frame as it comes
94e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param quarter_res  Whether to compute alignment at quarter the input resolution (default = false)
95e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param thresh_still Minimum number of pixels of translation detected between the new frame and the last frame before this frame is added to be mosaiced. For the low-res processing at 320x180 resolution input, we set this to 5 pixels. To reject no frames, set this to 0.0 (default value).
96e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Return code signifying success or failure.
97e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
98b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal  int initialize(int blendingType, int stripType, int width, int height, int nframes = -1, bool quarter_res = false, float thresh_still = 0.0);
99e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
100e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   /*!
101e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Adds a YVU frame to the mosaic.
102e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param imageYVU     Pointer to a YVU image.
103e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Return code signifying success or failure.
104e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
105e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int addFrame(ImageType imageYVU);
106e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
107e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   /*!
108e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Adds a RGB frame to the mosaic.
109e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param imageRGB     Pointer to a RGB image.
110e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Return code signifying success or failure.
111e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
112e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int addFrameRGB(ImageType imageRGB);
113e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
114e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   /*!
115e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   After adding all frames, call this function to perform the final blending.
11650b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal    *   \param progress     Variable to set the current progress in.
117e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Return code signifying success or failure.
118e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
119e1178a73fd5756771d25d0b8375452450f509e99mbansal  int createMosaic(float &progress, bool &cancelComputation);
120e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
121e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
122e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Obtains the resulting mosaic and its dimensions.
123e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param width        Width of the resulting mosaic (returned)
124e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \param height       Height of the resulting mosaic (returned)
125e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Pointer to image.
126e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
127e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType getMosaic(int &width, int &height);
128e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
129e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
130e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Provides access to the internal alignment object pointer.
131e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   \return             Pointer to the aligner object.
132e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
133e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Align* getAligner() { return aligner; }
134e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
135e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
136e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   Obtain initialization state.
137e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *
138e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    *   return              Returns true if initialized, false otherwise.
139e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
140e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  bool isInitialized() { return initialized; }
141e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
142e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
143e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /*!
144e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  Return codes for mosaic.
145e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
146e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  static const int MOSAIC_RET_OK    = 1;
147e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  static const int MOSAIC_RET_ERROR = -1;
148e1178a73fd5756771d25d0b8375452450f509e99mbansal  static const int MOSAIC_RET_CANCELLED = -2;
149dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal  static const int MOSAIC_RET_LOW_TEXTURE = -3;
150dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal  static const int MOSAIC_RET_FEW_INLIERS = 2;
151e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
152e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenprotected:
153e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
154e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
155e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Size of image frames making up mosaic
156e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
157e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int width, height;
158e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
159e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
160e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Size of actual mosaic
161e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
162e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int mosaicWidth, mosaicHeight;
163e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
164e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
165e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Bounding box to crop the mosaic when the gray border is not desired.
166e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
167e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MosaicRect mosaicCroppingRect;
168e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
169e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  ImageType imageMosaicYVU;
170e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
171e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
172e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Collection of frames that will make up mosaic.
173e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
174e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  MosaicFrame **frames;
175b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal
176b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal  /**
177b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    * Subset of frames that are considered as relevant.
178b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    */
179b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal  MosaicFrame **rframes;
180b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal
181e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int frames_size;
182e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int max_frames;
183e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
184e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
185e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Initialization state.
186e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
187e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  bool initialized;
188e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
189e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
190e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  Type of blending to perform.
191e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
192e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int blendingType;
193e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
194e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
195b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    * Type of strip to use. 0: thin (default), 1: wide
196b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal    */
197b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal  int stripType;
198b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal
199b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal  /**
200e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  Pointer to aligner.
201e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
202e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Align *aligner;
203e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
204e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
205e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  Pointer to blender.
206e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
207e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  Blend *blender;
208e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
209e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  /**
210e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  Modifies TRS matrices so that rotations are balanced
211e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *  about center of mosaic
212e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *
213e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   * Side effect: TRS matrices of all mosaic frames
214e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   *              are modified
215e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen   */
216e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen  int balanceRotations();
217e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
218e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen};
219e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
220e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#endif
221