OpenCV--030图像积方图算法

积方图原理

图像由一系列离散像素点组成,因此图像的积分其实就是求和。图像积分图中每个点的值是原图像中该点左上角的所有像素值之和。

例如建立一个数组A作为积分图像,它的宽高与图像相等。然后这个数组赋值,每个点存储的是该点与图像原点所构成的矩形中所有像素的和
S A T ( x , y ) = ∑ x i ≤ x , y i ≤ y I ( x i , y i ) SAT(x,y)=\sum_{x_i≤x,y_i≤y}I(x_i,y_i) SAT(x,y)=xix,yiyI(xi,yi)
其中 I ( x , y ) I(x,y) I(x,y) 表示图像 ( x , y ) (x,y) (x,y) 位置的像素值。 S A T ( x , y ) SAT(x,y) SAT(x,y)表示图像 ( x , y ) (x,y) (x,y)处的积分像素值之和。


在这里插入图片描述

此外积分图像可以采用增量的方式计算:

S A T ( x , y ) = S A T ( x , y − 1 ) + S A T ( x − 1 , y ) − S A T ( x − 1 , y − 1 ) + I ( x , y ) SAT(x,y)=SAT(x,y−1)+SAT(x−1,y)−SAT(x−1,y−1)+I(x,y) SAT(x,y)=SAT(x,y1)+SAT(x1,y)SAT(x1,y1)+I(x,y)

初始边界: S A T ( − 1 , y ) = S A T ( x , − 1 ) = S A T ( − 1 , − 1 ) = 0 SAT(−1,y)=SAT(x,−1)=SAT(−1,−1)=0 SAT(1,y)=SAT(x,1)=SAT(1,1)=0
在这里插入图片描述

下面对上述公式进行说明:

  1. 坐标 ( x − 1 , y ) (x-1,y) (x1,y)处的积分图像 S A T ( x − 1 , y ) SAT(x-1,y) SAT(x1,y)

    在这里插入图片描述
  1. 坐标 ( x , y − 1 ) (x,y-1) (x,y1)处的积分图像 S A T ( x , y − 1 ) SAT(x,y-1) SAT(x,y1):
    在这里插入图片描述
  2. 从上面可以发现它们有一部分重合,即重合的积分图像是 S A T ( x − 1 , y − 1 ) SAT(x-1,y-1) SAT(x1,y1):
    在这里插入图片描述

由此可以看出 S A T ( x , y ) SAT(x,y) SAT(x,y)的积分图像等于 S A T ( x − 1 , y ) SAT(x-1,y) SAT(x1,y) S A T ( x , y − 1 ) SAT(x,y-1) SAT(x,y1),再减去二者的重合部分 S A T ( x − 1 , y − 1 ) SAT(x-1,y-1) SAT(x1,y1),最后再加上 I ( x , y ) I(x,y) I(x,y)处的像素值。
在这里插入图片描述

计算任意区域内的像素和

根据积分图的概念,就可以计算出任意区域的像素和。如下:

在这里插入图片描述

由上图我们可以得到:

  • 点1的积分: S A T 1 = S u m ( R a ) SAT_1=Sum(R_a) SAT1=Sum(Ra)
  • 点2的积分: S A T 2 = S u m ( R a ) + S u m ( R b ) SAT_2=Sum(R_a)+Sum(R_b) SAT2=Sum(Ra)+Sum(Rb)
  • 点3的积分: S A T 3 = S u m ( R a ) + S u m ( R c ) SAT_3=Sum(R_a)+Sum(R_c) SAT3=Sum(Ra)+Sum(Rc)
  • 点4的积分: S A T 4 = S u m ( R a ) + S u m ( R b ) + S u m ( R c ) + S u m ( R d ) SAT_4=Sum(R_a)+Sum(R_b)+Sum(R_c)+Sum(R_d) SAT4=Sum(Ra)+Sum(Rb)+Sum(Rc)+Sum(Rd)

那么就可以求任意的某个矩形像素和,比如区域 Rd 内所有点的像素值之和(积分)可以表示为:

计算过程如下:
S u m ( R d ) = S A T 4 − S u m ( R a ) − S u m ( R b ) − S u m ( R c ) Sum(R_d)=SAT_4-Sum(R_a)-Sum(R_b)-Sum(R_c) Sum(Rd)=SAT4Sum(Ra)Sum(Rb)Sum(Rc)
S u m ( R d ) = S A T 4 − ( S u m ( R a ) + S u m ( R b ) ) − ( S A T 3 − S u m ( R a ) ) Sum(R_d)=SAT_4-(Sum(R_a)+Sum(R_b))-(SAT_3-Sum(R_a)) Sum(Rd)=SAT4(Sum(Ra)+Sum(Rb))(SAT3Sum(Ra))
                  = S A T 4 − ( S A T 2 ) − ( S A T 3 − S A T 1 ) =SAT_4-(SAT_2)-(SAT_3-SAT_1) =SAT4(SAT2)(SAT3SAT1)
                  = S A T 4 − S A T 2 − S A T 3 + S A T 1 =SAT_4-SAT_2-SAT_3+SAT_1 =SAT4SAT2SAT3+SAT1

S u m ( R d ) = S A T 1 + S A T 4 − S A T 2 − S A T 3 Sum(Rd)=SAT_1+SAT_4−SAT_2−SAT_3 Sum(Rd)=SAT1+SAT4SAT2SAT3

所以无论矩形的尺寸大小,只需查找积分图像 4 次就可以快速计算任意矩形内像素值的和, 即算法复杂度为 O(4)
在这里插入图片描述

积分图算法介绍

积分图算法是一种快速计算图像区域和以及图像区域平方和的算法。直白的说,就是很快计算一幅图像任意区域,也就是卷积区域下的像素值的和跟平方和。它的核心思想就是对每一个图像建立起自己的积分图查找表,在图像处理的阶段就可以根据预先建立积分图查找表直接查找从而实现对均值卷积的线性时间计算。做到了卷积执行的时间与半径窗口大小的无关联。


积分图的建立

图像积分图是根据原图像像素值而计算建立出来的,假设原图的大小为WH,则积分图的大小为(W+1)(H+1)。在积分图上任意坐标(x,y)处的ii(x,y)即表示原图中坐标为(x,y)的点的左上角所有点的像素值之和。

和表:
s u m ( X , Y ) = ∑ x ≤ X , y ≤ Y i m g ( x , y ) sum(X,Y)=\sum_{x≤X,y≤Y}img(x,y) sum(X,Y)=xX,yYimg(x,y)
平方和表:
s u m ( X , Y ) = ∑ x ≤ X , y ≤ Y ( i m g ( x , y ) ) 2 sum(X,Y)=\sum_{x≤X,y≤Y}(img(x,y))^2 sum(X,Y)=xX,yY(img(x,y))2

比如:假设输入图像为3*3,则积分图像为4*4。
在这里插入图片描述
X轴和Y轴边沿处的积分都为0。即积分图的第一列和第一行都为0。
S u m ( 1 , 1 ) = S u m ( 0 , 1 ) + S u m ( 1 , 0 ) − S u m ( 0 , 0 ) + I ( 1 , 1 ) = 0 + 0 − 0 + 1 = 1 Sum(1,1)=Sum(0,1)+Sum(1,0)-Sum(0,0)+I(1,1)=0+0-0+1=1 Sum(1,1)=Sum(0,1)+Sum(1,0)Sum(0,0)+I(1,1)=0+00+1=1;
S u m ( 1 , 2 ) = S u m ( 0 , 2 ) + S u m ( 1 , 1 ) − S u m ( 0 , 1 ) + I ( 1 , 2 ) = 0 + 1 − 0 + 4 = 5 Sum(1,2)=Sum(0,2)+Sum(1,1)-Sum(0,1)+I(1,2)=0+1-0+4=5 Sum(1,2)=Sum(0,2)+Sum(1,1)Sum(0,1)+I(1,2)=0+10+4=5;
S u m ( 1 , 3 ) = S u m ( 0 , 3 ) + S u m ( 1 , 2 ) − S u m ( 0 , 2 ) + I ( 1 , 3 ) = 0 + 5 − 0 + 7 = 12 Sum(1,3)=Sum(0,3)+Sum(1,2)-Sum(0,2)+I(1,3)=0+5-0+7=12 Sum(1,3)=Sum(0,3)+Sum(1,2)Sum(0,2)+I(1,3)=0+50+7=12;


S u m ( 2 , 1 ) = S u m ( 1 , 1 ) + S u m ( 2 , 0 ) − S u m ( 1 , 0 ) + I ( 2 , 1 ) = 1 + 0 − 0 + 2 = 3 Sum(2,1)=Sum(1,1)+Sum(2,0)-Sum(1,0)+I(2,1)=1+0-0+2=3 Sum(2,1)=Sum(1,1)+Sum(2,0)Sum(1,0)+I(2,1)=1+00+2=3;
S u m ( 2 , 2 ) = S u m ( 1 , 2 ) + S u m ( 2 , 1 ) − S u m ( 1 , 1 ) + I ( 2 , 2 ) = 5 + 3 − 1 + 5 = 12 Sum(2,2)=Sum(1,2)+Sum(2,1)-Sum(1,1)+I(2,2)=5+3-1+5=12 Sum(2,2)=Sum(1,2)+Sum(2,1)Sum(1,1)+I(2,2)=5+31+5=12;
S u m ( 2 , 3 ) = S u m ( 1 , 3 ) + S u m ( 2 , 2 ) − S u m ( 1 , 2 ) + I ( 2 , 3 ) = 12 + 12 − 5 + 8 = 27 Sum(2,3)=Sum(1,3)+Sum(2,2)-Sum(1,2)+I(2,3)=12+12-5+8=27 Sum(2,3)=Sum(1,3)+Sum(2,2)Sum(1,2)+I(2,3)=12+125+8=27;


S u m ( 3 , 1 ) = S u m ( 2 , 1 ) + S u m ( 3 , 0 ) − S u m ( 2 , 0 ) + I ( 3 , 1 ) = 3 + 0 − 0 + 3 = 6 Sum(3,1)=Sum(2,1)+Sum(3,0)-Sum(2,0)+I(3,1)=3+0-0+3=6 Sum(3,1)=Sum(2,1)+Sum(3,0)Sum(2,0)+I(3,1)=3+00+3=6;
S u m ( 3 , 2 ) = S u m ( 2 , 2 ) + S u m ( 3 , 1 ) − S u m ( 2 , 1 ) + I ( 3 , 2 ) = 12 + 6 − 3 + 6 = 21 Sum(3,2)=Sum(2,2)+Sum(3,1)-Sum(2,1)+I(3,2)=12+6-3+6=21 Sum(3,2)=Sum(2,2)+Sum(3,1)Sum(2,1)+I(3,2)=12+63+6=21;
S u m ( 3 , 3 ) = S u m ( 2 , 3 ) + S u m ( 3 , 2 ) − S u m ( 2 , 2 ) + I ( 3 , 3 ) = 27 + 21 − 12 + 9 = 45 Sum(3,3)=Sum(2,3)+Sum(3,2)-Sum(2,2)+I(3,3)=27+21-12+9=45 Sum(3,3)=Sum(2,3)+Sum(3,2)Sum(2,2)+I(3,3)=27+2112+9=45;

图像积分图的查找

在这里插入图片描述
根据上面得到的图像积分图,若想求出图像中的绿色区域的像素值和(5+6+8+9=28),只要根据每个点左上方所有像素值和表值进行两次减法和一次加法即可:45-6-12+1=28。也就是右下角+左上角-右上角和左下角。

OpenCV中的积分图

  • 函数说明
    用于计算图像的积分。
    s u m ( X , Y ) = ∑ x < X , y < Y i m a g e ( x , y ) sum(X,Y)=∑_{x<X,y<Y}image(x,y) sum(X,Y)=x<X,y<Yimage(x,y)
    s q s u m ( X , Y ) = ∑ x < X , y < Y i m a g e ( x , y ) 2 sqsum(X,Y)=∑_{x<X,y<Y}image(x,y)^2 sqsum(X,Y)=x<X,y<Yimage(x,y)2
    t i l t e d ( X , Y ) = ∑ y < Y , ∣ x − X + 1 ∣ ≤ Y − y − 1 i m a g e ( x , y ) tilted(X,Y)=∑_{y<Y,|x−X+1|≤Y−y−1}image(x,y) tilted(X,Y)=y<Y,xX+1Yy1image(x,y)
    使用这些积分图像,可以在恒定时间内计算出图像的特定直立或旋转矩形区域上的和,均值和标准偏差,例如:
    该函数为源图像计算一个或多个积分图像,如下所示:
    ∑ x 1 ≤ x < x 2 , y 1 ≤ y < y 2 i m a g e ( x , y ) = s u m ( x 2 , y 2 ) − s u m ( x 1 , y 2 ) − s u m ( x 2 , y 1 ) + s u m ( x 1 , y 1 ) ∑_{x_1≤x<x_2,y_1≤y<y_2}image(x,y)=sum(x_2,y_2)−sum(x_1,y_2)−sum(x_2,y_1)+sum(x_1,y_1) x1x<x2,y1y<y2image(x,y)=sum(x2,y2)sum(x1,y2)sum(x2,y1)+sum(x1,y1)

    例如,可以使用可变的窗口大小进行快速模糊或快速块相关。在多通道图像的情况下,每个通道的总和是独立累加的。

    作为一个实际示例,下图显示了直矩形Rect(3,3,3,2)和倾斜矩形Rect(5,1,2,3)的积分计算。显示原始图像中的选定像素,以及积分图像中的相对像素之和。
    在这里插入图片描述

  • 函数声明

    void integral( 
           InputArray src, 
           OutputArray sum,
           OutputArray sqsum, 
           OutputArray tilted,
           int sdepth = -1, 
           int sqdepth = -1 );
    
    void integral( 
           InputArray src, 
           OutputArray sum,
           OutputArray sqsum, 
           int sdepth = -1, 
           int sqdepth = -1 );
    
    void integral(
           InputArray src, 
           OutputArray sum, 
           int sdepth = -1 );
    
    
  • 函数参数

    src输入图像的大小为WH,8位或者浮点型。
    sum和表。积分图像为(W+1)(H+1), 32-bit integer or floating-point (32f or 64f).
    sqsum平方和表。像素值平方的积分图像;是(W+1)(H+1)的双精度浮点型数组。
    tilted旋转45度的图像的积分;它是数据类型和sum相同的(W+1)(H+1)的数组。
    sdepth和表深度,即积分和倾斜积分图像的所需深度CV_32S,CV_32F或CV_64F。
    sqdepth平方和表深度,即平方像素值CV_32F或CV_64F的积分图像的所需深度。
  • 应用举例

Mat src(Size(3,3),CV_8UC1);
	int flag = 1;
	for (int i = 0; i <src.rows ; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{

			src.at<uchar>(i, j) = flag;
			flag++;
		}
	}

	cout << endl << "图像的灰度值:" << endl<<endl;
	for (int i = 0; i < src.rows; i++)
	{
		const uchar* p = src.ptr(i);
		cout << "  ";
		for (int j = 0; j < src.cols;j++)
		{
			cout <<(int) p[j]<<" , ";
		}
		cout << endl;
	}



	Mat sum(Size(src.rows + 1, src.cols + 1), CV_32FC1);
	Mat sqsum(Size(src.rows+1,src.cols+1),CV_64FC1);
	
	integral(src, sum, sqsum);
	//integral(src, sum);

	cout << endl << "图像的和表:" << endl << endl;
	for (int i = 0; i < sum.rows; i++)
	{
		cout << "  ";
		//const float* p2 =sum.ptr(i);
		for (int j = 0; j < sum.cols; j++)
		{
			cout <<sum.at<int>(i,j)<< " , ";
		}
		cout << endl;
	}

	cout << endl << "图像的平方和表:" << endl << endl;
	for (int i = 0; i < sqsum.rows; i++)
	{
		cout << "  ";
		for (int j = 0; j < sqsum.cols; j++)
		{
			cout << sqsum.at<double>(i,j) << " , ";
		}
		cout << endl;
	}

在这里插入图片描述
学习:
【图像处理】OpenCV系列二十七 — 积分图(integral)详解
积分图(一) - 原理及应用
OpenCV图像积分图算法
函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值