转载

[blogs 算法原理 ]局部标准差实现对比度增强

基于“局部标准差”的图像增强(原理、算法、代码)

一、理论

图像增强算法的基本原则是“降低低频区域,突出高频区域”,以此强化边缘,达到增强的目的。最简单的例子就是通过原始图像减去高斯模糊处理后的图像,就能够将边缘强化出来。

直方图均衡化也是一种非常常见的增强方法。但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理。我们这里着重研究自适应对比度增强(ACE)的相关内容。

ACE的定义和原理(TODO)

ACE算法的相关内容:

计算低频成分:

     [blogs 算法原理 ]局部标准差实现对比度增强

对于具体的像素,一般可以通过计算以该像素为中心的局部区域的像素平均值来实现。

而局部方差为:

[blogs 算法原理 ]局部标准差实现对比度增强

则ACE算法可以表示为:

[blogs 算法原理 ]局部标准差实现对比度增强

看上去还是比较简单的。这里的 [blogs 算法原理 ]局部标准差实现对比度增强[blogs 算法原理 ]局部标准差实现对比度增强 都可以根据图像本身计算出来。而 [blogs 算法原理 ]局部标准差实现对比度增强 则需要单独计算。

[blogs 算法原理 ]局部标准差实现对比度增强 可以为单独的常量,或者通过 [blogs 算法原理 ]局部标准差实现对比度增强 来代替。这里的D是一个全局的值,比如平均值。

二、实现

涉及到局部的运算,自然而然会想到使用卷积的方法。更好的是Opencv提供了专门的函数用来做这个工作—BLUR

文档中写到:

[blogs 算法原理 ]局部标准差实现对比度增强

那么正是我们想要的结果。

[blogs 算法原理 ]局部标准差实现对比度增强

[blogs 算法原理 ]局部标准差实现对比度增强

[blogs 算法原理 ]局部标准差实现对比度增强

//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 = 30 ;

int = 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();

}

接下来,为了实现 [blogs 算法原理 ]局部标准差实现对比度增强 那么需要计算局部标准差和全局均值或方差

前面已经计算出了局部均值,那么

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 = 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();

}

[blogs 算法原理 ]局部标准差实现对比度增强

三、小结

从结果上来看,ACE算法对于特定情况下的图片细节增强是显著的,但是并不是适用于所有的情况,并且其参数需要手工进行调整。了解它的特性,就能够解决一系列的问题,有效地增强现实。

来自为知笔记(Wiz)

正文到此结束
Loading...