前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自动色阶、对比度、直方图均衡等算法的一些小改进

自动色阶、对比度、直方图均衡等算法的一些小改进

作者头像
OpenCV学堂
发布2019-08-21 18:09:12
1.4K0
发布2019-08-21 18:09:12
举报

点击上方↑↑↑“OpenCV学堂”关注我

作者网名:laviewpbt 是图像处理,算法实现与加速优化方面的大神!其开发的imageshop软件大小只有1MB,却实现了非常丰富与复杂的各种图像处理功能, 邮箱地址为:Email: laviewpbt@sina.com 博客地址:https://www.cnblogs.com/Imageshop/

自动色阶、对比度、直方图均衡化算法优化

自动色阶、自动对比度以及直方图均衡这三个算法虽然很普通,也很简单,但是在实际应用中有着非常高的使用率,特别是在修图中,很多设计师打开一幅图,首先的的操作就是Shift+Ctrl+L(自动色阶)。在原理实现上,他们都属于基于直方图统计方面的算法,执行效率都非常之高。我在调整图像- 自动对比度、自动色阶算法一文中对他们的过程进行了详细的分析和解读,这里不在详述。

但是有的时候我们发现自动色阶或对比度等等会过调整或欠调整,在某个软件(不记得是那个了)中我发现了对他们的一些改进方式,其核心改进如下: 普通的方式:

代码语言:javascript
复制
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);
}

改进后的方式:

代码语言:javascript
复制
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的代码中找到这样一段话:

代码语言:javascript
复制
//    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

他的核心代码修改如下:

代码语言:javascript
复制
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等等,也可以有效的改进他们的效果。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自动色阶、对比度、直方图均衡化算法优化
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档