点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
白色色阶、对比度、直方图均衡化算法优化
自动色阶、自动对比度以及直方图均衡这三个算法虽然很普通,也很简单,但是在实际应用中有着非常高的使用率,特别是在修图中,很多设计师打开一幅图,首先的的操作就是Shift+Ctrl+L(自动色阶)。在原理实现上,他们都属于基于直方图统计方面的算法,执行效率都非常之高。我在调整图像- 自动对比度、自动色阶算法一文中对他们的过程进行了详细的分析和解读,这里不在详述。
但是有的时候我们发现自动色阶或对比度等等会过调整或欠调整,在某个软件(不记得是那个了)中我发现了对他们的一些改进方式,其核心改进如下:
普通的方式:
for (int Y = 0; Y < 256; Y++)
{
if (Y < Min)
Table[Y] = 0;
else if (Y > Max)
Table[Y] = 255;
else
Table[Y] = IM_ClampToByte((float)(Y - Min) / (Max - Min) * 255);
}
改进后的方式:
float Avg = 0, Mean = 0, Sum = 0;
for (int Y = 0; Y < 256; Y++)
{
Sum += Histgram[Y];
Avg += Y * Histgram[Y];
}
Mean = Avg / Sum;
float Gamma = log(0.5f) / log((float)(Mean - Min) / (Max - Min));
if (Gamma < 0.1f)
Gamma = 0.1f;
else if (Gamma > 10)
Gamma = 10;
for (int Y = 0; Y < 256; Y++)
{
if (Y < Min)
Table[Y] = 0;
else if (Y > Max)
Table[Y] = 255;
else
Table[Y] = IM_ClampToByte(pow((float)(Y - Min) / (Max - Min), Gamma) * 255);
}
其中的Max和Min的意思请参考其他的文章。改进后的查找表考虑到全图的一个平均值信息,根据这个平局值来决定调整的一个Gamma值,相当于他同时结合了Gamma校正和自动色阶的思想,普通的自动色阶对应Gamma=1,还是拿一些我常用的测试图举例吧。
似乎改进后的更为合理。对于直方图均衡化的改进,我在ImageJ的代码中找到这样一段话:
// Changes the tone curves of images.
// It should bring up the detail in the flat regions of your image.
// Histogram Equalization can enhance meaningless detail and hide important but small high-contrast features. This method uses a
// similar algorithm, but uses the square root of the histogram values, so its effects are less extreme. Hold the alt key down
// to use the standard histogram equalization algorithm. This code was contributed by Richard Kirk (rak@cre.canon.co.uk).
// ImageJ\source\ij\plugin\ContrastEnhancer.java
他的核心代码修改如下:
private void equalize(ImageProcessor ip, int[] histogram)
{
ip.resetRoi();
if (ip instanceof ShortProcessor) { // Short
max = 65535;
range = 65535;
} else { //bytes
max = 255;
range = 255;
}
double sum;
sum = getWeightedValue(histogram, 0);
for (int i=1; i<max; i++)
sum += 2 * getWeightedValue(histogram, i);
sum += getWeightedValue(histogram, max);
double scale = range/sum;
int[] lut = new int[range+1];
lut[0] = 0;
sum = getWeightedValue(histogram, 0);
for (int i=1; i<max; i++) {
double delta = getWeightedValue(histogram, i);
sum += delta;
lut[i] = (int)Math.round(sum*scale);
sum += delta;
}
lut[max] = max;
applyTable(ip, lut);
}
private double getWeightedValue(int[] histogram, int i) {
int h = histogram[i];
if (h<2 || classicEqualization) return (double)h;
return Math.sqrt((double)(h));
}
他这里主要是对直方图的数据进行了开根号,这样可以减少有些色阶特别集中的直方图对修正后的图像的影响,他可以解决普通的直方图均衡化有时候处理起来图像变换太大的问题,我们同样以上述两幅图来做示范。
可以明显的看到,标准的直方图均衡化对两幅图的处理都太过分,而改进后的则效果要和谐和自然很多。这种改进还可以嵌入到很多其他的和直方图有关的算法中,比如CLAHE等等,也可以有效的改进他们的效果。
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~