剪辑限制在 OpenCV CLAHE 中究竟意味着什么?

I. *_*Lin 1 python opencv

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

小智 5

所以,剪辑限制的实现方式如下:

  1. 概率密度函数 (PDF) 是为每个可能的像素强度计算的,假设我们有一个 8 位图像,所以 PDF 是一个索引为 0 到 255 的数组。 PDF 是通过计算图像中的像素数来计算的该强度,例如,PDF(intensity = 0) = 26 表示图像中有 26 个像素的强度为 0。
  2. 计算出 PDF 后,代码循环遍历 PDF 中的每个元素,并确定 PDF 的该元素是否大于 clipLimit。所以,比如说,clipLimit 是 4,我们从 PDF(0) = 26 开始,它大于 4。所以,代码“clipped = clipped + pdf[i] - clipLimit;裁剪”了 4 处强度为 0 的像素计数 ,裁剪开始的地方在 0。然后裁剪 = 0 + 26 - 4 = 22。代码继续为 PDF(强度 = 1)、PDF(强度 = 2)、...、PDF(强度 = 255) 执行此操作。最后,PDF 的任何单个元素都不会大于 clipLimit,并且多余的像素计数已存储在变量 clipped 中。(就像 fmw42 所说的那样)。
  3. 然后,裁剪像素的数量在数组 PDF 上均匀地重新分布。例如,假设裁剪 = 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。

维基百科来看,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源代码。作为脚注,我对重新分发的实现做了一些简化,但希望它应该更容易理解。