该方法的基本思想是将图像分成两部分:低频和高频两部分,增强高频部分,再合成。达到锐度增强的效果。一般在Y通道进行。
局部低频部分:lowFre = blur(srcY, r)//局部滤波
局部高频部分:highFre = srcY - lowFre
局部标准差: localStd^2 = blur(highFre*highFre, r)
全局均值和标准差:Gmean
自适应高频增强因子:c = a * Gmean / localStd,其中a =[0,1]
计算低频和高频的合成:srcY' = lowFre + c * highFre
最后转换并合成三通道
程序如下:
bool adaptContrastEnhancement(Mat& src, Mat& dst, int r, int maxCg)
{
if (!src.data) //判断图像是否被正确读取;
{
cerr << "自适应对比度增强函数读入图片有误";
return false;
}
//Mat ycc; //转换空间到YCrCb;
//cvtColor(scr, ycc, COLOR_RGB2YCrCb);
//vector<Mat> channels(3); //分离通道;
//split(ycc, channels);
Mat localMeansMatrix(src.rows, src.cols, CV_8UC1);
Mat localVarianceMatrix(src.rows, src.cols, CV_8UC1);
Mat highFre(src.rows, src.cols, CV_8UC1);
//Mat highFreMul(src.rows, src.cols, CV_8UC1, Scalar::all(10));
boxFilter(src, localMeansMatrix, CV_8UC1, Size(r, r));//low fre
highFre = src - localMeansMatrix;//heigh fre
//highFre = highFre.mul(highFreMul);
imshow("low fre", localMeansMatrix);
imshow("high fre", highFre);
//imshow("blur high fre", highFre);
localVarianceMatrix = highFre.mul(highFre);
localMeansMatrix.convertTo(localMeansMatrix, CV_32F);
localVarianceMatrix.convertTo(localVarianceMatrix, CV_32F);
boxFilter(localVarianceMatrix, localVarianceMatrix, CV_32FC1, Size(r, r));// var , e((r-e(r))*(r-e(r)))
for (int i = 0; i < localVarianceMatrix.rows; i++)
{
for (int j = 0; j < localVarianceMatrix.cols; j++)
{
localVarianceMatrix.at<float>(i, j) = (float)sqrt(localVarianceMatrix.at<float>(i, j));//std
}
}
Mat temp = src.clone();
Scalar mean;
Scalar dev;
meanStdDev(temp, mean, dev);//global mean std
float meansGlobal = mean.val[0];
Mat enhanceMatrix(src.rows, src.cols, CV_8UC1);
for (int i = 0; i < src.rows; i++) //遍历,对每个点进行自适应调节
{
for (int j = 0; j < src.cols; j++)
{
if (localVarianceMatrix.at<float>(i, j) >= 0.01)
{
float cg = 0.5 * meansGlobal / localVarianceMatrix.at<float>(i, j);//0.5
float cgs = cg > maxCg ? maxCg : cg;
cgs = cgs < 1 ? 1 : cgs;
int e = localMeansMatrix.at<float>(i, j) + cgs * (temp.at<uchar>(i, j) - localMeansMatrix.at<float>(i, j));
if (e > 255)
{
e = 255;
}
else if (e < 0)
{
e = 0;
}
enhanceMatrix.at<uchar>(i, j) = e;
}
else
{
enhanceMatrix.at<uchar>(i, j) = temp.at<uchar>(i, j);
}
}
}
dst = enhanceMatrix;
}
Y通道低频部分和高频部分(为了可视化,高频幅值被放大了)分别如下:
但是存在一个问题,因为噪声也属于高频,所以噪声也会被增强,所以效果看上去并不是很好,所以再加上一个时域去燥,去除高频噪声。这个是改进的地方。效果:增强前后对比如下: