OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDilationFilter.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: ossimDilationFilter.cpp 21631 2012-09-06 18:10:55Z dburken $
12 
18 #include <vector>
19 #include <numeric>
20 
21 using namespace std;
22 
24 
25 // Keywords used throughout.
26 static const ossimString WINDOW_SIZE_KW = "window_size";
27 static const ossimString RECURSIVE_DILATION_KW = "recursive_dilation";
28 
30  :ossimImageSourceFilter(owner),
31  theTile(0),
32  theTempTile(0),
33  theWindowSize(15),
34  theRecursiveFlag(false),
35  theNullFoundFlag(false)
36 {
37  setDescription(ossimString("Dilation Filter"));
38 }
39 
41 {
42 }
43 
45 {
47  theTile = NULL;
48 }
49 
51  ossim_uint32 resLevel)
52 {
53  if(!isSourceEnabled())
54  return ossimImageSourceFilter::getTile(rect, resLevel);
55 
57  if (theRecursiveFlag)
58  inputData = ossimImageSourceFilter::getTile(rect, resLevel);
59  else
60  {
61  ossim_uint32 halfSize = getWindowSize()>>1;
62  ossimIrect requestRect(rect.ul().x - halfSize,
63  rect.ul().y - halfSize,
64  rect.lr().x + halfSize,
65  rect.lr().y + halfSize);
66 
67  inputData = ossimImageSourceFilter::getTile(requestRect, resLevel);
68  }
69 
70  if(!inputData.valid() || !inputData->getBuf())
71  return inputData;
72 
73  vector<ossimIpt> viv;
76 
77  if(!theTile.valid())
78  {
79  theTile = (ossimImageData*)inputData->dup();
81  }
82  else
83  {
85  }
86 
87  theNullFoundFlag = false;
88  switch(inputData->getScalarType())
89  {
90  case OSSIM_UINT8:
91  doDilation(ossim_uint8(0), inputData);
92  break;
93  case OSSIM_USHORT11:
94  case OSSIM_USHORT12:
95  case OSSIM_USHORT13:
96  case OSSIM_USHORT14:
97  case OSSIM_USHORT15:
98  case OSSIM_UINT16:
99  doDilation(ossim_uint16(0), inputData);
100  break;
101  case OSSIM_SINT16:
102  doDilation(ossim_sint16(0), inputData);
103  break;
104  case OSSIM_UINT32:
105  doDilation(ossim_uint32(0), inputData);
106  break;
107  case OSSIM_FLOAT32:
109  doDilation(ossim_float32(0), inputData);
110  break;
111  case OSSIM_FLOAT64:
113  doDilation(ossim_float64(0), inputData);
114  break;
115  default:
116  {
118  << "ossimDilationFilter::applyFilter WARNING:\n"
119  << "Unhandled scalar type!" << endl;
120  }
121  }
122  return theTile;
123 }
124 
125 template <class T>
127 {
129 
130  if ((status == OSSIM_FULL) || (status == OSSIM_EMPTY))
131  {
132  // Nothing to do just copy the tile.
133  theTile->loadTile(inputData.get());
134  return;
135  }
136 
137  ossim_int32 halfWindow = (ossim_int32)(theWindowSize >> 1);
138  ossim_int32 x, y, kernelX, kernelY;
139  ossim_int32 iw = (ossim_int32)inputData->getWidth();
140  ossim_int32 ih = (ossim_int32)inputData->getHeight();
143  ossim_uint32 numBands = ossim::min(theTile->getNumberOfBands(), inputData->getNumberOfBands());
144 
145  // It may be that the input rect is the same size as the output (i.e., the tile bounds aren't
146  // expanded in the input's request to permit full kernels for output edge pixels:
147  ossim_uint32 i_offset = 0;
148  ossim_int32 delta = (ossim_int32)((iw - ow) >> 1);
149  ossim_int32 xi, yi;
150  if (delta > 0)
151  i_offset = (ossim_uint32) halfWindow*(iw + 1);
152 
153  ossimIpt tile_ul (theTile->getImageRectangle().ul());
154  vector<double> values;
155  for(ossim_uint32 bandIdx = 0; bandIdx < numBands; ++bandIdx)
156  {
157  T* inputBuf = (T*)inputData->getBuf(bandIdx);
158  T* outputBuf = (T*)theTile->getBuf(bandIdx);
159  if (!inputBuf || !outputBuf)
160  {
161  return; // Shouldn't happen...
162  }
163 
164  const T NP = (T)inputData->getNullPix(bandIdx);
165 
166  for(y = 0; y < oh; ++y)
167  {
168  for(x = 0; x < ow; ++x)
169  {
170  // Get the center input pixel. Only process those points inside the valid image
171  // (to avoid dilation beyond valid image)
172  const T CP = *(inputBuf+i_offset);
173  ossimDpt ipt (tile_ul.x+x, tile_ul.y+y);
174  if ((CP == NP) && theValidImagePoly.isPointWithin(ipt))
175  {
176  theNullFoundFlag = true; // Needed for recursion
177  values.clear();
178  for(kernelY = -halfWindow; kernelY <= halfWindow; ++kernelY)
179  {
180  yi = y + kernelY + delta;
181  if ((yi < 0) || (y > ih))
182  continue;
183 
184  for(kernelX = -halfWindow; kernelX <= halfWindow; ++kernelX)
185  {
186  xi = x + kernelX + delta;
187  if ((xi < 0) || (x > iw))
188  continue;
189 
190  T tempValue = *(inputBuf+kernelX+delta + (kernelY+delta)*iw);
191  if(tempValue != NP)
192  values.push_back((double)tempValue);
193  }
194  }
195 
196  if(values.size() > 0)
197  {
198  double accum = accumulate(values.begin(), values.end(), 0.0);
199  double average = accum/(double)values.size();
200  (*outputBuf) = (T)average;
201  }
202  else
203  {
204  (*outputBuf) = NP;
205  }
206 
207  }
208  else // Center pixel (CP) not null.
209  {
210  (*outputBuf) = CP;
211  }
212 
213  // Move over...
214  ++inputBuf;
215  ++outputBuf;
216 
217  } // End of loop in x direction.
218 
219  // Move down...
220  inputBuf += iw - ow;
221 
222  } // End of loop in y direction.
223 
224  } // End of band loop.
225 
226  theTile->validate();
227 
228  // Set up recursion for "dilation fill mode", we'll keep calling this getTile until all pixels
229  // are filled with non-null values:
230  if (theRecursiveFlag)
231  {
232  //cout << "Percent Full: "<<theTile->percentFull()<<endl; //###
233  //theTile->write("filtered.ras"); //###
234 
236  if (theNullFoundFlag)
237  {
238  theNullFoundFlag = false; // assume will fill, set true in next recursion if null found
240  doDilation(scalarType, theTempTile);
241  }
242  }
243 }
244 
246 {
247  if (!property.valid())
248  return;
249 
250  ossimString name = property->getName();
251 
252  if (name == WINDOW_SIZE_KW)
253  {
254  theWindowSize = property->valueToString().toUInt32();
255  }
256  else if (name == RECURSIVE_DILATION_KW)
257  {
258  ossimString value;
259  property->valueToString(value);
260  setRecursiveFlag(value.toBool());
261  }
262  else
263  {
265  }
266 }
267 
269 {
271  if (name == WINDOW_SIZE_KW)
272  {
273  prop = new ossimNumericProperty(WINDOW_SIZE_KW, ossimString::toString(theWindowSize), 3, 25);
274  prop->setCacheRefreshBit();
275  return prop;
276  }
277  else if (name == RECURSIVE_DILATION_KW)
278  {
279  prop = new ossimBooleanProperty(RECURSIVE_DILATION_KW, getRecursiveFlag());
280  prop->setFullRefreshBit();
281  return prop;
282  }
284 }
285 
286 void ossimDilationFilter::getPropertyNames(vector<ossimString>& propertyNames) const
287 {
288  propertyNames.push_back(WINDOW_SIZE_KW);
289  propertyNames.push_back(RECURSIVE_DILATION_KW);
291 }
292 
293 bool ossimDilationFilter::saveState(ossimKeywordlist& kwl, const char* prefix)const
294 {
295  kwl.add(prefix, WINDOW_SIZE_KW.c_str(), theWindowSize, true);
296  kwl.add(prefix, RECURSIVE_DILATION_KW.c_str(), (theRecursiveFlag?"true":"false"), true);
297  return ossimImageSourceFilter::saveState(kwl, prefix);
298 }
299 
300 bool ossimDilationFilter::loadState(const ossimKeywordlist& kwl, const char* prefix)
301 {
302  const char* lookup = kwl.find(prefix, WINDOW_SIZE_KW.c_str());
303  if (lookup)
304  theWindowSize = ossimString(lookup).toUInt32();
305 
306  lookup = kwl.find(prefix, RECURSIVE_DILATION_KW.c_str());
307  if (lookup)
308  setRecursiveFlag(ossimString(lookup).toBool());
309 
310  return ossimImageSourceFilter::loadState(kwl, prefix);
311 }
16 bit unsigned integer (15 bits used)
virtual ossim_uint32 getWidth() const
ossim_uint32 x
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual void setDescription(const ossimString &description)
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossim_uint32 getNumberOfBands() const
64 bit floating point
virtual void setImageRectangle(const ossimIrect &rect)
16 bit unsigned integer
Represents serializable keyword/value map.
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
float ossim_float32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
static ossimString toString(bool aValue)
Numeric to string methods.
ossim_uint32 theWindowSize
Used for recursion when recursive fill enabled
16 bit signed integer
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
ossim_uint32 toUInt32() const
16 bit unsigned integer (13 bits used)
32 bit floating point
RTTI_DEF1(ossimDilationFilter, "ossimDilationFilter", ossimImageSourceFilter)
unsigned short ossim_uint16
ossimPolygon theValidImagePoly
32 bit unsigned integer
virtual ossimObject * dup() const
void setFullRefreshBit()
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)
virtual ossimDataObjectStatus validate() const
signed short ossim_sint16
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual void setImageRectangleAndBands(const ossimIrect &rect, ossim_uint32 numberOfBands)
bool toBool() const
String to numeric methods.
virtual void getValidImageVertices(std::vector< ossimIpt > &validVertices, ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER, ossim_uint32 resLevel=0) const
ordering specifies how the vertices should be arranged.
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual ossimIrect getImageRectangle() 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.
void setRecursiveFlag(bool flag=true)
Set if getTile is to be called recursively until all pixels have been assigned non-null.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
T min(T a, T b)
Definition: ossimCommon.h:203
ossimRefPtr< ossimImageData > theTile
bool getRecursiveFlag() const
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
return status
virtual ossimScalarType getScalarType() const
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
ossim_int32 y
Definition: ossimIpt.h:142
bool isPointWithin(const ossimDpt &point) const
virtual const void * getBuf() 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.
void doDilation(T scalarType, ossimRefPtr< ossimImageData > &inputData)
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
ossimDilationFilter(ossimObject *owner=NULL)
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
ossim_int32 x
Definition: ossimIpt.h:141
8 bit unsigned integer
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
ossimDataObjectStatus
Definitions for data object status.
ossim_uint32 getWindowSize() const
unsigned char ossim_uint8
ossimRefPtr< ossimImageData > theTempTile
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void setCacheRefreshBit()
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
16 bit unsigned integer (12 bits used)