网上不乏直方图均衡化代码,但是没用一个是自己编写的,都是利用了各种各样的库去写。
我现在就想分享一些自己的作业代码和对直方图均衡化的理解。
我尽量用最通俗的语言最简单的代码去让各位能理解直方图均衡化的原理。
直方图均衡化数学原理
根据图示关系去寻找映射
//声明所需要的数组
int a[256]={0};
float b[256]={0.0},c[256]={0.0},d[256]={0.0},balanceEnd[256]={0.0};
单个分布率
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
int pix;
pix=int(src.at<uchar>(i,j));
a[pix]+=1;
}
}
累计分布率
for(int i=0;i<=255;i++){
b[i]=(float(a[i])/(src.cols*src.rows));
for(int j=0;j<=i;j++){
c[i]=b[j]+c[i];
}
}
扩展
for(int i=0;i<=255;i++){
d[i]=255*c[i];
balanceEnd[i]=int(d[i]+0.5);
}
sml映射
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
int pix=0;
pix=src.at<uchar>(i,j);
out.at<uchar>(i,j)=uchar(balanceEnd[pix]);
}
}
此时就已经完成了对单通道图像的均衡化
代码
void histogramEqualization(Mat src,Mat &out,int x=1){
x=src.channels();
out=src.clone();
int a[256]={0};
float b[256]={0.0},c[256]={0.0},d[256]={0.0},balanceEnd[256]={0.0};
Mat mergeImage,channelsSrc[3];//blue green red
switch (x) {
case 1:
//直方图均衡化
//单个分部率
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
int pix;
pix=int(src.at<uchar>(i,j));
a[pix]+=1;
}
}
//累计分布率
for(int i=0;i<=255;i++){
b[i]=(float(a[i])/(src.cols*src.rows));
for(int j=0;j<=i;j++){
c[i]=b[j]+c[i];
}
}
//扩展
for(int i=0;i<=255;i++){
d[i]=255*c[i];
balanceEnd[i]=int(d[i]+0.5);
}
//映射
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
int pix=0;
pix=src.at<uchar>(i,j);
out.at<uchar>(i,j)=uchar(balanceEnd[pix]);
}
}
break;
case 3:
//分离图像
split(src,channelsSrc);
histogramEqualization(channelsSrc[0],channelsSrc[0]);
histogramEqualization(channelsSrc[1],channelsSrc[1]);
histogramEqualization(channelsSrc[2],channelsSrc[2]);
//合拼图像
merge(channelsSrc,3,out);
break;
}
}