我读过很多文章说clip limit是CDF斜率的极限。但是在OpenCV中,该参数可以设置为0~999...,我不知道这个参数的最大值,PDF的总和不等于1吗?斜率怎么会大于1呢?
剪辑限制的另一种说法是,这是对每个灰度级计数的限制,因此例如,如果我将图块设置为 (8,8),则该图块中的任何灰度级都不可能超过 64 像素,但如果我设置限制超过64,结果仍在变化。
请赐教我任何观点。
因此,clip limit的实现方式如下:
- 概率密度函数 (PDF) 是针对每个可能的像素强度计算的,假设我们有一个 8 位图像,因此 PDF 是一个索引为 0 到 255 的数组。PDF 是通过计算图像中的像素数来计算的例如,PDF(intensity = 0) = 26 表示图像中有 26 个像素的强度为 0。
- 一旦计算出 PDF,代码就会循环遍历 PDF 中的每个元素,并确定 PDF 的该元素是否大于 ClipLimit。因此,举例来说,clipLimit 为 4,我们从 PDF(0) = 26 开始,它大于 4。因此,代码通过以下方式“剪辑”强度为 0 的像素计数:
clipped = clipped + pdf[i] - clipLimit;
,其中 Clipped 从 0 开始。然后 Clipped = 0 + 26 - 4 = 22。代码继续对 PDF(intensity = 1)、PDF(intensity = 2)、...、PDF(intensity = 255) 执行此操作。最后,PDF 中没有任何单个元素大于 ClipLimit,并且超出的像素数已存储在变量 Clipped 中。 (就像 fmw42 所说的)。
- 然后,剪裁的像素数量在 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。
From 维基百科 https://en.wikipedia.org/wiki/Adaptive_histogram_equalization,clipLimit通常设置在3到4之间。当像上面那样实现clip limit时,直方图中任意元素的最大值受到限制,因此,直方图中任意两个相邻元素之间的最大斜率(即强度变化)直方图是有限的。
- 一个不切实际但有用的练习是想象一下尺寸为 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。重新分布后,每个直方图箱大约多获得 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(强度 = 2) = 0/2073600
,那么这些分数的总和确实为 1。像 OpenCV 源代码中那样实现的概率密度函数将在数组 PDF 中显示为:
- PDF(0) = 4
- PDF(1) = 2
- PDF(2) = 0
,并且如果没有分母,这些元素之和就不等于 1。
代码的实现可以参考OpenCV 源代码 https://github.com/opencv/opencv/blob/master/modules/imgproc/src/clahe.cpp。作为脚注,我对重新分配的实现进行了一些简化,但希望它应该更容易理解。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)