代码
所用图像如下,
s
h
a
p
e
=
(
300
,
300
)
shape=(300, 300)
shape=(300,300),请自行更换图像:
我主要使用了四种方法缩小图像:
-
1、直接删去图像偶数行列
-
2、使用高斯平滑,然后删去图像偶数行列
-
3、使用最大池化
-
4、使用均值池化
Content Loss由于需要相同的shape才能计算,所以我统一用opencv的resize默认方式将缩小的图像放大回去,便于计算Loss
import numpy as np
from scipy.ndimage import rotate
import os
from PIL import Image
import math
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
im = cv2.imread('figures/exampleFig.jpg', 0)
im = cv2.resize(im,(300,300))
plt.imshow(im)
def content_loss(im1, im2):
return np.mean(np.square((im1 - im2)))
def GaussianFilter(u, v, sigma):
f = (1 / (2 * math.pi * sigma**2)) * math.e**(-(u**2+v**2) / 2*sigma**2)
return f
def decrease1(im):
imD = np.zeros((int(im.shape[0] / 2), int(im.shape[1] / 2))).astype(np.uint8)
for i in range(int(im.shape[0] / 2)):
for j in range(int(im.shape[1] / 2)):
imD[i][j] = im[i*2][j*2]
return imD
def decrease2(im):
im = cv2.filter2D(im, kernel = GFKernel, ddepth = -1)
imD = np.zeros((int(im.shape[0] / 2), int(im.shape[1] / 2))).astype(np.uint8)
for i in range(int(im.shape[0] / 2)):
for j in range(int(im.shape[1] / 2)):
imD[i][j] = im[i*2][j*2]
return imD
def decrease3(im):
imD = np.zeros((int(im.shape[0] / 2), int(im.shape[1] / 2))).astype(np.uint8)
for i in range(int(imD.shape[0])):
for j in range(int(imD.shape[1])):
imD[i][j] = np.max(im[i*2:i*2+2, j*2:j*2+2])
return imD
def decrease4(im):
imD = np.zeros((int(im.shape[0] / 2), int(im.shape[1] / 2))).astype(np.uint8)
for i in range(int(imD.shape[0])):
for j in range(int(imD.shape[1])):
imD[i][j] = np.mean(im[i*2:i*2+2, j*2:j*2+2])
return imD
def estimateLoss(im, way = 1):
_, ax = plt.subplots(nrows=1, ncols=3, figsize=(20, 10))
if way == 1:
a = decrease1(decrease1(im))
elif way == 2:
a = decrease2(decrease1(im))
elif way == 3:
a = decrease3(decrease1(im))
elif way == 4:
a = decrease4(decrease1(im))
else:
print('Error: You should choose way from 1-4')
print(a.shape)
b = cv2.resize(a, (300, 300))
print(b.shape)
ax[0].imshow(im)
ax[0].set_title("Original")
ax[1].imshow(a)
ax[1].set_title("DownSample")
ax[2].imshow(b)
ax[2].set_title("DownSample to UpSample")
loss = content_loss(im, b)
return loss
GFKernel = [[GaussianFilter(-1, 1, 1), GaussianFilter(0, 1, 1), GaussianFilter(1, 1, 1)],
[GaussianFilter(-1, 0, 1), GaussianFilter(0, 0, 1), GaussianFilter(1, 0, 1)],
[GaussianFilter(-1, -1, 1), GaussianFilter(0, -1, 1), GaussianFilter(1, -1, 1)]]
GFKernel = np.array(GFKernel)
print('Delete Even Rows and Columns')
print('loss: ', estimateLoss(im, 1))
print('Using Gassian Filter Then Delete Even Rows and Columns')
print('loss: ', estimateLoss(im, 2))
print('Max Pooling')
print('loss: ', estimateLoss(im, 3))
print('Mean Pooling')
print('loss: ', estimateLoss(im, 4))
结果对比
1、直接删除偶数行列,content loss 为 77.55943333333333
2、使用高斯平滑,然后删去图像偶数行列,content loss 为 91.84892222222223
3、使用最大池化,content loss 为 83.76383333333334
4、使用均值池化,content loss 为 73.81282222222222
Content Loss计算的是像素值差异,因此我们可以估计缩小前后变化像素的多少来预估。第四幅图像的损失最低,这是因为像素值是平均值,并且更接近之前周围的像素值。第二种算法的损失最高,因为它通过加权改变了所有的像素。