通过均值可以实现平滑的效果,不过这样采用卷积的方式来计算还是不够快,即使是使用了分离的卷积计算。由于均值的特殊性,可以针对这种卷积计算进行优化。我们知道计算均值就是把所有元素加到一起,然后再除以个数。由于图像很大,而卷积算子很小,那么就相当于一个窗口不断地滑动在图像上,并且计算这个窗口的和,那么有没有方法让这个计算的和快速一些。我们知道卷积计算是由乘法再求和,要快速就得把乘法替换掉,那么要怎么样才替换掉呢?这里就得引入一个技巧性的计算方法—积分图像(Integral Image)。图像是由一系列的离散像素点组成, 因此图像的积分其实就是求和. 图像积分图中每个点的值是原图像中该点左上角的所有像素值之和。首先建立一个数组 A 作为积分图像,其宽高与原图像相等。 然后对这个数组赋值,每个点存储的是该点与图像原点所构成的矩形中所有像素的和。如下图来说明计算:
在这里左边是输入图像,右边是积分图像。为了计算方便,一般积分图像需要在原图的大小上面和左边补充一行0的元素,这样采用公式计算就方便。在原图里(1,1)的位置是1,在积分图像里,就变成(2,2)的位置,然后来看一下(2,2)左上角所有元素只有一个(1,1),即是1。计算积分图(2,3)的位置时,那么查看原图里左上角所有元素是(1,1),(1,2),即是1+5,因此等于6。计算积分图(3,2)位置,这个左上角的元素是(1,1),(2,1),即是1+2=3,所以(3,2)位置值等于3。计算积分图(3,3)位置,就是计算原图里(1,1)、(1,2)、(2,1)、(2,2)元素之和,即是1+5+2+4=12。通过这样的方式,就可以计算出积分图像,就像右边的图像一样。
有了这样的积分图像,再来计算均值,就容易得多了,并且无论计算那一点的均值都是常量时间,无须考虑窗口的大小。如下图这样使用:
左边是输入图像,右边是该图像的积分图像,现在要计算原图选中的像素之和,那么可以这样计算,找到这个区域对应积分图像的四个坐标,再把坐标左上角的值按这样计算:46 – 22 – 20 + 10 = 14。
从这个图里看到就更加明显,要计算A的面积,就是L4-L2-L3+L1。
在这里引入快速计算积分图像的方法,如下图:
可以看到上面计算公式:Integral(i,j) = Integral(i,j-1) + ColumnSum(j);
这样只需要计算原图像上列积分,再加上积分图像左边的元素值即可。由此可见可见,可以通过这个公式快速地计算积分图像,实现的代码如下:
#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np
#计算积分图像Integral(i,j) = Integral(i,j-1) + ColumnSum(j);
def integral(img,h,w):
integ_graph = np.zeros((h+1,w+1),dtype = np.int32)
for x in range(h):
sum_clo = 0
for y in range(w):
sum_clo += img[x][y]
#print('y={},{},sum={}'.format(y,img[x][y],sum_clo))
integ_graph[x+1][y+1] = integ_graph[x][y+1] + sum_clo;
return integ_graph
#测试1
image1=np.array([[1,5,1],[2,4,1]])
h,w = image1.shape[:2]
print('imagesize={}-{}'.format(w,h))
print(image1)
print(integral(image1,h,w))
#测试2
image2=np.array([[1,2,2,4,1],
[3,4,1,5,2],
[2,3,3,2,4],
[4,1,5,4,6],
[6,3,2,1,3]])
h,w = image2.shape[:2]
print('imagesize={}-{}'.format(w,h))
print(image2)
print(integral(image2,h,w))
cv2.waitKey(0)
cv2.destroyAllWindows()
结果输出如下:
imagesize=3-2
[[1 5 1]
[2 4 1]]
[[ 0 0 0 0]
[ 0 1 6 7]
[ 0 3 12 14]]
imagesize=5-5
[[1 2 2 4 1]
[3 4 1 5 2]
[2 3 3 2 4]
[4 1 5 4 6]
[6 3 2 1 3]]
[[ 0 0 0 0 0 0]
[ 0 1 3 5 9 10]
[ 0 4 10 13 22 25]
[ 0 6 15 21 32 39]
[ 0 10 20 31 46 59]
[ 0 16 29 42 58 74]]
https://blog.csdn.net/caimouse/article/details/51749579
转载:https://blog.csdn.net/caimouse/article/details/100894310