该方法的基本思想是将图像分成两部分:低频和高频两部分,增强高频部分,再合成。达到锐度增强的效果。一般在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通道低频部分和高频部分(为了可视化,高频幅值被放大了)分别如下:
但是存在一个问题,因为噪声也属于高频,所以噪声也会被增强,所以效果看上去并不是很好,所以再加上一个时域去燥,去除高频噪声。这个是改进的地方。效果:增强前后对比如下: