Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Erosion.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 
26 
27 #include "Erosion.hh"
28 
29 using namespace BIAS;
30 using namespace std;
31 
32 template <class InputStorageType, class OutputStorageType>
35  Image<OutputStorageType>& Destination,
36  int KernelSize) {
37  if (Destination.IsEmpty()) {
38  Destination.Init(Source.GetWidth(), Source.GetHeight(),
39  Source.GetChannelCount());
40  Destination.SetColorModel(ImageBase::CM_Grey);
41  }
42 #ifdef BIAS_BOUNDS_CHECK
43  if (Source.GetChannelCount() !=1)
44  BIASERR("Erosion<StorageType>::Dilate() only implemented for grey images");
45  if (! Source.SamePixelAndChannelCount(Destination))
46  BIASERR("Erosion<StorageType>::Dilate() wrong images sizes");
47  if (KernelSize % 2 != 1)
48  BIASERR("Erosion<StorageType>::Dilate() odd KernelSize required");
49 #endif
50 
51  int Width = Source.GetWidth();
52  int Height = Source.GetHeight();
53  register int HalfKernelSize = (KernelSize - 1) / 2;
54  register OutputStorageType **DestArray = Destination.GetImageDataArray();
55  register const InputStorageType **SourceArray = Source.GetImageDataArray();
56 
57  // loop
58  for (register int y = HalfKernelSize;
59  y < (Height - HalfKernelSize); y++) {
60  for (register int x = HalfKernelSize;
61  x < (Width - HalfKernelSize); x++) {
62  DestArray[y][x] = OutputStorageType(SourceArray[y][x]);
63  for (register int ky = -HalfKernelSize; ky <= HalfKernelSize; ky++)
64  for (register int kx = -HalfKernelSize; kx <= HalfKernelSize; kx++)
65  if ( (DestArray[y][x]==0) || (SourceArray[y+ky][x+kx]==0) )
66  DestArray[y][x] = 0;
67  }
68  }
69 
70  // fill borders with zero
71  this->FillBorderConst(Destination, (unsigned short int)HalfKernelSize,
72  (unsigned short int)HalfKernelSize, (OutputStorageType)0);
73  return 0;
74 }
75 
76 
77 
78 template <class InputStorageType, class OutputStorageType>
82  bool Neighbor4) {
83 #ifdef BIAS_BOUNDS_CHECK
84  if ((src.GetChannelCount() !=1) || (dest.GetChannelCount() !=1)) {
85  BIASERR("Erosion<StorageType>::Erode3Fast() only implemented for grey images");
86  return -1;
87  }
88  if (src.GetPixelCount()<25) {
89  BIASERR("Erosion<StorageType>::Erode3Fast(): src has less than 25 pixel");
90  return -2;
91  }
92  if ( (src.GetHeight()<5) || (src.GetWidth() < 5)) {
93  BIASERR("Erosion<StorageType>::Erode3Fast(): src has less than 5 cols or rows");
94  return -3;
95  }
96  if (src.GetPixelCount() != dest.GetPixelCount()) {
97  BIASERR("Erosion<StorageType>::Erode3Fast(): src and dest have different sizes");
98  return -3;
99  }
100 #endif
101  // copy src to dest
102  // memcpy(dest.GetImageData() , src.GetImageData(),
103  // src.GetPixelCount() * sizeof(StorageType));
104  memset(dest.GetImageData(),0,src.GetPixelCount()*sizeof(OutputStorageType));
105  register OutputStorageType *d=dest.GetImageDataArray()[1]+1;
106  register const InputStorageType *p1=src.GetImageDataArray()[0];
107  register const InputStorageType *p2=p1+1, *p3 = p2+1;
108  register const InputStorageType *p4=src.GetImageDataArray()[1];
109  register const InputStorageType *p5 = p4+1, *p6=p5+1;
110  register const InputStorageType *p7 =src.GetImageDataArray()[2];
111  register const InputStorageType *p8 = p7+1, *p9=p8+1;
112  register const InputStorageType *last=&(src.GetImageData()[src.GetPixelCount()-1]);
113  if (Neighbor4) {
114  while (p8<last) {
115  if (*p5 != 0)
116  if (*p2!=0)
117  if (*p4!=0)
118  if (*p6!=0)
119  if (*p8!=0)
120  *d = OutputStorageType(*p5);
121  p2++; p4++; p5++; p6++; p8++; d++;
122  }
123  } else {
124  while (p9<=last) {
125  if (*p5 != 0)
126  if (*p1!=0)
127  if (*p2!=0)
128  if (*p3!=0)
129  if (*p4!=0)
130  if (*p6!=0)
131  if (*p7!=0)
132  if (*p8!=0)
133  if (*p9!=0)
134  *d = OutputStorageType(*p5);
135  p1++; p2++; p3++; p4++; p5++; p6++; p7++; p8++; p9++; d++;
136  }
137  }
138  //// set border to zero
139  // top and bottom
140  register OutputStorageType *o1, *o9, *o2, *olast;
141  o1 = dest.GetImageDataArray()[0];
142  o9 = dest.GetImageDataArray()[dest.GetHeight()-1];
143  olast=
144  &(dest.GetImageData()[(dest.GetPixelCount()-1)*dest.GetChannelCount()]);
145  while (o9<=olast) {
146  *o1=0; *o9=0;
147  o1++; o9++;
148  }
149  // left and right
150  register int offset = dest.GetWidth()*dest.GetChannelCount();
151  o1 = dest.GetImageData();
152  o2 = o1+offset-1;
153  while (o2<=olast) {
154  *o1=0; *o2=0;
155  o1+=offset; o2+=offset;
156  }
157  return 0;
158 }
159 
160 template <class InputStorageType, class OutputStorageType>
164  if (src.GetChannelCount()!=1) {
165  BIASERR("Erosion only for 1 channel images");
166  return -1;
167  }
168  if (_FilterBorderHandling==TBH_valid) {
169  if (kernelSize_==3) {
170  if ( (dst.IsEmpty()) || (! src.SamePixelAndChannelCount(dst)) )
171  dst=src;
172  Erode3Fast(src,dst,false);
173  dst.GetROI()->SetCorners(1,1,dst.GetWidth()-2,dst.GetHeight()-2);
174  } else {
175  Erode(src,dst,kernelSize_);
176  dst.GetROI()->SetCorners(1,1,dst.GetWidth()-2,dst.GetHeight()-2);
177  }
178  } else if (_FilterBorderHandling==TBH_same) {
180  tmp.Init(src.GetWidth()+ int(kernelSize_/2)*2,
181  src.GetHeight()+ int(kernelSize_/2)*2,1);
182  tmp.FillImageWithConstValue(InputStorageType(0));
183  tmp.GetROI()->SetCorners(kernelSize_/2 ,kernelSize_/2 ,
184  tmp.GetWidth()-(kernelSize_/2),
185  tmp.GetHeight()-(kernelSize_/2));
186  tmp.Paste2ROI(src);
187  dst.Release();
188  Erode(tmp,dst,kernelSize_);
189  dst.GetROI()->SetCorners(kernelSize_/2 ,kernelSize_/2 ,
190  tmp.GetWidth() -(kernelSize_/2),
191  tmp.GetHeight()-(kernelSize_/2));
192  dst.Cut2ROI();
193  } else {
194  BIASERR("borderhandling not implemnted/");
195  return -1;
196  }
197  return 0;
198 }
199 
200 template <class InputStorageType, class OutputStorageType>
202 GetBordersValid_(int& /*border_x*/, int& /*border_y*/) const
203 {
204  BIASERR("no parameter support");
205  BIASABORT;
206 }
207 
208 
209 //////////////////////////////////////////////////////////////////////////
210 // instantiation
211 //////////////////////////////////////////////////////////////////////////
212 
213 namespace BIAS{
214 #define FILTER_INSTANTIATION_CLASS Erosion
215 #include "Filterinst.hh"
216 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Does the erosion.
Definition: Erosion.cpp:162
int Cut2ROI()
reduces image to current ROI, !!! image size changes !!!
Definition: ImageBase.cpp:646
gray values, 1 channel
Definition: ImageBase.hh:130
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
Definition: ROI.cpp:287
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
unsigned int GetWidth() const
Definition: ImageBase.hh:312
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:615
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
int Erode3Fast(const Image< InputStorageType > &src, Image< OutputStorageType > &dest, bool Neighbor4=false)
Very fast erode with 3x3 mask, all values, which are not not zero, are treated as foreground...
Definition: Erosion.cpp:80
void FillImageWithConstValue(StorageType Value)
fill grey images
Definition: Image.cpp:456
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
int Paste2ROI(const ImageBase &Image)
paste Image to current ROI
Definition: ImageBase.cpp:603
virtual void GetBordersValid_(int &border_x, int &border_y) const
Definition: Erosion.cpp:202
unsigned long int GetPixelCount() const
returns number of pixels in image
Definition: ImageBase.hh:422
int Erode(const Image< InputStorageType > &Source, Image< OutputStorageType > &Destination, int KernelSize=3)
erode with square kernel filled with 255
Definition: Erosion.cpp:34
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153