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;
}