在《OpenCV自适应直方图均衡CLAHE的clipLimit的含义及理解》,老猿结合源代码介绍了clipLimit裁剪限制值的意义,但没有来得及介绍具体裁剪过程,下面就结合源代码介绍一下自适应直方图均衡的裁剪过程。
裁剪处理在类 CLAHE_Impl的apply方法里调用CLAHE_CalcLut_Body类的函数对象来实现的,CLAHE_Impl是createCLAHE生成CLAHE实例时真正使用的类,而CLAHE_CalcLut_Body类是生成真正的直方图灰度映射和进行裁剪的类。涉及裁剪的代码在CLAHE_CalcLut_Body的operator函数中。相关的关键源代码如下:
template <class T, int histSize, int shift>
void CLAHE_CalcLut_Body<T,histSize,shift>::operator ()(const cv::Range& range) const
{
...
// clip histogram
if (clipLimit_ > 0)
{
// how many pixels were clipped
int clipped = 0;
for (int i = 0; i < histSize; ++i)
{
if (tileHist[i] > clipLimit_)
{
clipped += tileHist[i] - clipLimit_;
tileHist[i] = clipLimit_;
}
}
// redistribute clipped pixels
int redistBatch = clipped / histSize;
int residual = clipped - redistBatch * histSize;
for (int i = 0; i < histSize; ++i)
tileHist[i] += redistBatch;
if (residual != 0)
{
int residualStep = MAX(histSize / residual, 1);
for (int i = 0; i < histSize && residual > 0; i += residualStep, residual--)
tileHist[i]++;
}
}
...
}
}
以上代码就是OpenCV自适应直方图均衡CLAHE直方图裁剪的对应源代码。上述代码中,tileHist为当前处理块的直方图分组数据,clipLimit_是《OpenCV自适应直方图均衡CLAHE的clipLimit的含义及理解》介绍的裁剪限制值,某个分组中的像素数超过这个限制值则需要裁剪。
具体裁剪处理时,对于直方图分组像素数超过clipLimit_的,则将该分组中超过clipLimit_的像素数累加到clipped局部变量中,然后将该直方图分组像素数强制设置为clipLimit_。
上述过程对当前块的所有分组都处理完成后,将超出后累加的clipped变量值按分组数平均分配到各分组中,如果存在不够平均分配的部分,则等间距按顺序插入到分组中,直到所有超出部分都分配到了对应分组。如直方图分组是256个,累加的clipped值是1027个,则先每个分组值加4,然后将剩余4个分别累加到第0、85、 170三个位置的直方图分组中。
OpenCV自适应直方图均衡CLAHE中的参数clipLimit,是CLAHE的裁剪限制值,当图像的各分块图像的直方图分组的像素数据超过这个限制值就需要裁剪。裁剪时,将个分组中像素数超出限制值的强制值为限制值,并将所有分组中超出部分累加后平均分配到各分组。
阅读量:2023
点赞量:0
收藏量:0