一种消除局部自适应对比度加强算法方块效应的方法

一种基于腐蚀膨胀运算实现的局部自适应对比度加强算法中,提出了一种能够分开自适应的调整局部亮部和暗部对比度的方法。可是就象在评论中提到的,这种方法会产生方块效应。特别是在对比度已经比较大的边缘附近,这种方块效应会比较明显。这是由于在边缘附近,对比度原本就是比较大的,偏均方差也就响应的比较大。那么调整的时候给出自适应的调整量就会相应地变小。一旦离开边缘附近,领域不包括边缘,对比度就会相对陡然变小,那么自适应的调整量就会相应变大。那么在边缘同一侧就可能会比较明显地出现不均匀的变化,也就是咱们所说的方块效应。不均匀变化的位置离边缘的位置之间的距离就是所使用的高光半径或者暗影半径大小。html

看一下示例。这里为了明显显示方块效应,选择了一张前景和背景反差比较大的图片。同时这里我特地把高光半径和暗影半径选的不同,这样咱们就能够看到在不一样半径的地方有两个明显的不均匀变化。c++

原始图片  

                                      原始图片(1024x701)                           高光半径100,高光数量30,暗影半径50,暗影数量30,产生方块效应redis

消除方块效应的办法,一个是在作完对比度调整后,再作一个高斯模糊之类的低通滤波平滑这种不均匀。这种方法不可避免地会减少图像总体清晰度。另外一个简单的应对方法是,扩大所使用的领域。领域越大,包含像素越多,那么移动领域时对比度变化幅度就不会特别剧烈(即便在边缘附近),这样使得调整量的变化幅度也会大幅减小,极大地减小了方块效应。但同时,领域的扩大,也使得不一样像素的领域不论是腐蚀仍是膨胀结果都更加趋同,失去了所谓的局部自适应的效果。极限状况咱们想象一下,若是领域半径接近甚至超过图像大小,那么全部像素的腐蚀或者膨胀结果都是同样的了。那么自适应调整量也就都同样了,那就是一个全局的调整量了。算法

那么有没有一种方法既能减少方块效应,又避免这些反作用呢?方块效应产生的根源是在图像边缘附近对比度的变化过大致使的。那是否能过滤这种变化呢?这让我想到了有保边效果的选择性平滑所使用的方法。好比选择性均值平滑,不是把领域内的全部像素一块儿求平均值,而是选择领域内和中心像素的差值小于必定阈值的全部像素求平均值。假设在领域内有一个边缘,若是设定合适的阈值,就能把和中心像素在边缘另外一侧的像素都排除掉,只使用和中心像素同侧的像素参与计算,结果既保留了边缘,也起到了平滑效果。若是应用这种思想,在计算自适应调整量时,具体就是在计算膨胀或腐蚀结果的偏方差的时候,只选择和膨胀或腐蚀结果像素差值小于必定阈值的像素参与计算偏方差,理论上应该就能消除方块效应了。ide

原理上来讲和原始方法没有大的区别,就是须要多设置一个阈值post

  • 膨胀腐蚀计算时也是选择性的,选择领域内和中心像素差值小于阈值的全部像素中的最大值(膨胀)和最小值(腐蚀)。
  • 计算偏方差也是选择性的,选择领域内和中心像素差值小于阈值的全部像素参与计算。公式是同样的,只是求和不是全部像素总数n。

剩下的其余步骤都是同样的。测试

如何计算选择性膨胀腐蚀,还有选择性偏方差的方法也是一个问题。其中须要计算领域极值,均值和平方均值。原始算法是用积分图来计算领域平方和和领域和,如今选择性求和,积分图再也不适用了。在选择性平滑方法中常用的是O(1)复杂度的领域直方图更新算法,原始论文能够在Median Filtering in Constant Time找到。咱们在这里也能够用它,它的计算量基本和领域半径无关。并且使用领域直方图更新算法,能够计算多种选择性领域值,好比平均值,中值,极值,平方和均值,还能够应用表面模糊算法,局部直方图均衡等等。领域直方图更新算法的主要思想是,计算领域内全部像素直方图。当咱们从左到右,从上到下移动时,每次移动更新一次领域直方图。更新时减去移出领域的全部像素的直方图,加上新进入领域的全部像素的直方图,这只须要较少的计算量。具体的为加快计算,还保持更新和领域高度相同的全部列的直方图,这样更新领域直方图时,只需加减相应的列直方图便可。具体算法这里很少作讨论了。url

有了领域直方图,就能够很简单地计算选择性平均值和平方和均值。以下代码计算选择性均值。选择性平方和均值,还有极值也很简单。spa

{ /* int cen: 中心像素 * int threshold: 阈值 * Hist[]: 领域直方图 */
    int l; unsigned long weight = 0, sum = 0; int low, high; low = cen - threshold; if (low < 0) low = 0; high = cen + threshold; if (high > 255) high = 255; for (l = low; l <= high; l++) { sum += Hist[l] * l; weight += Hist[l]; } return sum / weight; }
选择性计算领域均值

 对于高光调整计算,一次直方图更新算法能够获得选择性平方和均值,均值和最小值。再作一次直方图更新算法能够获得暗影调整所需的值。若是高光和暗影半径是同样的话,只须要一次直方图更新算法就能够获得高光暗影调整全部须要的结果。再遍历一次图像,应用到全部像素便可。3d

看一下效果。无阈值至关于领域内全部像素都参与计算,如前所述会产生方块效应。保持高光和暗影半径不变,随着阈值减少,方块效应也会减少,达到咱们但愿的结果了。

原始图片   

                                        原始图片(1024x701)                                高光半径100,高光数量30,暗影半径50,暗影数量30,无阈值

  

高光半径100,高光数量30,暗影半径50,暗影数量30,阈值50        高光半径100,高光数量30,暗影半径50,暗影数量30,阈值10

分享一个测试程序https://files.cnblogs.com/files/mightycode/edcontrast.7z,须要安装vc++ 2015-2019 redistributable。

相关文章
相关标签/搜索