首页 > 解决方案 > 剪辑限制在 OpenCV CLAHE 中究竟意味着什么?

问题描述

我读过很多文章说剪辑限制是CDF斜率的限制。但是在OpenCV中,那个参数可以设置为0~999...,我不知道这个参数的最大值,不是PDF的总和等于1吗?斜率怎么会大于1?剪辑限制的另一种说法是每个灰度级计数的限制,例如,如果我将平铺设置为 (8,8),则该平铺中的任何灰度级都不会超过 64 像素,但如果我设置限制超过64,结果还在变化。请以任何观点启发我。

标签: pythonopencv

解决方案


因此,剪辑限制的实现方式如下:

  1. 为每个可能的像素强度计算概率密度函数 (PDF),假设我们有一个 8 位图像,因此 PDF 是一个索引为 0 到 255 的数组。PDF 是通过计算图像中的像素数来计算的该强度,例如,PDF(intensity = 0) = 26 表示图像中有 26 个像素,强度为 0。
  2. 计算出 PDF 后,代码将遍历 PDF 中的每个元素,并确定 PDF 中的该元素是否大于 clipLimit。因此,例如,clipLimit 为 4,我们从 PDF(0) = 26 开始,它大于 4。因此,代码在 4 by 处“剪切”强度为 0 的像素数 clipped = clipped + pdf[i] - clipLimit;,剪切开始的位置在 0。然后裁剪 = 0 + 26 - 4 = 22。代码继续为 PDF(强度 = 1)、PDF(强度 = 2)、...、PDF(强度 = 255)执行此操作。最后,PDF 中没有单个元素大于clipLimit,并且超出的像素计数已存储在变量clipped 中。(就像 fmw42 所说的那样)。
  3. 然后,裁剪像素的数量在数组 PDF 中重新分布均匀。例如,假设 clipped = 128,那么 PDF 的几乎每个其他元素都会获得 +1 像素计数。所以,如果剪裁后的 PDF(0) = 4, PDF(1) = 2, PDF(2) = 0,那么重新分配后就是 PDF(0) = 4+1, PDF(1) = 2, PDF (2) = 0+1。请注意,在重新分配之后,之前处于最大值的一些像素,即 clipLimit,被略微推高超过了 clipLimit。

Wikipedia来看,clipLimit 通常设置在 3 到 4 之间。当按上述方式实现剪辑限制时,直方图中任何元素的最大值都是有限的,因此,任意两个相邻元素之间的最大斜率(即强度变化)直方图中的元素是有限的。

  • 一个不切实际但有帮助的练习是,假设大小为 1920 x 1080 像素的图像中的所有像素的强度为 1,因此 PDF 的开头是 PDF(0) = 0,PDF(1) = 2073600, PDF 的其余元素为 0。那么,CDF 的斜率 = (2073600-0)/(1-0) = 2073600。
  • 然而,现在想象一下,对于同一张图像,我们将 clipLimit 设置为 4,并且整个图像只有一个直方图。剪裁后的 PDF 为:PDF(0) = 0、PDF(1) = 4、PDF(2) = 0,以此类推。剪裁后的最大斜率为 (4-0)/(1-0) = 4,远小于 2073600。重新分配后,每个直方图 bin 大约多出 8100 个像素,因此 PDF 将类似于 PDF(0) = 8100,PDF(1) = 8104,PDF(2) = 8100,以此类推。现在,剪裁和重新分配后 CDF 的最大斜率是 (8104-8100)/(1-0) = 4。

至于你的问题,PDF的总和确实是1。但是,这里的数组PDF存储了计数,即PDF的分子。因此,对于大小为 1920 x 1080 的图像,如果实际 PDF 是

  • 概率(强度 = 0)= 4/(1920x1080)= 4/2073600
  • P(强度 = 1) = 2/2073600
  • P(intensity = 2) = 0/2073600 ,那么这些分数的总和确实是 1。这个在 OpenCV 源代码中实现的概率密度函数将在数组 PDF 中显示为:
  • PDF(0) = 4
  • PDF(1) = 2
  • PDF(2) = 0 ,如果没有分母,这些元素的总和不会为 1。

代码的实现参考OpenCV源码。作为脚注,我对重新分配的实施做了一些简化,但希望它应该更容易理解。


推荐阅读