MCPcopy Create free account
hub / github.com/PDAL/PDAL / progressiveFilter

Method progressiveFilter

filters/SMRFilter.cpp:669–733  ·  view source on GitHub ↗

Iteratively open the estimated surface. progressiveFilter can be used to identify both low points and object (i.e., non-ground) points, depending on the inputs.

Source from the content-addressed store, hash-verified

667// identify both low points and object (i.e., non-ground) points, depending on
668// the inputs.
669std::vector<int> SMRFilter::progressiveFilter(std::vector<double> const& ZImin,
670 double slope, double max_window)
671{
672 // "The maximum window radius is supplied as a distance metric (e.g., 21 m),
673 // but is internally converted to a pixel equivalent by dividing it by the
674 // cell size and rounding the result toward positive infinity (i.e., taking
675 // the ceiling value)."
676 int max_radius = static_cast<int>(std::ceil(max_window / m_args->m_cell));
677 std::vector<double> prevSurface = ZImin;
678 std::vector<double> erosion = ZImin;
679
680 // "...the radius of the element at each step [is] increased by one pixel
681 // from a starting value of one pixel to the pixel equivalent of the maximum
682 // value."
683 std::vector<int> Obj(m_rows * m_cols, 0);
684 for (int radius = 1; radius <= max_radius; ++radius)
685 {
686 // "On the first iteration, the minimum surface (ZImin) is opened using
687 // a disk-shaped structuring element with a radius of one pixel."
688 math::erodeDiamond(erosion, m_rows, m_cols, 1);
689 std::vector<double> curOpening = erosion;
690 math::dilateDiamond(curOpening, m_rows, m_cols, radius);
691
692 // "An elevation threshold is then calculated, where the value is equal
693 // to the supplied slope tolerance parameter multiplied by the product
694 // of the window radius and the cell size."
695 double threshold = slope * m_args->m_cell * radius;
696
697 // "This elevation threshold is applied to the difference of the minimum
698 // and the opened surfaces."
699
700 // Need to provide means of diffing two vectors.
701 std::vector<double> diff;
702 std::transform(prevSurface.begin(), prevSurface.end(),
703 curOpening.begin(), std::back_inserter(diff),
704 [&](double l, double r) { return std::fabs(l - r); });
705
706 // "Any grid cell with a difference value exceeding the calculated
707 // elevation threshold for the iteration is then flagged as an OBJ
708 // cell."
709 std::vector<int> foo;
710 std::transform(diff.begin(), diff.end(), std::back_inserter(foo),
711 [threshold](double x) {
712 return (x > threshold) ? int(1) : int(0);
713 });
714 std::transform(Obj.begin(), Obj.end(), foo.begin(), Obj.begin(),
715 [](int a, int b) { return (std::max)(a, b); });
716
717 // "The algorithm then proceeds to the next window radius (up to the
718 // maximum), and proceeds as above with the last opened surface acting
719 // as the minimum surface for the next difference calculation."
720 prevSurface = curOpening;
721
722 size_t ng = std::count(Obj.begin(), Obj.end(), 1);
723 size_t g(Obj.size() - ng);
724 double p(100.0 * double(ng) / double(Obj.size()));
725 log()->floatPrecision(2);
726 log()->get(LogLevel::Debug) << "progressiveFilter: radius = " << radius

Callers

nothing calls this directly

Calls 11

ceilFunction · 0.85
erodeDiamondFunction · 0.85
dilateDiamondFunction · 0.85
transformFunction · 0.85
floatPrecisionMethod · 0.80
countFunction · 0.70
logFunction · 0.50
beginMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected