前言:
有时候只需要计算图像中某个特定区域的直方图。实际上累计图像的某个子区域内的像素总和,是很多计算机视觉算法中常见的过程。现在假设需要对图像中的多个兴趣区域计算几个此类直方图。这些计算过程都马上会变得非常耗时。这种情况下,有一个工具可以极大地提高统计图像子区域像素的效率:积分图像。
一、积分图像的原理
为了理解积分图像的实现原理,我们先对它下一个定义。取图像左上侧的全部像素计算累加和,并用这个累加和替换图像中的每一个像素,用这种方式得到的图像称为积分图像。计算积分图像时只需对图像扫描一次。这是因为当前像素的积分值等于上一像素的积分值加上当前行的累计值。因此积分图像就是一个包含像素累加和的新图像。为了防止溢出,积分图像的值通常采用int类型或float类型。例如下图中,积分图像的像素L1包含左上角区域。
计算完积分图像后,只需要访问四个像素就可以得到任何矩形区域的像素累加和。A区域的面积为:L4-L2-L3+L1,这里解释一下原因。再来看看前面的图片,计算由L1、L2、L3、L4四个像素表示区域的像素累计和,先读取L4的积分值,然后减去L2的像素值和L3左手边区域的像素值。但是这样就把L1左上角的像素累加和减去两次,因此需要重新加上L1的积分值。
二、代码实现
void integral(unsigned char* inputMatrix, unsigned long* outputMatrix, int width, int height){
// calculate integral of the first line
for(int i=0;i<width;i++){
outputMatrix[i] = inputMatrix[i];
if(i>0){
outputMatrix[i] += outputMatrix[i-1];
}
}
for (int i=1;i<height;i++){
int offset = i*width;
// first column of each line
outputMatrix[offset] = outputMatrix[offset-width]+inputMatrix[offset];
// other columns
outputMatrix[offset+j] = outputMatrix[offset+j-1] + outputMatrix[offset-width] + outputMatrix[offset-width-1] + inputMatrix[offset];
}
}
return;
}
参考博客:
https://blog.csdn.net/weixin_41695564/article/details/80056430
https://blog.csdn.net/xiaowei_cqu