note
锚点灰度值 用 原图像对应点的原灰度值 和 局部均值加权得到
局部均值 由 掩膜 区域计算得到
权重 由 局部方差 与用户输入参数计算确定
code
// 局部均方差滤波
/*
\brief 局部均方差滤波
\param src:原矩阵,单通道
\param res:结果矩阵
\param size:掩膜矩形大小,长宽都是奇数
\param parameter:均值,方差权重因子
*/
void MyPartMeanVarianceFilter(Mat& src, Mat& res, Size& size, double parameter) {
if ((src.channels() > 1) || (res.channels() > 1)) {
return;
}
if ((size.width / 2 == 0) || (size.height / 2 == 0)) {
return;
}
if (parameter < 0) {
return;
}
int srcType = src.type();
src.copyTo(res);
src.convertTo(src, CV_64FC1);
res.convertTo(res, CV_64FC1);
int anchor_c = size.width / 2;
int anchor_r = size.height / 2;
for (int r = 0; r+size.height <= src.rows; r=r+1) {
for (int c = 0; c+size.width <= src.cols; c=c+1) {
Rect roi;
roi.x = c;
roi.y = r;
roi.width = size.width;
roi.height = size.height;
Mat tmp = src(roi);
Mat mean; // 均值
Mat sigma; // 标准差
meanStdDev(tmp, mean, sigma);
double fMean = mean.at<double>(0);
double fSigma = sigma.at<double>(0);
double fSigma2 = fSigma * fSigma; // 方差
double k = fSigma2 / (fSigma2 + parameter);
double origin = src.at<double>(r+anchor_r,c+anchor_c);
double out = (1 - k) * fMean + k * origin; // 锚点灰度值由原灰度值和局部均值加权得到
res.at<double>(r+anchor_r,c+anchor_c) = out;
// printf("origin:%lf, fMean:%lf, out:%lf\n", origin, fMean, out);
}
}
src.convertTo(src, srcType);
res.convertTo(res, srcType);
}