利用高斯金字塔制作图像显著图
显著图:
显著图是将一幅图像中最容易吸引人眼球的部分突出表现的图像
虽然现在我们通常使用深度学习的方法计算显著图,但是一开始人们用图像的RGB成分或者HSV成分创建高斯金字塔,并通过求差来得到显著图。
有关高斯金字塔的描述,读者可查看:
知乎大神讲解高斯金字塔
自己实现高斯金字塔
我提供了使用高斯金字塔来简单地求显著图的算法:
- 我们使用双线性插值调整图像大小至原图的 1/2 1/4 1/8...... ,再使用双线性插值将生成的这些图像放大到原来的大小。
- 将得到的金字塔(我们将金字塔的各层分别编号为0,1,2,3,4,5)两两求差。
- 将第二部得到的差全部相加,并正规化到[0,255]。
完成以上步骤就可以得到显著图了。我们知道在缩小放大的过程中,图像的边缘变化较大,通过将缩小放大后的图像做差,我们得到的是图像灰度剧烈变化的区域,同时也是我们眼球感兴趣的区域。
实验:利用高斯金字塔制作图像的显著图:
# Writer : wojianxinygcl@163.com
# Date : 2020.3.25
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# make image pyramid
def make_pyramid(gray):
# 裁剪图像
H,W = gray.shape
H -= H % 32
W -= W % 32
out = np.zeros((H,W),dtype=np.uint8)
out = gray[:H,:W]
# first element
pyramid = [out]
# each scale
for i in range(1, 6):
# define scale
a = 2. ** i
# down scale
p = cv.resize(out, (int(out.shape[1] / a), int(out.shape[0] / a)),interpolation=cv.INTER_LINEAR)
# up scale
p = cv.resize(p, (int(p.shape[1] * a), int(p.shape[0] * a)),interpolation=cv.INTER_LINEAR)
# add pyramid list
pyramid.append(p.astype(np.float32))
return pyramid
# make saliency map
def saliency_map(pyramid):
# get shape
H, W = pyramid[0].shape
# prepare out image
out = np.zeros((H, W), dtype=np.float32)
# add each difference
out += np.abs(pyramid[0] - pyramid[5])
out += np.abs(pyramid[0] - pyramid[4])
out += np.abs(pyramid[0] - pyramid[3])
out += np.abs(pyramid[3] - pyramid[2])
out += np.abs(pyramid[4] - pyramid[1])
out += np.abs(pyramid[5] - pyramid[0])
# normalization
out = out / out.max() * 255
return out
# Read image
img = cv.imread("../paojie.jpg")
# grayscale
gray = cv.cvtColor(img,cv.COLOR_RGB2GRAY)
# pyramid
pyramid = make_pyramid(gray)
# pyramid -> saliency
out = saliency_map(pyramid)
out = out.astype(np.uint8)
# Save result
cv.imshow("result", out)
cv.imwrite("out.jpg", out)
cv.waitKey(0)
cv.destroyAllWindows()