OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimSFIMFusion.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: ossimSFIMFusion.cpp 22755 2014-04-30 19:50:30Z dburken $
11 #include <ossim/matrix/newmat.h>
12 #include <ossim/matrix/newmatio.h>
21 
23 
24 
25 static const ossim_uint32 HIGH_PASS_GAIN_OFFSET = 0;
26 static const ossim_uint32 LOW_PASS_WIDTH_OFFSET = 1;
27 static const ossim_uint32 NUMBER_OF_ADJUSTABLE_PARAMETERS = 2;
28 
30  :theLowPassKernelWidth(1.5),
31  theHighPassKernelWidth(3)
32 {
33  theAutoAdjustScales = true;
36 
37  setFilters();
38 
40 }
41 
43 {
44 }
45 
47  ossim_uint32 resLevel)
48 {
50  {
52  }
53 
55  {
56  return theInputConnection->getTile(rect, resLevel);
57  }
58 
60  {
63  1,
64  rect.width(),
65  rect.height());
68  1,
69  rect.width(),
70  rect.height());
73  }
74 
79 
81  {
82  initialize();
83  }
84 
85  ossimRefPtr<ossimImageData> lowTile = theLowPassFilter->getTile(rect, resLevel);
86  ossimRefPtr<ossimImageData> highTile = theHighPassFilter->getTile(rect, resLevel);
87 // ossimRefPtr<ossimImageData> highTile = getNormIntensity(rect, resLevel);
88 
89  // if we don't have valid low and high pass then return the input color tile
90  // in its original format
91  //
92  if(!lowTile.valid()||!highTile.valid())
93  {
94 // return theInputConnection->getTile(rect, resLevel);
95  return 0;
96  }
97 
98  if((lowTile->getDataObjectStatus() == OSSIM_EMPTY)||
99  (!lowTile->getBuf()) ||
100  (highTile->getDataObjectStatus() == OSSIM_EMPTY)||
101  (!highTile->getBuf()))
102  {
103 // return theInputConnection->getTile(rect, resLevel);
104  return 0;
105  }
106 
107  ossimRefPtr<ossimImageData> normColorData = getNormTile(rect, resLevel);
108 
109  if(!normColorData.valid())
110  {
111  return 0;
112 // return theTile;
113  }
114 
115  // Must set the rectangle before querrying height and width.
116  theTile->setImageRectangle(rect);
117 
118  // Do a make blank in case the whole tile is not stuffed.
119  theTile->makeBlank();
120 
121  if((normColorData->getDataObjectStatus() == OSSIM_EMPTY)||
122  !normColorData->getBuf())
123  {
124  return theTile;
125  }
126 
127  ossim_uint32 y = 0;
128  ossim_uint32 x = 0;
131 
132  ossimRefPtr<ossimImageData> normColorOutputData = (ossimImageData*)normColorData->dup();
133  normColorOutputData->setImageRectangle(rect);
134  normColorOutputData->loadTile(normColorData.get());
135 
136  // ossim_float64 slopeResult = 0.0;
137  ossim_uint32 idx = 0;
138  std::vector<ossim_float32*> bands(normColorData->getNumberOfBands());
139 
140  // Use copyTileBand... in case n-band data passed in for pan input.
143 
147  lowPan->setImageRectangle(rect);
148  lowPan->loadTile(theNormLowPassTile.get());
150  highPan->setImageRectangle(rect);
151  highPan->loadTile(theNormHighPassTile.get());
152 
153  ossim_float32* panHigh = (ossim_float32*)highPan->getBuf();
154  ossim_float32* panLow = (ossim_float32*)lowPan->getBuf();
155  for(idx = 0; idx < bands.size(); ++idx)
156  {
157  bands[idx] = (ossim_float32*)normColorOutputData->getBuf(idx);
158  }
159  // double delta = 0.0;
160  ossim_uint32 bandsSize = (ossim_uint32)bands.size();
161  double normMinPix = 0.0;
162  for(y = 0; y < h; ++y)
163  {
164  for(x = 0; x < w; ++x)
165  {
166  for(idx = 0; idx < bandsSize; ++idx)
167  {
168  if((*bands[idx] != 0.0)&&
169  (*panLow > FLT_EPSILON) ) // if band is not null and not divide by 0
170  {
171  normMinPix = (ossim_float32)normColorOutputData->getMinPix(idx);
172  *bands[idx] = ((*bands[idx])*(*panHigh))/
173  (*panLow);
174  if(*bands[idx] > 1.0) *bands[idx] = 1.0;
175  if(*bands[idx] < normMinPix) *bands[idx] = normMinPix;
176  }
177  // let's comment out the nulling and we will instead just pass the color on
178  //
179 // else
180 // {
181 // *bands[idx] = 0.0;
182 // }
183  ++bands[idx];
184  }
185  ++panHigh;
186  ++panLow;
187  }
188  }
189 
190  theTile->copyNormalizedBufferToTile((ossim_float32*)normColorOutputData->getBuf());
191  theTile->validate();
192 
193  return theTile;
194 }
195 
197 {
200  {
203  }
204  else
205  {
211  setFilters();
215  {
217  {
218  ossimTypeNameVisitor visitor("ossimImageRenderer", true);
219 
220  theInputConnection->accept(visitor);
222  visitor.reset();
223  theIntensityConnection->accept(visitor);
225 
226 
227  if(inputColor.valid()&&inputPan.valid())
228  {
229  ossimImageSource* inputColorSource = dynamic_cast<ossimImageSource*> (inputColor->getInput());
230  ossimImageSource* inputPanSource = dynamic_cast<ossimImageSource*> (inputPan->getInput());
231 
232  if(inputColorSource&&inputPanSource)
233  {
234  ossimRefPtr<ossimImageGeometry> colorGeom = inputColorSource->getImageGeometry();
235  ossimRefPtr<ossimImageGeometry> intensityGeom = inputPanSource->getImageGeometry();
236  if(colorGeom.valid()&&intensityGeom.valid())
237  {
238  ossimDpt gsdIntensity = intensityGeom->getMetersPerPixel();
239  ossimDpt gsdColor = colorGeom->getMetersPerPixel();
240  if(!gsdColor.hasNans()&&!gsdIntensity.hasNans())
241  {
242  double scaleChange = gsdColor.length()/gsdIntensity.length();
243  if(scaleChange < 1.0) scaleChange = 1.0;
244  setParameterOffset(LOW_PASS_WIDTH_OFFSET,
245  scaleChange);
246  }
247  }
248  }
249  }
250  }
251  }
252  }
253 }
254 
256 {
258 
260  theHighPassMatrix = 0;
262 
263  // adjust the gain for the high pass filter
264  //
265  NEWMAT::Matrix high = theHighPassMatrix;
266 
268  double gain = computeParameterOffset(HIGH_PASS_GAIN_OFFSET)*(kernelW2);
269  double multiplier = gain/(kernelW2);
270  high = -multiplier;
273 
274  if(gain > FLT_EPSILON)
275  {
276  high[cy][cx] = multiplier* ( (kernelW2-1)+kernelW2/gain);
277  }
278  else
279  {
280  high = 0.0;
281  high[cy][cx] = 1.0;
282  }
283 
285 }
286 
288 {
289  resizeAdjustableParameterArray(NUMBER_OF_ADJUSTABLE_PARAMETERS);
290 
291  setAdjustableParameter(HIGH_PASS_GAIN_OFFSET,
292  -1.0);
293  setParameterDescription(HIGH_PASS_GAIN_OFFSET,
294  "High pass gain");
295  setParameterSigma(HIGH_PASS_GAIN_OFFSET,
296  1);
297  setParameterCenter(HIGH_PASS_GAIN_OFFSET,
298  1.0);
299 
300  setAdjustableParameter(LOW_PASS_WIDTH_OFFSET,
301  -1);
302  setParameterDescription(LOW_PASS_WIDTH_OFFSET,
303  "Low pass kernel width");
304  setParameterSigma(LOW_PASS_WIDTH_OFFSET,
305  40);
306  setParameterCenter(LOW_PASS_WIDTH_OFFSET,
307  40.5);
308 
309 
310  setParameterOffset(LOW_PASS_WIDTH_OFFSET,
311  1.5);
312 }
313 
315 {
316 // std::cout << "Parameter offset = " << computeParameterOffset(2) << std::endl;
317  theLowPassKernelWidth = (ossim_uint32)(ossim::round<int>(computeParameterOffset(LOW_PASS_WIDTH_OFFSET)));
318 }
319 
321 {
322  ossimString name = property->getName();
323  if(name=="low_pass_kernel_width")
324  {
325  setParameterOffset(LOW_PASS_WIDTH_OFFSET,
326  property->valueToString().toDouble(),
327  true);
328  }
329  else if(name=="high_pass_gain")
330  {
331  setParameterOffset(HIGH_PASS_GAIN_OFFSET,
332  property->valueToString().toDouble(),
333  true);
334  }
335  else if(name=="auto_adjust_scales")
336  {
337  theAutoAdjustScales = property->valueToString().toBool();
338  }
339  else
340  {
342  }
343 }
344 
346 {
347  if(name == "low_pass_kernel_width")
348  {
349  ossimNumericProperty* prop = new ossimNumericProperty(name,
350  ossimString::toString(computeParameterOffset(LOW_PASS_WIDTH_OFFSET)),
351  getParameterCenter(LOW_PASS_WIDTH_OFFSET)-getParameterSigma(LOW_PASS_WIDTH_OFFSET),
352  getParameterCenter(LOW_PASS_WIDTH_OFFSET)+getParameterSigma(LOW_PASS_WIDTH_OFFSET));
353  prop->setCacheRefreshBit();
354  return prop;
355  }
356  else if(name == "high_pass_gain")
357  {
358  ossimNumericProperty* prop = new ossimNumericProperty(name,
359  ossimString::toString(computeParameterOffset(HIGH_PASS_GAIN_OFFSET)),
360  getParameterCenter(HIGH_PASS_GAIN_OFFSET)-getParameterSigma(HIGH_PASS_GAIN_OFFSET),
361  getParameterCenter(HIGH_PASS_GAIN_OFFSET)+getParameterSigma(HIGH_PASS_GAIN_OFFSET));
362  prop->setCacheRefreshBit();
363  return prop;
364  }
365  else if(name=="auto_adjust_scales")
366  {
368  prop->setCacheRefreshBit();
369  return prop;
370  }
371 
373 }
374 
375 void ossimSFIMFusion::getPropertyNames(std::vector<ossimString>& propertyNames)const
376 {
378  propertyNames.push_back("low_pass_kernel_width");
379  propertyNames.push_back("high_pass_gain");
380  propertyNames.push_back("auto_adjust_scales");
381 }
382 
384  const char* prefix) const
385 {
386  ossimFusionCombiner::saveState(kwl, prefix);
387  saveAdjustments(kwl, prefix);
388  kwl.add(prefix,
389  "auto_adjust_scales",
391  true);
392 
393  return true;
394 }
395 
397  const char* prefix)
398 {
399  ossimFusionCombiner::loadState(kwl, prefix);
400  loadAdjustments(kwl, prefix);
402  ossimString autoAdjustScales = kwl.find(prefix, "auto_adjust_scales");
403 
404  if(!autoAdjustScales.empty())
405  {
406  theAutoAdjustScales = autoAdjustScales.toBool();
407  }
408  return true;
409 }
virtual void valueToString(ossimString &valueResult) const =0
virtual ossim_uint32 getWidth() const
ossim_uint32 x
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)
Represents serializable keyword/value map.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
float ossim_float32
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual void copyTileBandToNormalizedBuffer(ossim_uint32 band, ossim_float64 *buf) const
Will copy this tiles specified band number to the normalized buffer.
virtual void adjustableParametersChanged()
ossim_uint32 theHighPassKernelWidth
ossim_uint32 height() const
Definition: ossimIrect.h:487
static ossimString toString(bool aValue)
Numeric to string methods.
ossimRefPtr< ossimImageData > theTile
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)
This class imlements the fusion algorithm from the paper:
double length() const
Definition: ossimDpt.h:81
virtual void initialize()
Initialize the data buffer.
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossimObject * dup() const
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
virtual void setProperty(ossimRefPtr< ossimProperty > property)
NEWMAT::Matrix theHighPassMatrix
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual ossimDataObjectStatus validate() const
void setParameterOffset(ossim_uint32 idx, ossim_float64 value, bool notify=false)
RTTI_DEF2(ossimSFIMFusion, "ossimSFIMFusion", ossimFusionCombiner, ossimAdjustableParameterInterface)
class for symmetric Gaussian filtering implemented as two separable horizontal/vertical gaussian filt...
virtual ~ossimSFIMFusion()
#define FLT_EPSILON
ossimImageSource * theIntensityConnection
virtual void setConvolution(const double *kernel, int nrows, int ncols, bool doWeightedAverage=false)
bool toBool() const
String to numeric methods.
unsigned int ossim_uint32
ossimDpt getMetersPerPixel() const
Returns the GSD associated with this image in the active projection.
32 bit normalized floating point
ossimRefPtr< ossimImageData > theNormLowPassTile
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
bool loadAdjustments(const ossimKeywordlist &kwl, const ossimString &prefix=ossimString(""))
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_float64 theLowPassKernelWidth
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimRefPtr< ossimImageData > theNormHighPassTile
bool hasNans() const
Definition: ossimDpt.h:67
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if not defined...
virtual const ossim_float64 * getMinPix() const
virtual void makeBlank()
Initializes data to null pixel values.
T * getObjectAs(ossim_uint32 idx=0)
Definition: ossimVisitor.h:64
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
virtual const void * getBuf() const
void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
bool empty() const
Definition: ossimString.h:411
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
ossimRefPtr< ossimConvolutionSource > theHighPassFilter
virtual void accept(ossimVisitor &visitor)
We will add a visitor interface for all connectable objects.
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.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual void disconnectAllInputs()
Will disconnect all of the input objects.
void setParameterCenter(ossim_uint32 idx, double center, bool notify=false)
ossimRefPtr< ossimImageGaussianFilter > theLowPassFilter
virtual void initAdjustableParameters()
void setParameterSigma(ossim_uint32 idx, double value, bool notify=false)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
void setCacheRefreshBit()
int ossim_int32
virtual void initialize()
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)