最近在学习数字图像处理,自己对一些算法做了总结,方便以后查阅。
直方图均衡化的处理流程
其中n表示所有像素点的个数,nj表示灰度值为j的像素的个数。Sk为得到的新的灰度级。(原来为0的灰度和L-1的灰度映射完是不会改变的。)
结果对比
均衡化后的直方图分布一般都不是均匀的,从上图可以看出均衡化的图像有明显的增强,骨骼的结构更加的清晰,自己写的函数,没有自带的函数效果好,我觉得可能是灰度值为小数的时候,我直接强制类型转化成int型,这中间可能存在一定问题。总体来说,直方图均衡化对于背景和前景都太亮或者太暗的图像非常有用。
核心代码
Mat HistogramEqual(Mat Img){
Mat Out = Img;
int ImgSize = Img.cols * Img.rows;
double Gray_Level_New[256]; //存放新的灰度级
int GrayVal_Add[256]; //存放各个灰度值的个数
double P[256]; //存放各级灰度值所占的比列 也就是概率
cvtColor(Out, Out, CV_BGR2GRAY);
/*初始化各参数*/
int idx = 0;
for (int i = 0; i < 256; i++){
GrayVal_Add[i] = 0;
P[i] = 0;
Gray_Level_New[i] = 0;
}
/*统计每个灰度值的个数*/
for (int i = 0; i < Img.rows; i++)
for (int j = 0; j < Img.cols; j++){
GrayVal_Add[Out.ptr<uchar>(i)[j]] += 1;
}
for (int i = 0; i < 256; i++){
P[i] = (double)GrayVal_Add[i] / ImgSize;
}
/*建立新的灰度级别的数组*/
double sum = 0;
for (int i = 0; i < 256; i++){
sum += P[i];
Gray_Level_New[i] = sum * 255;
}
/*结果*/
for (int i = 0; i < Out.rows; i++){
for (int j = 0; j < Out.cols; j++){
Out.ptr<uchar>(i)[j] = (int)Gray_Level_New[(int)Out.ptr<uchar>(i)[j]];
}
}
return Out;
}