积方图原理
图像由一系列离散像素点组成,因此图像的积分其实就是求和。图像积分图中每个点的值是原图像中该点左上角的所有像素值之和。
例如建立一个数组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)=xi≤x,yi≤y∑I(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,y−1)+SAT(x−1,y)−SAT(x−1,y−1)+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
下面对上述公式进行说明:
- 坐标
(
x
−
1
,
y
)
(x-1,y)
(x−1,y)处的积分图像
S
A
T
(
x
−
1
,
y
)
SAT(x-1,y)
SAT(x−1,y)
- 坐标
(
x
,
y
−
1
)
(x,y-1)
(x,y−1)处的积分图像
S
A
T
(
x
,
y
−
1
)
SAT(x,y-1)
SAT(x,y−1):
- 从上面可以发现它们有一部分重合,即重合的积分图像是
S
A
T
(
x
−
1
,
y
−
1
)
SAT(x-1,y-1)
SAT(x−1,y−1):
由此可以看出
S
A
T
(
x
,
y
)
SAT(x,y)
SAT(x,y)的积分图像等于
S
A
T
(
x
−
1
,
y
)
SAT(x-1,y)
SAT(x−1,y)加
S
A
T
(
x
,
y
−
1
)
SAT(x,y-1)
SAT(x,y−1),再减去二者的重合部分
S
A
T
(
x
−
1
,
y
−
1
)
SAT(x-1,y-1)
SAT(x−1,y−1),最后再加上
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)=SAT4−Sum(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))−(SAT3−Sum(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)−(SAT3−SAT1)
= 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−SAT3+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+SAT4−SAT2−SAT3
所以无论矩形的尺寸大小,只需查找积分图像 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)=x≤X,y≤Y∑img(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)=x≤X,y≤Y∑(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+0−0+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+1−0+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+5−0+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+0−0+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+3−1+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+12−5+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+0−0+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+6−3+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+21−12+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<Y∑image(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<Y∑image(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,∣x−X+1∣≤Y−y−1∑image(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) x1≤x<x2,y1≤y<y2∑image(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图像积分图算法
函数