关于直方图均衡化,教材大都讲解的是8bit灰度图的直方图均衡化,什么是直方图均衡化,我没有完全理解,以后若能有通俗易懂的理解,我会贴上来,我的大概理解是:
1、累计函数即概率密度函数面积的相等导致的映射函数。
2、因为上述完成的映射后灰度的变化范围只是在[0,N],N为灰度图有效像素数目,所以得进行线性拉伸255/N。
具体代码:
void RmwHistogramEqualize(BYTE *pimg,int width,int height)
{//直方图均衡化
BYTE *pcur,*pend=pimg+width*height;
unsigned int hist[256];
int LUT[256],i,sum;
memset(hist,0,sizeof(int)*256);
// memset(LUT,0,sizeof(int)*256);
for(pcur=pimg;pcur<pend;)//这步其实也是直方图求解
hist[*(pcur++)]++;
for(sum=hist[0],LUT[0]=0,i=0;i<256;i++)
{
sum=sum+hist[i];
LUT[i]=255*sum/(width*height);
}
for(pcur=pimg;pcur<pend;)
*(pcur++)=LUT[*pcur];
}
这是我上课的老师写的,他是图像处理领域的大牛级人物。
所以8bit灰度图的直方图均衡化利用这几行代码就能完成,简单。一下是效果图:
这两张,分别是均衡化前后的对比,可以看出,确实直方图均衡化以后,图片的对比度更加大,即人物更清晰了。
今天要讨论的是24位彩色bmp图片的均衡化,首先看一下效果图:
这辆图片,依次是均衡化前和均衡化以后的、
具体的操作方法,其实很简单,就是讲RGB分布放入一个数组,对R数组、G数组和R数组分别均衡化,然后在一次写入图片即可。对于,这种方法的正确性,我没去证实,只是看了一篇档次比较低的文献后,今晚进行的实验,从实验效果来看,处理过的图片的前景确实变淡了,人物也更加突出了。Good Luck!
#include"fun.h"
#include<iostream.h>
void main()
{
BYTE *pimg,*p1,*p2,*p3;
int width,height;
pimg=RmwReadImg24("lena.bmp",&width,&height);//将图片像素数据读出来的函数
p1=new BYTE[width*height];
p2=new BYTE[width*height];
p3=new BYTE[width*height];
BYTE *pp1=p1;
BYTE *pp2=p2;
BYTE *pp3=p3;
for(int i=0;i<width*height*3;i++)//分布将RGB放入对应的数组
if(i%3==0)
*(pp1++)=*(pimg+i);
else if(i%3==1)
*(pp2++)=*(pimg+i);
else
*(pp3++)=*(pimg+i);
RmwHistogramEqualize(p1,width,height);//8bit灰度图片的均衡化操作
RmwHistogramEqualize(p2,width,height);
RmwHistogramEqualize(p3,width,height);
// RmwWriteImage(p1,width,height,"p1.bmp");
// RmwWriteImage(p2,width,height,"p2.bmp");
// RmwWriteImage(p3,width,height,"p3.bmp");
int j=0;
for(j=0;j<width*height*3;j++)//将RGB三个均衡化以后的数组在拼在一起
if(j%3==0)
*(pimg+j)=*(p1++);
else if(j%3==1)
*(pimg+j)=*(p2++);
else
*(pimg+j)=*(p3++);
RmwWriteImage24(pimg,width,height,"lenaEqu.bmp");//将像素数据写入图片文件函数
}