局部标准差实现对比度增强(ACE)
一、理论
图像增强算法的基本原则是“降低低频区域,突出高频区域”,以此强化边缘,达到增强的目的。最简单的例子就是通过原始图像减去高斯模糊处理后的图像,就能够将边缘强化出来。
直方图均衡化也是一种非常常见的增强方法。但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理。我们这里着重研究自适应对比度增强(ACE)的相关内容。
ACE的定义和原理看上去还是比较简单的。这里的
和
都可以根据图像本身计算出来。而
则需要单独计算。
可以为单独的常量,或者通过
来代替。这里的D是一个全局的值,比如平均值。
二、实现
涉及到局部的运算,自然而然会想到使用卷积的方法。更好的是Opencv提供了专门的函数用来做这个工作—BLUR
文档中写到:
那么正是我们想要的结果。
//ace 自适应对比度均衡研究 //by jsxyhelu //感谢 imageshop # include "stdafx.h" # include <iostream > # include "opencv2/core/core.hpp" # include "opencv2/highgui/highgui.hpp" # include "opencv2/imgproc/imgproc.hpp" using namespace std; using namespace cv; //点乘法 elementWiseMultiplication cv : :Mat EWM(cv : :Mat m1,cv : :Mat m2){ Mat dst =m1.mul(m2); return dst; } void main() { Mat src = imread( "hand.jpg", 0); Mat meanMask; Mat varMask; Mat meanGlobal; Mat varGlobal; Mat dst; Mat tmp; Mat tmp2; int C = 30; int D = 133; //全局均值和均方差 blur(src.clone(),meanGlobal,src.size()); varGlobal = src - meanGlobal; varGlobal = EWM(varGlobal,varGlobal); blur(src.clone(),meanMask,Size( 50, 50)); //meanMask为局部均值 tmp = src - meanMask; varMask = EWM(tmp,tmp); blur(varMask,varMask,Size( 50, 50)); //varMask为局部方差 dst = meanMask + C *tmp; imshow( "src",src); imshow( "dst",dst); waitKey(); }
接下来,为了实现
那么需要计算局部标准差和全局均值或方差
前面已经计算出了局部均值,那么
tmp = src - meanMask; varMask = EWM(tmp,tmp); blur(varMask,varMask,Size( 50, 50)); //varMask为局部方差 计算出局部方差 //换算成局部标准差 varMask.convertTo(varMask,CV_32F); for ( int i = 0;i <varMask.rows;i ++){ for ( int j = 0;j <varMask.cols;j ++){ varMask.at < float >(i,j) = ( float)sqrt(varMask.at < float >(i,j)); } }
换算成局部标准差
meanStdDev(src,meanGlobal,varGlobal); //meanGlobal为全局均值 varGlobal为全局标准差
是opencv提供的全局均值和标准差计算函数。
全部代码进行重构后如下
//ace 自适应对比度均衡研究 //by jsxyhelu //感谢 imageshop # include "stdafx.h" # include <iostream > # include "opencv2/core/core.hpp" # include "opencv2/highgui/highgui.hpp" # include "opencv2/imgproc/imgproc.hpp" using namespace std; using namespace cv; //点乘法 elementWiseMultiplication cv : :Mat EWM(cv : :Mat m1,cv : :Mat m2){ Mat dst =m1.mul(m2); return dst; } //图像局部对比度增强算法 cv : :Mat ACE(cv : :Mat src, int C = 4, int n = 20, int MaxCG = 5){ Mat meanMask; Mat varMask; Mat meanGlobal; Mat varGlobal; Mat dst; Mat tmp; Mat tmp2; blur(src.clone(),meanMask,Size( 50, 50)); //meanMask为局部均值 tmp = src - meanMask; varMask = EWM(tmp,tmp); blur(varMask,varMask,Size( 50, 50)); //varMask为局部方差 //换算成局部标准差 varMask.convertTo(varMask,CV_32F); for ( int i = 0;i <varMask.rows;i ++){ for ( int j = 0;j <varMask.cols;j ++){ varMask.at < float >(i,j) = ( float)sqrt(varMask.at < float >(i,j)); } } meanStdDev(src,meanGlobal,varGlobal); //meanGlobal为全局均值 varGlobal为全局标准差 tmp2 = varGlobal /varMask; for ( int i = 0;i <tmp2.rows;i ++){ for ( int j = 0;j <tmp2.cols;j ++){ if (tmp2.at < float >(i,j) >MaxCG){ tmp2.at < float >(i,j) = MaxCG; } } } tmp2.convertTo(tmp2,CV_8U); tmp2 = EWM(tmp2,tmp); dst = meanMask + tmp2; imshow( "D方法",dst); dst = meanMask + C *tmp; imshow( "C方法",dst); return dst; } void main() { Mat src = imread( "plant.bmp", 0); imshow( "src",src); ACE(src); waitKey(); }
三、小结
从结果上来看,ACE算法对于特定情况下的图片细节增强是显著的,但是并不是适用于所有的情况,并且其参数需要手工进行调整。了解它的特性,就能够解决一系列的问题,有效地增强现实。
分类:
传统算法
, GOCVHelper
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)