数字图像处理之积分图

      使用积分图是数字图像处理中常用的一种方法,通常能够很大程度的加速计算过程,比如均值滤波,非局部均值滤波,以及Harr计算等。本文主要讲解积分图的原理,以及基于opencv和C++的实现。

      从直观来说,一张图像就是一个矩形,这个矩形中每个像素点的积分值,就是以图像左上角像素点为左上角顶点,以该像素点为右下角顶点的矩形中包含的所有元素之和。如下图所示,点(x,y)处的积分值为矩形区域中所有像素之和(包括该点)。

      实际计算积分图的时候,为了提高计算效率,通常不会对每一个像素点都重新计算矩形区域包含的所有元素值之和,而是利用相邻点的积分值实现快速计算,如下图所示,点(x,y)的积分值可以使用点(x-1,y)与点(x,y-1)的积分值之和,然后减去重叠区域,也就是减去点(x-1,y-1)的积分值,最后再加上点(x,y)的像素值得到点(x,y)的积分值。

       上述原理用公式表示为:

        I(x,y) = I(x-1,y) + I(x,y-1) - I(x-1,y-1) + pixel(x,y)

        此外还需要考虑边界问题,也就是第一行和第一列的计算。

        对于第一行:

        I(0,0) = pixel(0,0),x=0,y=0

        I(x,0) = I(x-1,0) + pixel(x,0),x>0,y=0

        对于第一列:

        I(0,y) = I(0,y-1) + pixel(0,y),x=0,y>0

        根据上述原理,基于Opencv与C++的实现代码如下:

void Integral(Mat src, Mat &integal_out)

{  

        Mat tmp(src.size(), CV_64FC1, 0.0);

tmp.ptr<double>(0)[0] = (double)src.ptr<uchar>(0)[0];

for(int i = 1; i < src.cols; i++)   //第一行

{

tmp.ptr<double>(0)[i] = tmp.ptr<double>(0)[i-1] + src.ptr<uchar>(0)[i];

}

for(int i = 1; i < src.rows; i++)  //第一列

{

tmp.ptr<double>(i)[0] = tmp.ptr<double>(i-1)[0] + src.ptr<uchar>(i)[0];

}

for(int i = 1; i < src.rows; i++)   //第i行

{

for(int j = 1; j < src.cols; j++)   //第j列

{

tmp.ptr<double>(i)[j] = tmp.ptr<double>(i)[j-1] + tmp.ptr<double>(i-1)[j] - tmp.ptr<double>(i-1)[j-1] + src.ptr<uchar>(i)[j];

}

}

tmp.copyTo(integal_out);

}

posted @ 2020-09-28 21:47  萌萌哒程序猴  阅读(143)  评论(0编辑  收藏  举报