OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimImageToPlaneNormalFilter.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 //
10 //*************************************************************************
11 // $Id: ossimImageToPlaneNormalFilter.cpp 23451 2015-07-27 15:42:17Z okramer $
20 
21 static const char* SMOOTHNESS_FACTOR_KW="smoothness_factor";
22 
23 RTTI_DEF1(ossimImageToPlaneNormalFilter, "ossimImageToPlaneNormalFilter", ossimImageSourceFilter);
24 
27  theTile(NULL),
28  theBlankTile(NULL),
29  theTrackScaleFlag(true),
30  theXScale(1.0),
31  theYScale(1.0),
32  theSmoothnessFactor(1.0)
33 {
34 }
35 
37  :ossimImageSourceFilter(inputSource),
38  theTile(NULL),
39  theBlankTile(NULL),
40  theTrackScaleFlag(true),
41  theXScale(1.0),
42  theYScale(1.0),
43  theSmoothnessFactor(1.0)
44 {
45 }
46 
48  const ossimIrect& tileRect,
49  ossim_uint32 resLevel)
50 {
52  {
53  return ossimImageSourceFilter::getTile(tileRect, resLevel);
54  }
55 
56  if(!theTile.valid())
57  {
58  initialize();
59  }
60 
61  if(!theTile.valid())
62  {
63  return ossimImageSourceFilter::getTile(tileRect, resLevel);
64  }
65 
66  theTile->setImageRectangle(tileRect);
67 
68  ossimIrect requestRect(tileRect.ul().x - 1,
69  tileRect.ul().y - 1,
70  tileRect.lr().x + 1,
71  tileRect.lr().y + 1);
72 
74  theInputConnection->getTile(requestRect, resLevel);
75 
76  if(!input||(input->getDataObjectStatus()==OSSIM_EMPTY)||!input->getBuf())
77  {
78  if(tileRect.completely_within(theInputBounds))
79  {
81  theTile->validate();
82  return theTile.get();
83  }
85  return theBlankTile;
86  }
87 
88  double oldScaleX = theXScale;
89  double oldScaleY = theYScale;
90 
91  if(resLevel > 0)
92  {
93  ossimDpt scaleFactor;
94  theInputConnection->getDecimationFactor(resLevel, scaleFactor);
95 
96  if(!scaleFactor.hasNans())
97  {
98  theXScale *= scaleFactor.x;
99  theYScale *= scaleFactor.y;
100  }
101  }
102 
103  computeNormals(input, theTile);
104 
105  theXScale = oldScaleX;
106  theYScale = oldScaleY;
107 
108  theTile->validate();
109 
110  return theTile;
111 }
112 
114 {
115  double* x = static_cast<double*>(theTile->getBuf(0));
116  double* y = static_cast<double*>(theTile->getBuf(1));
117  double* z = static_cast<double*>(theTile->getBuf(2));
118 
119  if(x) std::fill(x, x+theTile->getSizePerBand(), 0.0);
120  if(y) std::fill(y, y+theTile->getSizePerBand(), 0.0);
121  if(z) std::fill(z, z+theTile->getSizePerBand(), 1.0);
122 }
123 
125 {
127  {
129 
133  theTile->initialize();
134 
136  {
138  if( geom.valid() )
139  {
140  ossimDpt pt = geom->getMetersPerPixel();
141  if(!pt.hasNans())
142  {
143  theXScale = 1.0/pt.x;
144  theYScale = 1.0/pt.y;
145  }
146  }
147  }
148  }
149 }
150 
152  ossimRefPtr<ossimImageData>& inputTile,
153  ossimRefPtr<ossimImageData>& outputTile)
154 {
155  switch(inputTile->getScalarType())
156  {
157  case OSSIM_SSHORT16:
158  {
160  inputTile,
161  outputTile);
162  break;
163  }
164  case OSSIM_UCHAR:
165  {
167  inputTile,
168  outputTile);
169  break;
170  }
171  case OSSIM_USHORT11:
172  case OSSIM_USHORT12:
173  case OSSIM_USHORT13:
174  case OSSIM_USHORT14:
175  case OSSIM_USHORT15:
176  case OSSIM_USHORT16:
177  {
179  inputTile,
180  outputTile);
181  break;
182  }
184  case OSSIM_DOUBLE:
185  {
187  inputTile,
188  outputTile);
189  break;
190  }
192  case OSSIM_FLOAT:
193  {
195  inputTile,
196  outputTile);
197  break;
198  }
199  default:
200  break;
201  }
202 }
203 
205  T /* inputScalarTypeDummy */,
206  ossimRefPtr<ossimImageData>& inputTile,
207  ossimRefPtr<ossimImageData>& outputTile)
208 {
209  T inputNull = (T) inputTile->getNullPix(0);
210  T* inbuf = (T*) inputTile->getBuf();
211  T outputNull = (T) outputTile->getNullPix(0);
212  double* normX = (double*)outputTile->getBuf(0);
213  double* normY = (double*)outputTile->getBuf(1);
214  double* normZ = (double*)outputTile->getBuf(2);
215  ossim_int32 inbuf_width = inputTile->getWidth();
216  ossim_int32 normbuf_width = outputTile->getWidth();
217  ossim_int32 normbuf_height = outputTile->getHeight();
218  ossimColumnVector3d normal;
219  bool valid_component = true;
220  for (ossim_int32 y=0; y<normbuf_height; y++)
221  {
222  // Establish offsets into the image and output normals buffers given row:
223  ossim_uint32 n = y*normbuf_width;
224  ossim_uint32 i = (y+1)*inbuf_width + 1;
225 
226  // Loop to compute the gradient (normal) vector [dh/dx, dh/dy, 1]:
227  for (ossim_int32 x=0; x<normbuf_width; x++)
228  {
229  // Default in case of null inputs is a flat earth:
230  normal[0] = 0;
231  normal[1] = 0;
232  normal[2] = 1.0;
233 
234  // Compute the x-direction differential:
235  if (inbuf[i+1] != inputNull)
236  {
237  if (inbuf[i-1] != inputNull)
238  normal[0] = theXScale*theSmoothnessFactor*(inbuf[i+1] - inbuf[i-1]) / 2.0;
239  else if (inbuf[i] != inputNull)
240  normal[0] = theXScale*theSmoothnessFactor*(inbuf[i+1] - inbuf[i]);
241  }
242  else if ((inbuf[i] != inputNull) && (inbuf[i-1] != inputNull))
243  {
244  normal[0] = theXScale*theSmoothnessFactor*(inbuf[i] - inbuf[i-1]);
245  }
246  else
247  {
248  valid_component = false;
249  }
250 
251  // Compute the y-direction differential:
252  if (valid_component)
253  {
254  if (inbuf[i+inbuf_width] != inputNull)
255  {
256  if (inbuf[i-inbuf_width] != inputNull)
257  normal[1] = theYScale*theSmoothnessFactor*(inbuf[i+inbuf_width] - inbuf[i-inbuf_width]) / 2.0;
258  else if (inbuf[i] != inputNull)
259  normal[1] = theYScale*theSmoothnessFactor*(inbuf[i+inbuf_width] - inbuf[i]);
260  }
261  else if ((inbuf[i] != inputNull) && (inbuf[i-inbuf_width] != inputNull))
262  {
263  normal[1] = theYScale*theSmoothnessFactor*(inbuf[i] - inbuf[i-inbuf_width]);
264  }
265  else
266  {
267  valid_component = false;
268  }
269  }
270 
271  // Stuff the normalized gradient vector into the output buffers:
272  if (valid_component)
273  {
274  normal = normal.unit();
275  normX[n] = normal[0];
276  normY[n] = normal[1];
277  normZ[n] = normal[2];
278  }
279  else
280  {
281  normX[n] = outputNull;
282  normY[n] = outputNull;
283  normZ[n] = outputNull;
284  }
285 
286  ++n;
287  ++i;
288  valid_component = true;
289  }
290  }
291 }
292 
294  const char* prefix)
295 {
298  ossimString trackFlag = kwl.find(prefix, "track_scale_flag");
299  ossimString smoothness = kwl.find(prefix, SMOOTHNESS_FACTOR_KW);
300 
301  if(scaleX != "")
302  {
303  theXScale = scaleX.toDouble();
304  }
305  if(scaleY != "")
306  {
307  theYScale = scaleY.toDouble();
308  }
309  if(trackFlag != "")
310  {
311  theTrackScaleFlag = trackFlag.toBool();
312  }
313  if(smoothness!="")
314  {
315  theSmoothnessFactor = smoothness.toDouble();
316  }
317 
318  return ossimImageSourceFilter::loadState(kwl, prefix);
319 }
320 
322  const char* prefix)const
323 {
324  kwl.add(prefix,
326  theXScale,
327  true);
328 
329  kwl.add(prefix,
331  theXScale,
332  true);
333 
334  kwl.add(prefix,
335  "track_scale_flag",
337  true);
338 
339  kwl.add(prefix,
340  SMOOTHNESS_FACTOR_KW,
342  true);
343 
344  return ossimImageSourceFilter::saveState(kwl, prefix);
345 }
346 
348 {
349  if(!isSourceEnabled())
350  {
352  }
353  return -1;
354 }
355 
357 {
358  if(!isSourceEnabled())
359  {
361  }
362  return 1.0;
363 }
364 
366 {
367  if(isSourceEnabled())
368  {
369  return OSSIM_DOUBLE;
370  }
371 
373 }
374 
376 {
377  if(isSourceEnabled())
378  {
379  return 3;
380  }
382 }
383 
385 {
386  theXScale = scale;
387 }
388 
390 {
391  return theXScale;
392 }
393 
395 {
396  return theYScale;
397 }
398 
400 {
401  theYScale = scale;
402 }
403 
405 {
406  theTrackScaleFlag = flag;
407 }
408 
410 {
411  return theTrackScaleFlag;
412 }
413 
415 {
416  theSmoothnessFactor = value;
417 }
418 
420 {
421  return theSmoothnessFactor;
422 }
423 
425 {
426  ossimString name = property->getName();
427  if((name == "smoothnessFactor")||
428  (name == "gain"))
429  {
430  theSmoothnessFactor = property->valueToString().toDouble();
431  initialize();
432  }
433  else if(name == "xscale")
434  {
435  theXScale = property->valueToString().toDouble();
436  initialize();
437  }
438  else if(name == "yscale")
439  {
440  theYScale = property->valueToString().toDouble();
441  initialize();
442  }
443  else if(name == "autoTrackScaleFlag")
444  {
445  theTrackScaleFlag = property->valueToString().toDouble();
446  initialize();
447  }
448  else
449  {
451  }
452 }
453 
455 {
456  if((name == "smoothnessFactor")||
457  (name == "gain"))
458  {
460  prop->setCacheRefreshBit();
461  return prop;
462  }
463  else if(name == "xscale")
464  {
466  prop->setCacheRefreshBit();
467  return prop;
468  }
469  else if(name == "yscale")
470  {
472  prop->setCacheRefreshBit();
473  return prop;
474  }
475  else if(name == "autoTrackScaleFlag")
476  {
478  prop->setCacheRefreshBit();
479  return prop;
480  }
481 
483 }
484 
485 void ossimImageToPlaneNormalFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
486 {
488  propertyNames.push_back("gain");
489  propertyNames.push_back("xscale");
490  propertyNames.push_back("yscale");
491  propertyNames.push_back("autoTrackScaleFlag");
492 }
16 bit unsigned integer (15 bits used)
virtual ossim_uint32 getWidth() const
ossim_uint32 x
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual void setImageRectangle(const ossimIrect &rect)
Represents serializable keyword/value map.
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
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
double y
Definition: ossimDpt.h:165
static ossimString toString(bool aValue)
Numeric to string methods.
ossimColumnVector3d unit() const
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
16 bit unsigned integer (13 bits used)
unsigned short ossim_uint16
virtual void initialize()
Initialize the data buffer.
virtual ossimObject * dup() const
bool completely_within(const ossimIrect &rect) const
Definition: ossimIrect.cpp:425
virtual double getMinPixelValue(ossim_uint32 band=0) const
Returns the min pixel of the band.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
static const char * SCALE_PER_PIXEL_X_KW
static ossimImageDataFactory * instance()
ossimRefPtr< ossimImageData > theTile
virtual ossimDataObjectStatus validate() const
signed short ossim_sint16
bool loadState(const ossimKeywordlist &kwl, const char *prefix)
Method to the load (recreate) the state of an object from a keyword list.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
os2<< "> n<< " > nendobj n
bool toBool() const
String to numeric methods.
virtual ossim_uint32 getSizePerBand() const
Returns the number of pixels in a single band in a tile.
ossimImageSource * theInputConnection
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
ossimDpt getMetersPerPixel() const
Returns the GSD associated with this image in the active projection.
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
double toDouble() const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Returns the min pixel of the band.
RTTI_DEF1(ossimImageToPlaneNormalFilter, "ossimImageToPlaneNormalFilter", ossimImageSourceFilter)
const ossimIpt & lr() const
Definition: ossimIrect.h:276
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
virtual void setProperty(ossimRefPtr< ossimProperty > property)
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...
ossimScalarType
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
virtual ossimScalarType getScalarType() const
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
void computeNormalsTemplate(T inputScalarTypeDummy, ossimRefPtr< ossimImageData > &inputTile, ossimRefPtr< ossimImageData > &outputTile)
double x
Definition: ossimDpt.h:164
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
ossim_int32 x
Definition: ossimIpt.h:141
virtual void initialize()=0
virtual void computeNormals(ossimRefPtr< ossimImageData > &inputTile, ossimRefPtr< ossimImageData > &outputTile)
static const char * SCALE_PER_PIXEL_Y_KW
bool saveState(ossimKeywordlist &kwl, const char *prefix) const
Method to save the state of an object to a keyword list.
32 bit floating point
virtual void getDecimationFactor(ossim_uint32 resLevel, ossimDpt &result) const
Will return the decimation factor for the given resolution level.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
16 bit unsigned iteger
64 bit floating point
16 bit signed integer
unsigned char ossim_uint8
ossimRefPtr< ossimImageData > theBlankTile
void setCacheRefreshBit()
8 bit unsigned iteger
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
16 bit unsigned integer (12 bits used)