OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimLocalCorrelationFusion.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2005 Garrett Potts
3 //
4 // LICENSE: See top level LICENSE.txt
5 //
6 // Author: Garrett Potts
7 //
8 //*******************************************************************
9 // $Id: ossimLocalCorrelationFusion.cpp 15833 2009-10-29 01:41:53Z eshirschorn $
11 #include <ossim/matrix/newmat.h>
12 #include <ossim/matrix/newmatio.h>
17 
19 
20 
21 static const ossim_uint32 REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET = 0;
22 static const ossim_uint32 REGRESSION_COEFFICIENT_CLAMP_OFFSET = 1;
23 static const ossim_uint32 HIGH_PASS_GAIN_OFFSET = 2;
24 static const ossim_uint32 PAN_BLURR_WIDTH_OFFSET = 3;
25 static const ossim_uint32 NUMBER_OF_ADJUSTABLE_PARAMETERS = 4;
26 
28  :theBlurrKernelWidth(1.5),
29  theHighPassKernelWidth(3),
30  theRegressionWidth(5)
31 {
34 
35  setFilters();
36 
38 }
39 
41 {
42 }
43 
45  ossim_uint32 resLevel)
46 {
48  {
50  }
51 
53  {
54  return theInputConnection->getTile(rect, resLevel);
55  }
56 
57  ossim_int32 regressionW2 = (ossim_int32)ceil(theRegressionWidth/2.0);
58 
59  ossimIrect expandedRegressionRect(rect.ul().x - regressionW2,
60  rect.ul().y - regressionW2,
61  rect.lr().x + regressionW2,
62  rect.lr().y + regressionW2);
63 
65  {
68  1,
69  expandedRegressionRect.width(),
70  expandedRegressionRect.height());
73  1,
74  expandedRegressionRect.width(),
75  expandedRegressionRect.height());
80  }
81 
82  theNormLowPassTile->setImageRectangle(expandedRegressionRect);
83  theNormHighPassTile->setImageRectangle(expandedRegressionRect);
86 
88  {
89  initialize();
90  }
91 
92  ossimRefPtr<ossimImageData> lowTile = theLowPassFilter->getTile(expandedRegressionRect, resLevel);
93  ossimRefPtr<ossimImageData> highTile = theHighPassFilter->getTile(expandedRegressionRect, resLevel);
94 // ossimRefPtr<ossimImageData> highTile = getNormIntensity(expandedRegressionRect, resLevel);
95  ossimIpt ul = rect.ul();
96  ossimIpt origin;
97 
98  // if we don't have valid low and high pass then return the input color tile
99  // in its original format
100  //
101  if(!lowTile.valid()||!highTile.valid())
102  {
103  return theInputConnection->getTile(rect, resLevel);
104  }
105 
106  if((lowTile->getDataObjectStatus() == OSSIM_EMPTY)||
107  (!lowTile->getBuf()) ||
108  (highTile->getDataObjectStatus() == OSSIM_EMPTY)||
109  (!highTile->getBuf()))
110  {
111  return theInputConnection->getTile(rect, resLevel);
112  }
113 
114  ossimRefPtr<ossimImageData> normColorData = getNormTile(expandedRegressionRect, resLevel);
115 
116  ossim_uint32 y = 0;
117  ossim_uint32 x = 0;
120 
121  theTile->makeBlank();
122  theTile->setImageRectangle(rect);
123 
124  if(!normColorData.valid())
125  {
126  return 0;
127 // return theTile;
128  }
129 
130  if((normColorData->getDataObjectStatus() == OSSIM_EMPTY)||
131  !normColorData->getBuf())
132  {
133  return theTile;
134  }
135  ossimRefPtr<ossimImageData> normColorOutputData = (ossimImageData*)normColorData->dup();
136  normColorOutputData->setImageRectangle(rect);
137  normColorOutputData->loadTile(normColorData.get());
138 
139  ossim_float64 slopeResult = 0.0;
140  ossim_uint32 idx = 0;
141  std::vector<ossim_float32*> bands(normColorData->getNumberOfBands());
142 
144 
149  lowPan->setImageRectangle(rect);
150  lowPan->loadTile(theNormLowPassTile.get());
152  highPan->setImageRectangle(rect);
153  highPan->loadTile(theNormHighPassTile.get());
154 
155  ossim_float32* panHigh = (ossim_float32*)highPan->getBuf();
156  ossim_float32* panLow = (ossim_float32*)lowPan->getBuf();
157  for(idx = 0; idx < bands.size(); ++idx)
158  {
159  bands[idx] = (ossim_float32*)normColorOutputData->getBuf(idx);
160  }
161  double panAttenuator = computeParameterOffset(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET);
162  double delta = 0.0;
163  ossim_uint32 bandsSize = (ossim_uint32)bands.size();
164  ossim_float64 slopeClamp = computeParameterOffset(REGRESSION_COEFFICIENT_CLAMP_OFFSET);
165  ossim_float64 minSlope = -slopeClamp;
166  ossim_float64 maxSlope = slopeClamp;
167  for(y = 0; y < h; ++y)
168  {
169  origin.y = ul.y + y;
170  for(x = 0; x < w; ++x)
171  {
172  origin.x = ul.x + x;
173 
174 // if(computeRegression(slopeResult,
175 // origin,
176 // theNormLowPassTile,
177 // normColorData,
178 // 0))
179 // {
180 // delta = panAttenuator*slopeResult*(*panHigh - *panLow);
181 
182  for(idx = 0; idx < bandsSize; ++idx)
183  {
184  if(*bands[idx] != 0.0) // if band is not null
185  {
186  if(computeRegression(slopeResult,
187  origin,
189  normColorData,
190  idx))
191  {
192  if(slopeResult < minSlope) slopeResult = minSlope;
193  if(slopeResult > maxSlope) slopeResult = maxSlope;
194  delta = panAttenuator*slopeResult*(*panHigh - *panLow);
195  ossim_float32 normMinPix = (ossim_float32)normColorOutputData->getMinPix(idx);
196  *bands[idx] += delta;
197  if(*bands[idx] > 1.0) *bands[idx] = 1.0;
198  if(*bands[idx] < normMinPix) *bands[idx] = normMinPix;
199  }
200  }
201  ++bands[idx];
202  }
203  ++panHigh;
204  ++panLow;
205  }
206  }
207 
208  theTile->copyNormalizedBufferToTile((ossim_float32*)normColorOutputData->getBuf());
209  theTile->validate();
210 
211  return theTile;
212 }
213 
215 {
218  {
221  }
222  else
223  {
228  setFilters();
231  }
232 }
233 
235 {
237 
239  theHighPassMatrix = 0;
241 
242  // adjust the gain for the high pass filter
243  //
244  NEWMAT::Matrix high = theHighPassMatrix;
245 
247  double gain = computeParameterOffset(HIGH_PASS_GAIN_OFFSET)*(kernelW2);
248  double multiplier = gain/(kernelW2);
249  high = -multiplier;
252 
253  if(gain > FLT_EPSILON)
254  {
255  high[cy][cx] = multiplier* ( (kernelW2-1)+kernelW2/gain);
256  }
257  else
258  {
259  high = 0.0;
260  high[cy][cx] = 1.0;
261  }
262 
264 }
265 
267  const ossimIpt& origin,
268  const ossimRefPtr<ossimImageData> panData,
269  const ossimRefPtr<ossimImageData> colorData,
270  ossim_uint32 colorBandIdx)
271 {
272  bool result = false;
273  slopeResult = 0.0;
274  if(panData.valid()&&colorData.valid())
275  {
277  ossimIrect rect = panData->getImageRectangle();
278  const ossim_float32* colorDataPtr = (const ossim_float32*)colorData->getBuf(colorBandIdx);
279  const ossim_float32* colorDataPtr2 = (const ossim_float32*)colorData->getBuf(colorBandIdx);
280 
281 // const ossim_float32* colorDataPtrBands[3]={0};
282 
283 // if(colorData->getNumberOfBands() <2)
284 // {
285 // colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
286 // }
287 // else if(colorData->getNumberOfBands() <3)
288 // {
289 // colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
290 // colorDataPtrBands[1] = (ossim_float32*)colorData->getBuf(1);
291 // }
292 // else
293 // {
294 // colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
295 // colorDataPtrBands[1] = (ossim_float32*)colorData->getBuf(1);
296 // colorDataPtrBands[2] = (ossim_float32*)colorData->getBuf(2);
297 // }
298  const ossim_float32* panDataPtr = (const ossim_float32*)panData->getBuf();
299  const ossim_float32* panDataPtr2 = (const ossim_float32*)panData->getBuf();
300 // if(!panDataPtr || !colorDataPtrBands[0]) return result;
301  if(!panDataPtr || !colorDataPtr) return result;
302 
303  ossim_float64 panNp = panData->getNullPix(0);
304  ossim_float64 colorNp = colorData->getNullPix(0);
305  ossim_int32 w = (ossim_int32)rect.width();
306  ossim_int32 offset = (ossim_int32)( ((origin.y-rect.ul().y) - regW2)*w +
307  ((origin.x-rect.ul().x) - regW2));
308 
309  ossim_uint32 y = 0;
310  ossim_uint32 x = 0;
311  ossim_uint32 idx = 0;
312  ossim2dLinearRegression regression;
313  ossim_uint32 offsetColorBand;
314 
315  for(y = 0; y < theRegressionWidth; ++y)
316  {
317  offsetColorBand = (offset + y*w);
318  panDataPtr = panDataPtr2 + offsetColorBand;
319  colorDataPtr = colorDataPtr2 + offsetColorBand;
320  for(x = 0; x < theRegressionWidth; ++x)
321  {
322 // if((*panDataPtr != panNp)&&
323 // (colorDataPtrBands[0][offsetColorBand] != colorNp)&&
324 // (colorDataPtrBands[1][offsetColorBand] != colorNp)&&
325 // (colorDataPtrBands[2][offsetColorBand] != colorNp))
326 // {
327  if((*panDataPtr != panNp)&&
328  (*colorDataPtr != colorNp))
329  {
330 // ossimNormRgbVector rgbV(colorDataPtrBands[0][offsetColorBand],
331 // colorDataPtrBands[1][offsetColorBand],
332 // colorDataPtrBands[2][offsetColorBand]);
333 // ossimHsiVector hsi(rgbV);
334 
335  regression.addPoint(ossimDpt(*panDataPtr, *colorDataPtr));
336 // regression.addPoint(ossimDpt(*panDataPtr, hsi.getI()));
337  ++idx;
338  }
339  ++panDataPtr;
340 // ++offsetColorBand;
341  ++colorDataPtr;
342  }
343  }
344  if(idx > 2)
345  {
346  double slope, intercept;
347  result = true;
348  regression.solve();
349  regression.getEquation(slope,
350  intercept);
351 
352  slopeResult = slope;
353  }
354  }
355 
356  return result;
357 }
358 
360 {
361  resizeAdjustableParameterArray(NUMBER_OF_ADJUSTABLE_PARAMETERS);
362 
363  setAdjustableParameter(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
364  0.0);
365  setParameterDescription(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
366  "Attenuator");
367  setParameterSigma(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
368  2.0);
369  setParameterCenter(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
370  1.0);
371 
372 
373  setAdjustableParameter(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
374  0.0);
375  setParameterDescription(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
376  "Regression clamp");
377  setParameterSigma(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
378  10.0);
379  setParameterCenter(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
380  10.0);
381 
382 
383  setAdjustableParameter(HIGH_PASS_GAIN_OFFSET,
384  -1.0);
385  setParameterDescription(HIGH_PASS_GAIN_OFFSET,
386  "High pass gain");
387  setParameterSigma(HIGH_PASS_GAIN_OFFSET,
388  1);
389  setParameterCenter(HIGH_PASS_GAIN_OFFSET,
390  1.0);
391 
392  setAdjustableParameter(PAN_BLURR_WIDTH_OFFSET,
393  -1);
394  setParameterDescription(PAN_BLURR_WIDTH_OFFSET,
395  "Blurring kernel width");
396  setParameterSigma(PAN_BLURR_WIDTH_OFFSET,
397  7);
398  setParameterCenter(PAN_BLURR_WIDTH_OFFSET,
399  7.5);
400 
401 
402  setParameterOffset(PAN_BLURR_WIDTH_OFFSET,
403  1.5);
404  setParameterOffset(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
405  4.0);
406 }
407 
409 {
410 // std::cout << "Parameter offset = " << computeParameterOffset(2) << std::endl;
411  theBlurrKernelWidth = (ossim_uint32)(ossim::round<int>(computeParameterOffset(PAN_BLURR_WIDTH_OFFSET)));
412 }
413 
414 
416  const char* prefix) const
417 {
418  ossimFusionCombiner::saveState(kwl, prefix);
419  saveAdjustments(kwl, prefix);
420 
421  return true;
422 }
423 
425  const char* prefix)
426 {
427  ossimFusionCombiner::loadState(kwl, prefix);
428  loadAdjustments(kwl, prefix);
430 
431  return true;
432 }
virtual ossim_uint32 getWidth() const
ossim_uint32 x
ossimRefPtr< ossimImageData > theNormLowPassTile
void setParameterDescription(ossim_uint32 idx, const ossimString &descrption)
bool saveAdjustments(ossimKeywordlist &kwl, const ossimString &prefix=ossimString("")) const
Save all adjustments to the KWL file.
virtual ossim_uint32 getNumberOfBands() const
ossimRefPtr< ossimImageData > getNormTile(const ossimIrect &rect, ossim_uint32 resLevel)
virtual void setImageRectangle(const ossimIrect &rect)
virtual void disconnect(ossimConnectableObject *object=0)
Will disconnect the object passed in.
Represents serializable keyword/value map.
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
float ossim_float32
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
ossimRefPtr< ossimImageData > theTile
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
ossimImageSource * theInputConnection
virtual ossimObject * getObject()
For RTTI support.
ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual void initialize()
Initialize the data buffer.
virtual ossimObject * dup() const
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
double ossim_float64
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
void getEquation(double &slope, double &intercept)
virtual ossimDataObjectStatus validate() const
void setParameterOffset(ossim_uint32 idx, ossim_float64 value, bool notify=false)
class for symmetric Gaussian filtering implemented as two separable horizontal/vertical gaussian filt...
#define FLT_EPSILON
ossimImageSource * theIntensityConnection
virtual void setConvolution(const double *kernel, int nrows, int ncols, bool doWeightedAverage=false)
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
bool loadAdjustments(const ossimKeywordlist &kwl, const ossimString &prefix=ossimString(""))
RTTI_DEF2(ossimLocalCorrelationFusion, "ossimLocalCorrelationFusion", ossimFusionCombiner, ossimAdjustableParameterInterface)
virtual ossimIrect getImageRectangle() const
virtual void copyTileToNormalizedBuffer(ossim_float64 *buf) const
Copies entire tile to buf passed in.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
virtual void copyNormalizedBufferToTile(ossim_float64 *buf)
Copies buf passed in to tile.
void setGaussStd(const ossim_float64 &v)
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
This implements a Local correlation fusion based on the paper:
virtual const ossim_float64 * getMinPix() const
virtual void makeBlank()
Initializes data to null pixel values.
ossimRefPtr< ossimImageData > theNormHighPassTile
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
ossim_int32 x
Definition: ossimIpt.h:141
ossimRefPtr< ossimConvolutionSource > theHighPassFilter
bool computeRegression(ossim_float64 &slopeResult, const ossimIpt &origin, ossimRefPtr< ossimImageData > panData, ossimRefPtr< ossimImageData > colorData, ossim_uint32 colorBandIdx)
virtual void initialize()
inherited methods
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=NULL)
Method to the load (recreate) the state of an object from a keyword list.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Method to save the state of an object to a keyword list.
void setParameterCenter(ossim_uint32 idx, double center, bool notify=false)
void addPoint(const ossimDpt &pt)
ossimRefPtr< ossimImageGaussianFilter > theLowPassFilter
void setParameterSigma(ossim_uint32 idx, double value, bool notify=false)
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)