? ? ? ? 直方图统计算法可指定对比度差的局部区域进行相应的提升,来实现图像局部区域的图像增强目的。直方图统计是根据模板大小内的像素邻域的均值、方差与全局的均值、方差的比较,来决定像素的操作。操作暗亮区域的图像只需要设置局部均值和全局均值的比值,而局部方差一般设置成小于全局的方差。
????????使用直方图统计实现图像中的暗区域图像增强的具体步骤:
1、获得输入图像的平均灰度
????????其中ri指灰度级为i的像元数量,p(ri)则为灰度级为i对应在直方图内的概率,得到的mG就是全图的平均灰度值了。
2、获得输入图像的方差
3、判断一个区域在点(x,y)处的局部平均灰度mSxy,局部标准差为σSxy,我们取k0,k1,k2,E,当
?
?时,我们把当前点看做较暗的点,此时我们将该像素点乘以E达到增大其灰度值效果,实现暗区域亮化目的。
4、对于与此相反的亮区域暗化,在满足下列关系情况下,再乘以一个小于1的比例系数E。
且
????????根据上述步骤进行代码实现,并得到的试验结果如下:
/*function description:统计直方图实现图像增强
*
*input parameter:ImgTyp* srcImg 源图像
* int size 滤波器尺寸
* double k0,double k1,double k2 阈值参数
* double E 亮度改变倍数
* bool dark 亮、暗区域确认
*return:
* ImgTyp* 图像增强后的图像
******************************************************/
ImgTyp* HistogramFun::HistStatistic(ImgTyp* srcImg,int size,double k0,double k1,double k2,double E,bool dark)
{
if (srcImg == NULL)
{
cout<<"Error:影像为空值,读取失败"<<endl;
return NULL;
}
if (size%2 == 0)
{
cout<<"滤波器尺寸不为奇数,请修改。"<<endl;
return NULL;
}
double mean_g = 0,sigam_g = 0;
ImgTyp* copyImg = new ImgTyp[Width*Height];
memcpy(copyImg,srcImg,sizeof(ImgTyp)*Width*Height);
double* ImgGhist = CalImgHist(copyImg);
//求均值和方差
for (int l = 0; l < ColorLen; l++)
{
mean_g += l * ImgGhist[l];
}
for (int l = 0; l < ColorLen; l++)
{
sigam_g += pow((l - mean_g),2)*ImgGhist[l];
}
delete []ImgGhist;ImgGhist=NULL;
int len = size*size;
int localwidth = size/2;
//创建局部窗口
ImgTyp* Filter = new ImgTyp[len];
memset(Filter,0,sizeof(ImgTyp)*len);
//直方图
double* ImgHist = new double[ColorLen];
for (int i = localwidth;i < Height-localwidth;i++)
{
for (int j = localwidth;j < Width-localwidth;j++)
{
memset(ImgHist,0,sizeof(double)*ColorLen);
for (int n = -localwidth;n < localwidth;n++)
{
for (int m = -localwidth;m < localwidth;m++)
{
Filter[(n+localwidth)*size+m+localwidth] = copyImg[(i+n)*Width+m+j];//赋值
ImgHist[Filter[(n+localwidth)*size+m+localwidth]]++;//统计各个灰度级的数量
}
}
//求邻域的均值和方差
double mean_s = 0,sigam_s = 0;
for (int l = 0; l < ColorLen; l++)
{
ImgHist[l] = ImgHist[l] / len;//归一化求各个灰度级出现频率
mean_s += l * ImgHist[l];
}
for (int l = 0; l < ColorLen; l++)
{
sigam_s += pow((l - mean_s),2)*ImgHist[l];
}
if (dark)
{
if (E < 1)
{
cout<<"Error:暗区域操作,比例系数应大于1,不正确!"<<endl;
delete []Filter;Filter=NULL;
delete []ImgHist;ImgHist=NULL;
delete []copyImg;copyImg=NULL;
return NULL;
}
if ((mean_s <= mean_g*k0) && (sqrt(sigam_s) <= k2*sqrt(sigam_g)) && (sqrt(sigam_s) >= k1*sqrt(sigam_g)))
{
int target_value = E * copyImg[i*Width+j];
if (target_value > ColorLen-1)
{
target_value = ColorLen-1;
}
copyImg[i*Width+j] = target_value;
}
}
else
{
if (E > 1)
{
cout<<"Error:亮区域操作,比例系数应小于1,不正确!"<<endl;
delete []Filter;Filter=NULL;
delete []copyImg;copyImg=NULL;
delete []ImgHist;ImgHist=NULL;
return NULL;
}
if ((mean_s > mean_g*k0) && (sqrt(sigam_s) <= k2*sqrt(sigam_g)) && (sqrt(sigam_s) >= k1*sqrt(sigam_g)))
{
int target_value = E * copyImg[i*Width+j];
if (target_value > ColorLen-1)
{
target_value = ColorLen-1;
}
copyImg[i*Width+j] = target_value;
}
}
}
}
delete []Filter;Filter=NULL;
delete []ImgHist;ImgHist=NULL;
return copyImg;
}
得到的测试结果:
原图 | | 参数: 3,0.4,0.02,0.4,10,ture | | 参数: 7,0.4,0.02,0.4,10,ture | |
????????从上结果可见,基于直方图统计算法的图像处理,能够有效的增强图像局部特征细节信息。滤波器尺寸越小,得到到细节越明显,但需要的计算消耗越大。同时其中涉及的k0,k1,k2,E等参数都过于依赖经验,或者需要从大量的重复试验中获取。参数的设置不同,得到的结果也会存在区别。
|