inline cv::Mat_ maskedMedianBlur()

in source/util/CvUtil.h [335:384]


inline cv::Mat_<float> maskedMedianBlur(
    const cv::Mat_<float>& mat,
    const cv::Mat_<float>& background,
    const cv::Mat_<bool>& mask,
    const int radius,
    const bool ignoreNan = true) {
  cv::Mat_<float> blurred(mat.size(), 0.0);
  for (int y = 0; y < mat.rows; ++y) {
    for (int x = 0; x < mat.cols; ++x) {
      std::vector<float> values;
      if (!mask(y, x)) {
        if (!background.empty()) {
          blurred(y, x) = background(y, x);
        }
        continue;
      }
      for (int yy = y - radius; yy <= y + radius; ++yy) {
        for (int xx = x - radius; xx <= x + radius; ++xx) {
          // Ignore out of bounds
          if (0 > yy || yy >= mat.rows || 0 > xx || xx >= mat.cols) {
            continue;
          }

          // Ignore outside mask
          if (!mask(yy, xx)) {
            continue;
          }

          // Ignore NAN values if specified to do so
          if (ignoreNan && (std::isnan(mat(yy, xx)) || mat(yy, xx) == 0)) {
            continue;
          }

          values.push_back(mat(yy, xx));
        }
      }

      if (values.size() != 0) {
        const size_t n = values.size() / 2;
        std::partial_sort(values.begin(), values.begin() + n + 1, values.end());
        if (values.size() % 2 == 1) {
          blurred(y, x) = values[n];
        } else {
          blurred(y, x) = (values[n - 1] + values[n]) / 2.0;
        }
      }
    }
  }
  return blurred;
}