37 #ifndef VIGRA_FLATMORPHOLOGY_HXX
38 #define VIGRA_FLATMORPHOLOGY_HXX
43 #include "multi_shape.hxx"
155 template <
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;
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;
372 template <
class SrcIterator,
class SrcAccessor,
373 class DestIterator,
class DestAccessor>
376 pair<DestIterator, DestAccessor> dest,
377 int radius,
float rank)
380 dest.first, dest.second,
384 template <
class T1,
class S1,
388 MultiArrayView<2, T2, S2> dest,
389 int radius,
float rank)
391 vigra_precondition(src.shape() == dest.shape(),
392 "discRankOrderFilter(): shape mismatch between input and output.");
451 template <
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);
465 template <
class SrcIterator,
class SrcAccessor,
466 class DestIterator,
class DestAccessor>
468 discErosion(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,
479 template <
class T1,
class S1,
483 MultiArrayView<2, T2, S2> dest,
486 vigra_precondition(src.shape() == dest.shape(),
487 "discErosion(): shape mismatch between input and output.");
488 discErosion(srcImageRange(src), destImage(dest), radius);
544 template <
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);
558 template <
class SrcIterator,
class SrcAccessor,
559 class DestIterator,
class DestAccessor>
561 discDilation(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,
572 template <
class T1,
class S1,
576 MultiArrayView<2, T2, S2> dest,
579 vigra_precondition(src.shape() == dest.shape(),
580 "discDilation(): shape mismatch between input and output.");
581 discDilation(srcImageRange(src), destImage(dest), radius);
637 template <
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);
651 template <
class SrcIterator,
class SrcAccessor,
652 class DestIterator,
class DestAccessor>
654 discMedian(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,
665 template <
class T1,
class S1,
668 discMedian(MultiArrayView<2, T1, S1>
const & src,
669 MultiArrayView<2, T2, S2> dest,
672 vigra_precondition(src.shape() == dest.shape(),
673 "discMedian(): shape mismatch between input and output.");
674 discMedian(srcImageRange(src), destImage(dest), radius);
796 template <
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;
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;
946 Diff2D pos(-xx, -yy);
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);
1053 template <
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,
1068 template <
class T1,
class S1,
1073 MultiArrayView<2, TM, SM>
const & mask,
1074 MultiArrayView<2, T2, S2> dest,
1075 int radius,
float rank)
1077 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1078 "discRankOrderFilterWithMask(): shape mismatch between input and output.");
1145 template <
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.");
1163 template <
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,
1180 template <
class T1,
class S1,
1185 MultiArrayView<2, TM, SM>
const & mask,
1186 MultiArrayView<2, T2, S2> dest,
1189 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1190 "discErosionWithMask(): shape mismatch between input and output.");
1254 template <
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.");
1272 template <
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,
1289 template <
class T1,
class S1,
1294 MultiArrayView<2, TM, SM>
const & mask,
1295 MultiArrayView<2, T2, S2> dest,
1298 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1299 "discDilationWithMask(): shape mismatch between input and output.");
1363 template <
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.");
1381 template <
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,
1398 template <
class T1,
class S1,
1403 MultiArrayView<2, TM, SM>
const & mask,
1404 MultiArrayView<2, T2, S2> dest,
1407 vigra_precondition(src.shape() == mask.shape() && src.shape() == dest.shape(),
1408 "discMedianWithMask(): shape mismatch between input and output.");
1416 #endif // VIGRA_FLATMORPHOLOGY_HXX
void discDilationWithMask(...)
Apply dilation (maximum) 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 discErosionWithMask(...)
Apply erosion (minimum) 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 discErosion(...)
Apply erosion (minimum) filter with disc of given radius to image.
void discDilation(...)
Apply dilation (maximum) filter with disc of given radius to image.
void discMedian(...)
Apply median filter with disc of given radius to image.
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void discMedianWithMask(...)
Apply median filter with disc of given radius to image using a mask.
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616