1 引言
图像层叠(Image Stacking)是数字图像处理中的常用的一种技术,它针对同一场景拍摄多张图像,然后将这组图像层叠在一起来减小图像噪声.
我们在低光照场景下拍摄的图像经常会带有噪声,为了将多张拍摄的图像进行堆叠,需要对不同图像上同一位置上像素进行校准.
上图所示,左侧为我们在低光照下拍摄的图像,右侧图像我们使用8张图像进行层叠后的效果.
2 实现
本文需要对以下4张包含不同噪声的四张图进行层叠,所选择的样例图像如下所示:
在进行图像层叠时,对同一位置来自不同图像的像素可以有多种处理方式,一般常用的方式有 均值,中值和最值,我们来写上述几种处理方式的相关代码.
def blendStack(stack, modo='median', axis=0):
if modo == 'arithmetic mean':
blend = np.mean(stack, axis)
if modo == 'geometric mean':
blend = stats.gmean(stack, axis)
if modo == 'harmonic mean':
blend = stats.hmean(stack, axis)
if modo == 'median':
blend = np.median(stack, axis)
if modo == 'minimum':
blend = np.amin(stack, axis)
if modo == 'maximum':
blend = np.amax(stack, axis)
return blend.astype(stack.dtype)
上述实现中:
- stack 参数为我们传入的图像array
- mode 参数为我们选择的层叠方式
- axis 参数为我们进行操作的坐标轴
3 处理效果
3.1 获取图像序列
我们一次读取一个目录下所有的图像序列,代码如下:
def stackRead(pathname):
'''
pathname defined by "glob" pattern.
i.e.: "directory/sequence_folder/image_*.jpg"
'''
SEQ_IMG = glob.glob(pathname)
n = len(SEQ_IMG)
print("total num is {}".format(n))
sample = imageio.imread(SEQ_IMG[0])
# x and y are the dimensions
# c is the number of channels
y, x, c = sample.shape # (512,512,3)
# define stack
stack = np.zeros((n, y, x, c), dtype=sample.dtype)
# image stacking
for FILE in SEQ_IMG:
index = SEQ_IMG.index(FILE)
image = imageio.imread(FILE)
stack[index] = image
return stack
调用代码如下:
stack = stackRead('./image/sample.*.jpg')
# print(len(stack))
panel(stack , (3, 1),interval=[0, 1],
dims=(1200, 400),
texts=['{:04}'.format(i + 1) for i in range(10)],
save_text = "./result/stack.jpg"
)
这里显示了取前3张图,运行结果如下:
3.2 中值效果
采用中值进行多幅图像的层叠,所进行的操作为对同一位置的像素点执行取中值操作,代码如下:
median = blendStack(stack)
sample_blend = np.array([stack[0] , median ])
panel(sample_blend, (2, 1),
interval=[0, 1],
texts=['sample 0001', 'median'],
save_text= "./result/median.jpg"
)
运行结果如下:
3.3 均值效果
采用均值进行多幅图像的层叠,所进行的操作为对同一位置的像素点执行取均值操作,均值的计算包括算术均值,几何均值以及调和均值,调用代码如下:
mean_a = blendStack(stack, modo='arithmetic mean')
mean_g = blendStack(stack, modo='geometric mean')
mean_h = blendStack(stack, modo='harmonic mean')
sample_blend = np.array([mean_a, mean_g, mean_h])
panel(sample_blend, (3, 1),
dims=(1200, 400),
interval=[0, 1],
texts=['arithmetic mean', 'geometric mean', 'harmonic mean'],
save_text = './result/mean.jpg',
)
运行效果如下:
从左往右依次为 算术均值,几何均值以及调和均值计算后的结果.
3.4 最值效果
采用最值进行多幅图像的层叠,所进行的操作为对同一位置的像素点执行取最大值或最小值操作,相应的调用代码如下:
minimum = blendStack(stack , modo='minimum')
maximum = blendStack(stack , modo='maximum')
sample_blend = np.array([minimum, maximum])
panel(sample_blend, (2, 1),
interval=[0, 1],
texts=['minimum', 'maximum'],
save_text= './result/extremes.jpg'
)
运行效果如下:
上述图像中,左侧为取最小值运算后的结果,右侧为取最大值运算后的结果.
4 总结
本文介绍了使用图像序列进行图像层叠的原理和多种实现方式,并给出了相应的代码示例和运行效果.
您学废了吗?
5 参考
参考 链接一
关注公众号《AI算法之道》,获取更多AI算法资讯。
注: 完整代码,关注公众号,后台回复 图像层叠 , 即可获取。