37#ifndef VIGRA_FLATMORPHOLOGY_HXX
38#define VIGRA_FLATMORPHOLOGY_HXX
43#include "multi_shape.hxx"
155template <
class SrcIterator,
class SrcAccessor,
156 class DestIterator,
class DestAccessor>
159 SrcIterator lowerright1, SrcAccessor sa,
160 DestIterator upperleft2, DestAccessor da,
161 int radius,
float rank)
163 vigra_precondition((rank >= 0.0) && (rank <= 1.0),
164 "discRankOrderFilter(): Rank must be between 0 and 1"
167 vigra_precondition(radius >= 0,
168 "discRankOrderFilter(): Radius must be >= 0.");
170 int i, x, y, xmax, ymax, xx, yy;
171 int rankpos, winsize, leftsum;
176 std::vector<int> struct_function(radius+1);
177 struct_function[0] = radius;
179 double r2 = (double)radius*radius;
180 for(i=1; i<=radius; ++i)
182 double r = (double) i - 0.5;
183 struct_function[i] = (int)(VIGRA_CSTD::sqrt(r2 - r*r) + 0.5);
186 int w = lowerright1.x - upperleft1.x;
187 int h = lowerright1.y - upperleft1.y;
189 SrcIterator ys(upperleft1);
190 DestIterator yd(upperleft2);
192 for(y=0; y<h; ++y, ++ys.y, ++yd.y)
204 for(i=0; i<256; ++i) hist[i] = 0;
208 ymax = (y1 < radius) ? y1 : radius;
209 for(yy=0; yy<=ymax; ++yy)
211 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
212 for(xx=0; xx<=xmax; ++xx)
214 hist[sa(xs,
Diff2D(xx, yy))]++;
219 ymax = (y0 < radius) ? y0 : radius;
220 for(yy=1; yy<=ymax; ++yy)
222 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
223 for(xx=0; xx<=xmax; ++xx)
225 hist[sa(xs,
Diff2D(xx, -yy))]++;
244 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
256 for(x=1; x<w; ++x, ++xs.x, ++xd.x)
265 yy = (y1 < radius) ? y1 : radius;
269 xx = struct_function[yy]+1;
272 cur = sa(xs,
Diff2D(-xx, yy));
275 if(cur < rankpos) leftsum--;
278 yy = (y0 < radius) ? y0 : radius;
282 xx = struct_function[yy]+1;
285 cur = sa(xs,
Diff2D(-xx, -yy));
288 if(cur < rankpos) leftsum--;
293 yy = (y1 < radius) ? y1 : radius;
297 xx = struct_function[yy];
300 cur = sa(xs,
Diff2D(xx, yy));
303 if(cur < rankpos) leftsum++;
306 yy = (y0 < radius) ? y0 : radius;
310 xx = struct_function[yy];
313 cur = sa(xs,
Diff2D(xx, -yy));
316 if(cur < rankpos) leftsum++;
326 for(i=rankpos; i<256; i++)
335 for(i=rankpos-1; i>=0; i--)
338 if(leftsum == 0)
break;
345 if((
float)leftsum / winsize < rank)
348 for(i=rankpos; i<256; i++)
350 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
358 for(i=rankpos-1; i>=0; i--)
361 if((
float)leftsum / winsize < rank)
break;
372template <
class SrcIterator,
class SrcAccessor,
373 class DestIterator,
class DestAccessor>
376 pair<DestIterator, DestAccessor> dest,
377 int radius,
float rank)
380 dest.first, dest.second,
384template <
class T1,
class S1,
389 int radius,
float rank)
391 vigra_precondition(src.shape() == dest.shape(),
392 "discRankOrderFilter(): shape mismatch between input and output.");
451template <
class SrcIterator,
class SrcAccessor,
452 class DestIterator,
class DestAccessor>
455 SrcIterator lowerright1, SrcAccessor sa,
456 DestIterator upperleft2, DestAccessor da,
459 vigra_precondition(radius >= 0,
"discErosion(): Radius must be >= 0.");
462 upperleft2, da, radius, 0.0);
465template <
class SrcIterator,
class SrcAccessor,
466 class DestIterator,
class DestAccessor>
468discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
469 pair<DestIterator, DestAccessor> dest,
472 vigra_precondition(radius >= 0,
"discErosion(): Radius must be >= 0.");
475 dest.first, dest.second,
479template <
class T1,
class S1,
486 vigra_precondition(src.shape() == dest.shape(),
487 "discErosion(): shape mismatch between input and output.");
488 discErosion(srcImageRange(src), destImage(dest), radius);
544template <
class SrcIterator,
class SrcAccessor,
545 class DestIterator,
class DestAccessor>
548 SrcIterator lowerright1, SrcAccessor sa,
549 DestIterator upperleft2, DestAccessor da,
552 vigra_precondition(radius >= 0,
"discDilation(): Radius must be >= 0.");
555 upperleft2, da, radius, 1.0);
558template <
class SrcIterator,
class SrcAccessor,
559 class DestIterator,
class DestAccessor>
561discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
562 pair<DestIterator, DestAccessor> dest,
565 vigra_precondition(radius >= 0,
"discDilation(): Radius must be >= 0.");
568 dest.first, dest.second,
572template <
class T1,
class S1,
579 vigra_precondition(src.shape() == dest.shape(),
580 "discDilation(): shape mismatch between input and output.");
581 discDilation(srcImageRange(src), destImage(dest), radius);
637template <
class SrcIterator,
class SrcAccessor,
638 class DestIterator,
class DestAccessor>
641 SrcIterator lowerright1, SrcAccessor sa,
642 DestIterator upperleft2, DestAccessor da,
645 vigra_precondition(radius >= 0,
"discMedian(): Radius must be >= 0.");
648 upperleft2, da, radius, 0.5);
651template <
class SrcIterator,
class SrcAccessor,
652 class DestIterator,
class DestAccessor>
654discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
655 pair<DestIterator, DestAccessor> dest,
658 vigra_precondition(radius >= 0,
"discMedian(): Radius must be >= 0.");
661 dest.first, dest.second,
665template <
class T1,
class S1,
672 vigra_precondition(src.shape() == dest.shape(),
673 "discMedian(): shape mismatch between input and output.");
674 discMedian(srcImageRange(src), destImage(dest), radius);
796template <
class SrcIterator,
class SrcAccessor,
797 class MaskIterator,
class MaskAccessor,
798 class DestIterator,
class DestAccessor>
801 SrcIterator lowerright1, SrcAccessor sa,
802 MaskIterator upperleftm, MaskAccessor mask,
803 DestIterator upperleft2, DestAccessor da,
804 int radius,
float rank)
806 vigra_precondition((rank >= 0.0) && (rank <= 1.0),
807 "discRankOrderFilter(): Rank must be between 0 and 1"
810 vigra_precondition(radius >= 0,
"discRankOrderFilter(): Radius must be >= 0.");
812 int i, x, y, xmax, ymax, xx, yy;
813 int rankpos, winsize, leftsum;
818 std::vector<int> struct_function(radius+1);
819 struct_function[0] = radius;
821 double r2 = (double)radius*radius;
822 for(i=1; i<=radius; ++i)
824 double r = (double) i - 0.5;
825 struct_function[i] = (int)(VIGRA_CSTD::sqrt(r2 - r*r) + 0.5);
828 int w = lowerright1.x - upperleft1.x;
829 int h = lowerright1.y - upperleft1.y;
831 SrcIterator ys(upperleft1);
832 MaskIterator ym(upperleftm);
833 DestIterator yd(upperleft2);
835 for(y=0; y<h; ++y, ++ys.y, ++yd.y, ++ym.y)
848 for(i=0; i<256; ++i) hist[i] = 0;
854 ymax = (y1 < radius) ? y1 : radius;
855 for(yy=0; yy<=ymax; ++yy)
857 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
858 for(xx=0; xx<=xmax; ++xx)
869 ymax = (y0 < radius) ? y0 : radius;
870 for(yy=1; yy<=ymax; ++yy)
872 xmax = (x1 < struct_function[yy]) ? x1 : struct_function[yy];
873 for(xx=0; xx<=xmax; ++xx)
899 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
913 for(x=1; x<w; ++x, ++xs.x, ++xd.x, ++xm.x)
922 yy = (y1 < radius) ? y1 : radius;
926 xx = struct_function[yy]+1;
935 if(cur < rankpos) leftsum--;
939 yy = (y0 < radius) ? y0 : radius;
943 xx = struct_function[yy]+1;
952 if(cur < rankpos) leftsum--;
958 yy = (y1 < radius) ? y1 : radius;
962 xx = struct_function[yy];
971 if(cur < rankpos) leftsum++;
975 yy = (y0 < radius) ? y0 : radius;
979 xx = struct_function[yy];
988 if(cur < rankpos) leftsum++;
1001 for(i=rankpos; i<256; i++)
1010 for(i=rankpos-1; i>=0; i--)
1013 if(leftsum == 0)
break;
1020 if((
float)leftsum / winsize < rank)
1023 for(i=rankpos; i<256; i++)
1025 if((
float)(hist[i]+leftsum) / winsize >= rank)
break;
1033 for(i=rankpos-1; i>=0; i--)
1036 if((
float)leftsum / winsize < rank)
break;
1042 da.set(rankpos, xd);
1053template <
class SrcIterator,
class SrcAccessor,
1054 class MaskIterator,
class MaskAccessor,
1055 class DestIterator,
class DestAccessor>
1058 pair<MaskIterator, MaskAccessor> mask,
1059 pair<DestIterator, DestAccessor> dest,
1060 int radius,
float rank)
1063 mask.first, mask.second,
1064 dest.first, dest.second,
1068template <
class T1,
class S1,
1075 int radius,
float rank)
1077 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1078 "discRankOrderFilterWithMask(): shape mismatch between input and output.");
1145template <
class SrcIterator,
class SrcAccessor,
1146 class MaskIterator,
class MaskAccessor,
1147 class DestIterator,
class DestAccessor>
1150 SrcIterator lowerright1, SrcAccessor sa,
1151 MaskIterator upperleftm, MaskAccessor mask,
1152 DestIterator upperleft2, DestAccessor da,
1155 vigra_precondition(radius >= 0,
"discErosionWithMask(): Radius must be >= 0.");
1163template <
class SrcIterator,
class SrcAccessor,
1164 class MaskIterator,
class MaskAccessor,
1165 class DestIterator,
class DestAccessor>
1168 pair<MaskIterator, MaskAccessor> mask,
1169 pair<DestIterator, DestAccessor> dest,
1172 vigra_precondition(radius >= 0,
"discErosionWithMask(): Radius must be >= 0.");
1175 mask.first, mask.second,
1176 dest.first, dest.second,
1180template <
class T1,
class S1,
1189 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1190 "discErosionWithMask(): shape mismatch between input and output.");
1254template <
class SrcIterator,
class SrcAccessor,
1255 class MaskIterator,
class MaskAccessor,
1256 class DestIterator,
class DestAccessor>
1259 SrcIterator lowerright1, SrcAccessor sa,
1260 MaskIterator upperleftm, MaskAccessor mask,
1261 DestIterator upperleft2, DestAccessor da,
1264 vigra_precondition(radius >= 0,
"discDilationWithMask(): Radius must be >= 0.");
1272template <
class SrcIterator,
class SrcAccessor,
1273 class MaskIterator,
class MaskAccessor,
1274 class DestIterator,
class DestAccessor>
1277 pair<MaskIterator, MaskAccessor> mask,
1278 pair<DestIterator, DestAccessor> dest,
1281 vigra_precondition(radius >= 0,
"discDilationWithMask(): Radius must be >= 0.");
1284 mask.first, mask.second,
1285 dest.first, dest.second,
1289template <
class T1,
class S1,
1298 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1299 "discDilationWithMask(): shape mismatch between input and output.");
1363template <
class SrcIterator,
class SrcAccessor,
1364 class MaskIterator,
class MaskAccessor,
1365 class DestIterator,
class DestAccessor>
1368 SrcIterator lowerright1, SrcAccessor sa,
1369 MaskIterator upperleftm, MaskAccessor mask,
1370 DestIterator upperleft2, DestAccessor da,
1373 vigra_precondition(radius >= 0,
"discMedianWithMask(): Radius must be >= 0.");
1381template <
class SrcIterator,
class SrcAccessor,
1382 class MaskIterator,
class MaskAccessor,
1383 class DestIterator,
class DestAccessor>
1386 pair<MaskIterator, MaskAccessor> mask,
1387 pair<DestIterator, DestAccessor> dest,
1390 vigra_precondition(radius >= 0,
"discMedianWithMask(): Radius must be >= 0.");
1393 mask.first, mask.second,
1394 dest.first, dest.second,
1398template <
class T1,
class S1,
1407 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1408 "discMedianWithMask(): shape mismatch between input and output.");
Two dimensional difference vector.
Definition diff2d.hxx:186
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
void discMedian(...)
Apply median filter with disc of given radius to image.
void discMedianWithMask(...)
Apply median filter with disc of given radius to image using a mask.
void discRankOrderFilterWithMask(...)
Apply rank order filter with disc structuring function to the image using a mask.
void discErosionWithMask(...)
Apply erosion (minimum) filter with disc of given radius to image using a mask.
void discRankOrderFilter(...)
Apply rank order filter with disc structuring function to the image.
void discErosion(...)
Apply erosion (minimum) filter with disc of given radius to image.
void discDilationWithMask(...)
Apply dilation (maximum) filter with disc of given radius to image using a mask.
void discDilation(...)
Apply dilation (maximum) filter with disc of given radius to image.