37 #ifndef VIGRA_FLATMORPHOLOGY_HXX
38 #define VIGRA_FLATMORPHOLOGY_HXX
42 #include "utilities.hxx"
136 template <
class SrcIterator,
class SrcAccessor,
137 class DestIterator,
class DestAccessor>
140 SrcIterator lowerright1, SrcAccessor sa,
141 DestIterator upperleft2, DestAccessor da,
142 int radius,
float rank)
144 vigra_precondition((rank >= 0.0) && (rank <= 1.0),
145 "discRankOrderFilter(): Rank must be between 0 and 1"
148 vigra_precondition(radius >= 0,
149 "discRankOrderFilter(): Radius must be >= 0.");
151 int i, x, y, xmax, ymax, xx, yy;
152 int rankpos, winsize, leftsum;
157 std::vector<int> struct_function(radius+1);
158 struct_function[0] = radius;
160 double r2 = (double)radius*radius;
161 for(i=1; i<=radius; ++i)
163 double r = (double) i - 0.5;
167 int w = lowerright1.x - upperleft1.x;
168 int h = lowerright1.y - upperleft1.y;
170 SrcIterator ys(upperleft1);
171 DestIterator yd(upperleft2);
173 for(y=0; y<h; ++y, ++ys.y, ++yd.y)
185 for(i=0; i<256; ++i) hist[i] = 0;
189 ymax = (y1 < radius) ? y1 : radius;
190 for(yy=0; yy<=ymax; ++yy)
192 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
193 for(xx=0; xx<=xmax; ++xx)
195 hist[sa(xs, Diff2D(xx, yy))]++;
200 ymax = (y0 < radius) ? y0 : radius;
201 for(yy=1; yy<=ymax; ++yy)
203 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
204 for(xx=0; xx<=xmax; ++xx)
206 hist[sa(xs, Diff2D(xx, -yy))]++;
225 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
237 for(x=1; x<w; ++x, ++xs.x, ++xd.x)
246 yy = (y1 < radius) ? y1 : radius;
250 xx = struct_function[yy]+1;
253 cur = sa(xs, Diff2D(-xx, yy));
256 if(cur < rankpos) leftsum--;
259 yy = (y0 < radius) ? y0 : radius;
263 xx = struct_function[yy]+1;
266 cur = sa(xs, Diff2D(-xx, -yy));
269 if(cur < rankpos) leftsum--;
274 yy = (y1 < radius) ? y1 : radius;
278 xx = struct_function[yy];
281 cur = sa(xs, Diff2D(xx, yy));
284 if(cur < rankpos) leftsum++;
287 yy = (y0 < radius) ? y0 : radius;
291 xx = struct_function[yy];
294 cur = sa(xs, Diff2D(xx, -yy));
297 if(cur < rankpos) leftsum++;
307 for(i=rankpos; i<256; i++)
316 for(i=rankpos-1; i>=0; i--)
319 if(leftsum == 0)
break;
326 if((
float)leftsum / winsize < rank)
329 for(i=rankpos; i<256; i++)
331 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
339 for(i=rankpos-1; i>=0; i--)
342 if((
float)leftsum / winsize < rank)
break;
353 template <
class SrcIterator,
class SrcAccessor,
354 class DestIterator,
class DestAccessor>
357 pair<DestIterator, DestAccessor> dest,
358 int radius,
float rank)
361 dest.first, dest.second,
405 doxygen_overloaded_function(template <...>
void discErosion)
407 template <
class SrcIterator,
class SrcAccessor,
408 class DestIterator,
class DestAccessor>
411 SrcIterator lowerright1, SrcAccessor sa,
412 DestIterator upperleft2, DestAccessor da,
415 vigra_precondition(radius >= 0,
"discErosion(): Radius must be >= 0.");
418 upperleft2, da, radius, 0.0);
421 template <
class SrcIterator,
class SrcAccessor,
422 class DestIterator,
class DestAccessor>
424 discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
425 pair<DestIterator, DestAccessor> dest,
428 vigra_precondition(radius >= 0,
"discErosion(): Radius must be >= 0.");
431 dest.first, dest.second,
475 doxygen_overloaded_function(template <...>
void discDilation)
477 template <
class SrcIterator,
class SrcAccessor,
478 class DestIterator,
class DestAccessor>
481 SrcIterator lowerright1, SrcAccessor sa,
482 DestIterator upperleft2, DestAccessor da,
485 vigra_precondition(radius >= 0,
"discDilation(): Radius must be >= 0.");
488 upperleft2, da, radius, 1.0);
491 template <
class SrcIterator,
class SrcAccessor,
492 class DestIterator,
class DestAccessor>
494 discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
495 pair<DestIterator, DestAccessor> dest,
498 vigra_precondition(radius >= 0,
"discDilation(): Radius must be >= 0.");
501 dest.first, dest.second,
545 doxygen_overloaded_function(template <...>
void discMedian)
547 template <
class SrcIterator,
class SrcAccessor,
548 class DestIterator,
class DestAccessor>
551 SrcIterator lowerright1, SrcAccessor sa,
552 DestIterator upperleft2, DestAccessor da,
555 vigra_precondition(radius >= 0,
"discMedian(): Radius must be >= 0.");
558 upperleft2, da, radius, 0.5);
561 template <
class SrcIterator,
class SrcAccessor,
562 class DestIterator,
class DestAccessor>
564 discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
565 pair<DestIterator, DestAccessor> dest,
568 vigra_precondition(radius >= 0,
"discMedian(): Radius must be >= 0.");
571 dest.first, dest.second,
673 template <
class SrcIterator,
class SrcAccessor,
674 class MaskIterator,
class MaskAccessor,
675 class DestIterator,
class DestAccessor>
678 SrcIterator lowerright1, SrcAccessor sa,
679 MaskIterator upperleftm, MaskAccessor mask,
680 DestIterator upperleft2, DestAccessor da,
681 int radius,
float rank)
683 vigra_precondition((rank >= 0.0) && (rank <= 1.0),
684 "discRankOrderFilter(): Rank must be between 0 and 1"
687 vigra_precondition(radius >= 0,
"discRankOrderFilter(): Radius must be >= 0.");
689 int i, x, y, xmax, ymax, xx, yy;
690 int rankpos, winsize, leftsum;
695 std::vector<int> struct_function(radius+1);
696 struct_function[0] = radius;
698 double r2 = (double)radius*radius;
699 for(i=1; i<=radius; ++i)
701 double r = (double) i - 0.5;
705 int w = lowerright1.x - upperleft1.x;
706 int h = lowerright1.y - upperleft1.y;
708 SrcIterator ys(upperleft1);
709 MaskIterator ym(upperleftm);
710 DestIterator yd(upperleft2);
712 for(y=0; y<h; ++y, ++ys.y, ++yd.y, ++ym.y)
725 for(i=0; i<256; ++i) hist[i] = 0;
731 ymax = (y1 < radius) ? y1 : radius;
732 for(yy=0; yy<=ymax; ++yy)
734 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
735 for(xx=0; xx<=xmax; ++xx)
746 ymax = (y0 < radius) ? y0 : radius;
747 for(yy=1; yy<=ymax; ++yy)
749 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
750 for(xx=0; xx<=xmax; ++xx)
776 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
790 for(x=1; x<w; ++x, ++xs.x, ++xd.x, ++xm.x)
799 yy = (y1 < radius) ? y1 : radius;
803 xx = struct_function[yy]+1;
812 if(cur < rankpos) leftsum--;
816 yy = (y0 < radius) ? y0 : radius;
820 xx = struct_function[yy]+1;
823 Diff2D pos(-xx, -yy);
829 if(cur < rankpos) leftsum--;
835 yy = (y1 < radius) ? y1 : radius;
839 xx = struct_function[yy];
848 if(cur < rankpos) leftsum++;
852 yy = (y0 < radius) ? y0 : radius;
856 xx = struct_function[yy];
865 if(cur < rankpos) leftsum++;
878 for(i=rankpos; i<256; i++)
887 for(i=rankpos-1; i>=0; i--)
890 if(leftsum == 0)
break;
897 if((
float)leftsum / winsize < rank)
900 for(i=rankpos; i<256; i++)
902 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
910 for(i=rankpos-1; i>=0; i--)
913 if((
float)leftsum / winsize < rank)
break;
930 template <
class SrcIterator,
class SrcAccessor,
931 class MaskIterator,
class MaskAccessor,
932 class DestIterator,
class DestAccessor>
935 pair<MaskIterator, MaskAccessor> mask,
936 pair<DestIterator, DestAccessor> dest,
937 int radius,
float rank)
940 mask.first, mask.second,
941 dest.first, dest.second,
992 template <
class SrcIterator,
class SrcAccessor,
993 class MaskIterator,
class MaskAccessor,
994 class DestIterator,
class DestAccessor>
997 SrcIterator lowerright1, SrcAccessor sa,
998 MaskIterator upperleftm, MaskAccessor mask,
999 DestIterator upperleft2, DestAccessor da,
1002 vigra_precondition(radius >= 0,
"discErosionWithMask(): Radius must be >= 0.");
1010 template <
class SrcIterator,
class SrcAccessor,
1011 class MaskIterator,
class MaskAccessor,
1012 class DestIterator,
class DestAccessor>
1015 pair<MaskIterator, MaskAccessor> mask,
1016 pair<DestIterator, DestAccessor> dest,
1019 vigra_precondition(radius >= 0,
"discErosionWithMask(): Radius must be >= 0.");
1022 mask.first, mask.second,
1023 dest.first, dest.second,
1074 template <
class SrcIterator,
class SrcAccessor,
1075 class MaskIterator,
class MaskAccessor,
1076 class DestIterator,
class DestAccessor>
1079 SrcIterator lowerright1, SrcAccessor sa,
1080 MaskIterator upperleftm, MaskAccessor mask,
1081 DestIterator upperleft2, DestAccessor da,
1084 vigra_precondition(radius >= 0,
"discDilationWithMask(): Radius must be >= 0.");
1092 template <
class SrcIterator,
class SrcAccessor,
1093 class MaskIterator,
class MaskAccessor,
1094 class DestIterator,
class DestAccessor>
1097 pair<MaskIterator, MaskAccessor> mask,
1098 pair<DestIterator, DestAccessor> dest,
1101 vigra_precondition(radius >= 0,
"discDilationWithMask(): Radius must be >= 0.");
1104 mask.first, mask.second,
1105 dest.first, dest.second,
1156 template <
class SrcIterator,
class SrcAccessor,
1157 class MaskIterator,
class MaskAccessor,
1158 class DestIterator,
class DestAccessor>
1161 SrcIterator lowerright1, SrcAccessor sa,
1162 MaskIterator upperleftm, MaskAccessor mask,
1163 DestIterator upperleft2, DestAccessor da,
1166 vigra_precondition(radius >= 0,
"discMedianWithMask(): Radius must be >= 0.");
1174 template <
class SrcIterator,
class SrcAccessor,
1175 class MaskIterator,
class MaskAccessor,
1176 class DestIterator,
class DestAccessor>
1179 pair<MaskIterator, MaskAccessor> mask,
1180 pair<DestIterator, DestAccessor> dest,
1183 vigra_precondition(radius >= 0,
"discMedianWithMask(): Radius must be >= 0.");
1186 mask.first, mask.second,
1187 dest.first, dest.second,
1195 #endif // VIGRA_FLATMORPHOLOGY_HXX