Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
UnVignette.cpp
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 "UnVignette.hh"
26 #include <iostream>
27 #include <math.h>
28 #include <MathAlgo/Lapack.hh>
29 #include <Base/Common/BIASpragma.hh>
30 #include <MathAlgo/SVD.hh>
31 #include <Base/Debug/TimeMeasure.hh>
32 
33 using namespace BIAS;
34 using namespace std;
35 
36 
38 {
39  PrinciplePointX_ = 0.0;
40  PrinciplePointY_ = 0.0;
41  bIsInitialized_ = false;
42  bUseLuT_ = false;
43  bLeastSquaresPrepared_ = false;
44  dInterPolationMethod_ = LEAST_SQUARES;
45 }
46 
47 //if Constructor is called only with CameraParam LuT is not used!
48 UnVignette::UnVignette(CameraParam &cParam,INTERPOLATION_METHOD method, bool bUseLuT)
49 {
50  dInterPolationMethod_ = method;
51  bUseLuT_ = bUseLuT;
52  bIsInitialized_ = false;
53  bLeastSquaresPrepared_ = false;
54  dWidth_ = cParam.GetWidth();
55  dHeight_ = cParam.GetHeight();
56 
57  PrinciplePointX_ = cParam.GetPrincipalX()- dWidth_/2;
58  PrinciplePointY_ = cParam.GetPrincipalY() - dHeight_/2;
59 
60  dWidthHalfMPPX_ = dWidth_/2 - PrinciplePointX_;
61  dHeightHalfMPPY_ = dHeight_/2 - PrinciplePointY_;
62 
63  ControlPoints_ = cParam.GetIlluCorrX();
64  PercentageValues_ = cParam.GetIlluCorrY();
65  if(ControlPoints_.size() > 2 && PercentageValues_.size() > 2)
66  Init(cParam,method,bUseLuT_);
67 }
68 
70 {
71 
72 }
73 
74 
76 {
77  if (!bIsInitialized_){
78  BIASWARN("Unvignette is not initialised, doing nothing");
79  return;
80  }
81  else{
82  if(dWidth_ != Image.GetWidth() || dHeight_ != Image.GetHeight())
83  {
84  BIASERR("Image size does not fit init size, returning" );
85  return;
86  }
87  float dum=0.0;
88  unsigned int newPixelValue =0;
89  dChannelCount_ = Image.GetChannelCount();
90 
91  ///////////////////////////////////////////
92  unsigned char* pId = Image.GetImageData();
93  float* pLuId = LuImage_.GetImageData();
94 
95  for(unsigned int i=0;i<dWidth_*dHeight_;i++)
96  {
97  dum = *pLuId++; // get data at look up image , this is correction factor
98  for(unsigned int j=0;j<dChannelCount_;j++)
99  {
100  newPixelValue = (unsigned int)( (*pId) * dum );
101  if(newPixelValue <= 255)
102  *pId++ = newPixelValue;
103  else
104  *pId++ = 255;
105 
106 
107  }
108  }
109  }
110  return;
111 }
112 
113 int UnVignette::Init(const std::vector<double> ControlPoints,
114  std::vector<double> PercentageValues,
115  unsigned int dImageWidth , unsigned int dImageHeight,
116  int dPPX, int dPPY, INTERPOLATION_METHOD method, bool bUseLuT)
117 {
118  bUseLuT_ = bUseLuT;
119  dInterPolationMethod_ = method;
120  dWidth_ = dImageWidth;
121  dHeight_ = dImageHeight;
122  PrinciplePointX_ = dPPX - dWidth_/2;
123  PrinciplePointY_ = dPPY - dHeight_/2;
124  ControlPoints_ = ControlPoints;
125  PercentageValues_ = PercentageValues;
126  return Init_();
127 }
128 
129 int UnVignette::Init(BIAS::CameraParam cParam,INTERPOLATION_METHOD method, bool bUseLuT)
130 {
131  bUseLuT_ = bUseLuT;
132  dInterPolationMethod_ = method;
133  dWidth_ = cParam.GetWidth();
134  dHeight_ = cParam.GetHeight();
135  PrinciplePointX_ = cParam.GetPrincipalX() - dWidth_/2;
136  PrinciplePointY_ = cParam.GetPrincipalY() - dHeight_/2;
137  ControlPoints_ = cParam.GetIlluCorrX();
138  PercentageValues_ = cParam.GetIlluCorrY();
139  return Init_();
140 }
141 
142 int UnVignette::Init_(){
143  int ret =0;
144  dWidthHalfMPPX_ = dWidth_/2 - PrinciplePointX_;
145  dHeightHalfMPPY_ = dHeight_/2 - PrinciplePointY_;
146  if(ControlPoints_.size() > 2 && PercentageValues_.size() > 2)
147  {
148  switch(dInterPolationMethod_){
149  case SPLINE_WITHOUT_LUT:
150  case SPLINE_WITH_LUT:
151  InterpolatorIllu_.SetKnotPoints(ControlPoints_);
152  InterpolatorIllu_.SetControlPoints(PercentageValues_);
153  InterpolatorIllu_.InitSpline();
154 
155  if(bUseLuT_)
156  ret = InterpolatorIllu_.PrepareLuTSpline(ControlPoints_[0],
157  ControlPoints_[ControlPoints_.size()-1],2000);
158 
159  break;
160  case LEAST_SQUARES:
161  ret = PrepareLeastSquaresMin_();
162  break;
163  }
164  if(ret >=0)
165  ret = PrepareLuImage_();
166  if(ret >=0)
167  bIsInitialized_ = true;
168  return ret;
169  }
170  else
171  return -1;
172 }
173 
174 
175 /////////////// Private functions /////////////////////
176 double UnVignette::
177 CalcRadius_(double x, double y)
178 {
179  double radius=0.0;
180  radius=sqrt((dWidthHalfMPPX_-x)*(dWidthHalfMPPX_-x) + (dHeightHalfMPPY_-y)*(dHeightHalfMPPY_-y));
181  return radius;
182 }
183 
184 int UnVignette::
185 PrepareLuImage_()
186 {
187  // if use the look up image, prepare it!
188  double radius=0.0;
189  double dum = 0.0;
190  //variables for calcradius
191  dWidthHalfMPPX_ = dWidth_/2 - PrinciplePointX_;
192  dHeightHalfMPPY_ = dHeight_/2 - PrinciplePointY_;
193 
194  LuImage_.Init(dWidth_,dHeight_,1);
195  float ** ida = LuImage_.GetImageDataArray();
196 
197  for(unsigned int k=0;k<LuImage_.GetWidth();k++)
198  {
199  for(unsigned int l=0;l<LuImage_.GetHeight();l++)
200  {
201  radius = CalcRadius_(k,l);
202  if(radius<0.0) radius = 0.0;
203  switch(dInterPolationMethod_){
204  case SPLINE_WITH_LUT:
205  case SPLINE_WITHOUT_LUT :
206  if( bUseLuT_ )
207  InterpolatorIllu_.SplineFromLuT(dum, radius/(dWidth_/2));
208  else
209  InterpolatorIllu_.Spline(dum,radius/(dWidth_/2),3);
210  break;
211  case LEAST_SQUARES:
212  LeastSquares_(dum,radius/(dWidth_/2));
213  break;
214  }
215 
216  // set factor in LuImage_ as correction factor;
217  ida[l][k] = (float)dum;
218  }
219  }
220  return 0;
221 }
222 
223 ///////////////// Prepare the Least Squares polynomial ///////////////
224 int UnVignette::
225 PrepareLeastSquaresMin_()
226 {
227  int res =0;
228  int rows = PercentageValues_.size();
229  A_.newsize(rows,4);
230  Y_.newsize(rows);
231  for(int row=0;row<rows;row++)
232  {
233 
234  A_[row][0] = 1;
235  A_[row][1] = ControlPoints_[row];
236  A_[row][2] = pow(ControlPoints_[row],2);
237  A_[row][3] = pow(ControlPoints_[row],3);
238  Y_[row] = PercentageValues_[row];
239  }
240  X_.newsize(4);
241 
242  BIAS::SVD svd;
243  res=svd.Solve(A_,Y_,X_);
244  // if(res!= 0)
245  // BIASERR("ERROR in SVD: "<<res);
246 
247  if(res == 0)
248  bLeastSquaresPrepared_ = true;
249  else
250  bLeastSquaresPrepared_ = false;
251  return res;
252 }
253 
254 //////////////// if least squares is prepared, get value for radius //
255 int UnVignette::
256 LeastSquares_(double &res, double radius)
257 {
258  if(!bLeastSquaresPrepared_)
259  {
260  BIASERR("Least Squares is not correctly prepared, aborting.");
261  return -1;
262  }
263  //X_ = {a,b,c,d}
264  res = X_[3]*pow(radius,3) + X_[2]*pow(radius,2) +X_[1]*radius + X_[0];
265  return 0;
266 }
267 
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
unsigned int GetHeight() const
get camera image height.
Vector< double > Solve(const Vector< double > &y) const
Definition: SVD.cpp:135
int Init(const std::vector< double > ControlPoints, std::vector< double > PercentageValues, unsigned int dImageWidth, unsigned int dImageHeight, int dPPX, int dPPY, INTERPOLATION_METHOD method=LEAST_SQUARES, bool bUseLuT=true)
Init the Unvignette algorithm give ControlPoints in image as offset from Principal Point in pixel giv...
Definition: UnVignette.cpp:113
double GetPrincipalY() const
get principal point, y in pixels relative to top left corner
unsigned int GetWidth() const
Definition: ImageBase.hh:312
unsigned int GetWidth() const
get camera image width.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
std::vector< double > GetIlluCorrY() const
Definition: CameraParam.hh:241
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
std::vector< double > GetIlluCorrX() const
Definition: CameraParam.hh:238
void Compute(BIAS::Image< unsigned char > &Image)
Definition: UnVignette.cpp:75
double GetPrincipalX() const
get principal point, x in pixels relative to top left corner