26 #include "Thinning.hh"
29 #include "Base/Image/ImageIO.hh"
32 #include <Base/Common/BIASpragma.hh>
37 template <
class InputStorageType,
class OutputStorageType>
40 :
FilterNToN<InputStorageType, OutputStorageType>()
44 template <
class InputStorageType,
class OutputStorageType>
47 :
FilterNToN<InputStorageType, OutputStorageType>(other)
51 template <
class InputStorageType,
class OutputStorageType>
57 template <
class InputStorageType,
class OutputStorageType>
61 BIASERR(
"Unimplemented interface, calling generic Filter");
62 return Filter(src, dst);
65 template <
class InputStorageType,
class OutputStorageType>
69 BIASERR(
"Unimplemented interface, calling generic Filter");
70 return Filter(src, dst);
74 template <
class InputStorageType,
class OutputStorageType>
78 BIASCDOUT(D_FILTERBASE_CALLSTACK,
"Thinning::Rosenfeld_\n");
85 std::vector < std::vector < bool > > Econnected_;
86 std::vector < std::vector < bool > > Eendpoint_;
87 std::vector < std::vector < bool > > Eisolated_;
88 std::vector < std::vector < bool > > Esimple_;
90 std::vector < std::vector < bool > > northBorder_;
91 std::vector < std::vector < bool > > southBorder_;
92 std::vector < std::vector < bool > > eastBorder_;
93 std::vector < std::vector < bool > > westBorder_;
96 int not_simple[] = {144,136,132,80,72,68,66,65,36,34,
97 33,20,18,17,9,5,208,200,196,164,
98 148,152,146,145,140,137,133,100,98,97,
99 84,82,81,88,76,74,73,70,69,67,
100 52,50,49,41,38,37,35,25,22,21,
101 19,13,228,216,212,210,209,204,201,197,
102 116,114,113,105,102,101,99,180,165,156,
103 153,150,149,147,141,92,90,89,86,85,
104 83,78,77,75,71,57,54,53,51,45,
105 39,29,23,220,217,214,213,211,205,241,
106 229,181,157,151,125,119,95,221,215,61,
107 55,121,118,117,115,109,103,94,93,91,
111 for (
int i = 0; i < img_height; i++)
113 std::vector< bool > just;
116 for (
int j = 0; j < img_width; j++)
119 just.push_back(
false);
122 Econnected_.push_back(just);
123 Eendpoint_.push_back(just);
124 Eisolated_.push_back(just);
125 Esimple_.push_back(just);
127 northBorder_.push_back(just);
128 southBorder_.push_back(just);
129 eastBorder_.push_back(just);
130 westBorder_.push_back(just);
133 const InputStorageType **srcida = NULL;
134 OutputStorageType **dstida = NULL;
136 if(channelcount == 1)
142 for(
int x = 0; x < img_height; x++)
144 for(
int y = 0; y < img_width; y++)
146 dstida[x][y] = (OutputStorageType)srcida[x][y];
151 for(
int bord = 0; bord < 4; bord++)
154 for(
int x = 0; x < img_height; x++)
156 for(
int y = 0; y < img_width; y++)
161 if((
int)dstida[x][y] != 0)
168 if((
int)dstida[x-1][y] > 0){
169 sum8++; sum8BIG += 64;}
171 northBorder_[x][y] =
true;}
176 if((y > 0) && ((int)dstida[x-1][y-1] > 0)){
177 sum8++; sum8BIG += 128;}
182 if((y < img_width - 1) && ((int)dstida[x-1][y+1] > 0)){
183 sum8++; sum8BIG += 32;}
185 if(x < img_height - 1)
190 if((
int)dstida[x+1][y] > 0){
191 sum8++; sum8BIG += 4;}
193 southBorder_[x][y] =
true;}
198 if((y > 0) && ((int)dstida[x+1][y-1] > 0)){
199 sum8++; sum8BIG += 2;}
204 if((y < img_width - 1) && ((int)dstida[x+1][y+1] > 0)){
205 sum8++; sum8BIG += 8;}
213 if((
int)dstida[x][y-1] > 0){
214 sum8++; sum8BIG += 1;}
216 westBorder_[x][y] =
true;}
219 if(y < img_width - 1)
224 if((
int)dstida[x][y+1] > 0){
225 sum8++; sum8BIG += 16;}
227 eastBorder_[x][y] =
true;}
235 Eendpoint_[x][y] =
true;
238 Econnected_[x][y] =
true;
239 Esimple_[x][y] =
true;
240 for(
int i = 0; i < 122; i++)
242 if(sum8BIG == not_simple[i]){Esimple_[x][y] =
false;}
247 Eisolated_[x][y] =
true;
252 for(
int x = 0; x < img_height; x++)
254 for(
int y = 0; y < img_width; y++)
265 (((bord == 0) && northBorder_[x][y]) ||
266 ((bord == 1) && southBorder_[x][y]) ||
267 ((bord == 2) && eastBorder_[x][y]) ||
268 ((bord == 3) && westBorder_[x][y])
271 dstida[x][y]=(OutputStorageType)(0);
281 #define FILTER_INSTANTIATION_CLASS Thinning
282 #include "Filterinst.hh"
unsigned int GetWidth() const
generic Thinning class, uses ethe Rosenfeld algorithm to thin structures in images without erasing th...
virtual int FilterFloat(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
only calls filter, for consistency of params
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
base class for simple n->n filter implementations
unsigned int GetHeight() const
virtual int FilterInt(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
only calls filter, for consistency of params
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
makes Rosenfeld-Thinning on src-Image and puts it in Destionation-Image
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase