# date : 2020.3.30
import os
import cv2
import random
import numpy as np
from matplotlib import pyplot as plt
import torch
import torch.nn.functional as F
from train_mnist import Net ## 重要,尽管显示灰色 (即在次代码中没用到),但若没有引入这个模型代码,加载模型时会找不到模型
from torch.autograd import Variable
import pandas as pd
res = {}
# 读取图像
def FourierAddGauss_Blur(img, mu, sigma, k):
# 归一化解决
img = np.array(img / 255, dtype=float)
# 傅里叶变换
f = np.fft.fft2(img)
# print('Fourier Done')
fshift = np.fft.fftshift(f)
print(fshift)
[rows, cols] = fshift.shape
for i in range(0, k):
for j in range(0, k):
# print('before')
# print(fshift[i][j])
f_real = fshift[i][j].real
f_imag = fshift[i][j].imag
f_real += random.gauss(mu, sigma)
fshift[i][j] = f_real + (1j * f_imag)
# print(fshift[i][j])
# print('Add GaussNoise to (0,10) real Done')
res = np.log(np.abs(fshift))
# 傅里叶逆变换
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
# 自适应高斯滤波
out = cv2.GaussianBlur(iimg, (3, 3), 1)
# print('Gaussian Filter Done')
# # 滤波后频率图
# f_out = np.fft.fft2(out)
# fshift_out = np.fft.fftshift(f_out)
# res_out = np.log(np.abs(fshift_out))
# 展现后果
plt.subplot(221), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.subplot(222), plt.imshow(res, 'gray'), plt.title('Fourier Image')
plt.subplot(223), plt.imshow(iimg, 'gray'), plt.title('Inverse Fourier Image')
plt.subplot(224), plt.imshow(out, 'gray'), plt.title('out Image')
# plt.subplot(325), plt.imshow(res_out, 'gray'), plt.title('Out Fourier Image')
plt.show()
return out
def FourierAddGauss_NoBlur(img, mu, var, k):
# 归一化解决
img = np.array(img / 255, dtype=float)
# 傅里叶变换
f = np.fft.fft2(img)
# print('Fourier Done')
fshift = np.fft.fftshift(f)
[rows, cols] = img.shape
f_real = np.zeros(img.shape)
f_imag = np.zeros(img.shape)
for i in range(0, rows):
for j in range(0, cols):
f_real[i][j] = fshift[i][j].real
f_imag[i][j] = fshift[i][j].imag
# 生成高频高斯噪声
noise = np.random.normal(mu, var ** 0.5, img.shape)
for i in range(0, rows):
for j in range(0, cols):
if i > k or j > k:
noise[i][j] = 0
print("noise")
print(noise)
print("f_real")
print(f_real)
# 退出噪声
f_real = f_real + noise
for i in range(0, rows):
for j in range(0, cols):
fshift[i][j] = f_real[i][j] + (1j * f_imag[i][j])
res = np.log(np.abs(fshift))
# 傅里叶逆变换
print("fshift")
print(fshift)
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
iimg = iimg * 255
# 自适应高斯滤波
out = cv2.GaussianBlur(iimg, (3, 3), 1)
# print('Gaussian Filter Done')
# # 滤波后频率图
# f_out = np.fft.fft2(out)
# fshift_out = np.fft.fftshift(f_out)
# res_out = np.log(np.abs(fshift_out))
# 展现后果
plt.subplot(221), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.subplot(222), plt.imshow(res, 'gray'), plt.title('Fourier Image')
plt.subplot(223), plt.imshow(iimg, 'gray'), plt.title('Inverse Fourier Image')
plt.subplot(224), plt.imshow(out, 'gray'), plt.title('out Image')
# plt.subplot(325), plt.imshow(res_out, 'gray'), plt.title('Out Fourier Image')
plt.show()
return out
def train_pngAddGauss(root):
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net()
model.load_state_dict(torch.load('mnist_cnn.pt')) # 加载模型
model = model.to(device)
model.eval() # 把模型转为 test 模式
# root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test'
# root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test_AddGaussion2000_NoFiltering'
# root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test_AddGaussion_NoFiltering'
files_path = os.listdir(root)
print("start testing:...")
for png_name in files_path:
# print(png_name)
img = cv2.imread(root + "/" + png_name, 0)
# print(img.shape)
# img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 图片转为灰度图,因为 mnist 数据集都是灰度图
img = np.array(img).astype(np.float32)
img = np.expand_dims(img, 0)
img = np.expand_dims(img, 0) # 扩大后,为 [1,1,28,28]
img = torch.from_numpy(img)
img = img.to(device)
output = model(Variable(img))
prob = F.softmax(output, dim=1)
prob = Variable(prob)
prob = prob.cpu().numpy() # 用 GPU 的数据训练的模型保留的参数都是 gpu 模式的,要显示则先要转回 cpu,再转回 numpy 模式
# print(prob) # prob 是 10 个分类的概率
pred = np.argmax(prob) # 选出概率最大的一个
res[png_name] = pred.item()
print("train over")
data = pd.read_csv(r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test.csv')
right = 0
for key, val in res.items():
# print(key,val)
if int(data[data['pic_name'] == key]['label']) == val:
right = right + 1
# else:
# print("Actually:" + key, val)
# Wrong_pred = int(data[data['pic_name'] == key]['label'])
# print("Wrong predicted:" + str(Wrong_pred))
acc = right / len(res)
print(acc)
return acc
def gasuss_noise(image, mean=0, var=0.001):
# '''
# 增加高斯噪声
# image: 原始图像
# mean : 均值
# var : 方差, 越大,噪声越大
# '''
image = cv2.imread(image)
image = np.array(image / 255, dtype=float) # 将原始图像的像素值进行归一化,除以 255 使得像素值在 0 - 1 之间
noise = np.random.normal(mean, var ** 0.5, image.shape) # 创立一个均值为 mean,方差为 var 呈高斯分布的图像矩阵
out = image + noise # 将噪声和原始图像进行相加失去加噪后的图像
if out.min() < 0:
low_clip = -1.
else:
low_clip = 0.
out = np.clip(out, low_clip, 1.0) # clip 函数将元素的大小限度在了 low_clip 和 1 之间了,小于的用 low_clip 代替,大于 1 的用 1 代替
out = np.uint8(out * 255) # 解除归一化,乘以 255 将加噪后的图像的像素值复原
# cv.imshow("gasuss", out)
noise = noise * 255
return [noise, out]
def dctAddLowFre(img,mu,var,k):
# 归一化解决
img = np.array(img / 255, dtype=float)
img_dct = cv2.dct(np.float32(img))
# img_dct_log = np.log(abs(img_dct))
# print('img_dct:')
# print(img_dct[0:k, 0:k])
# 生成低频噪声
# 学生成高斯噪声
noise = np.random.normal(mu, var ** 0.5, img.shape) # 创立一个均值为 mu,方差为 var 呈高斯分布的图像矩阵
# 对 GaussionNoise 进行剪裁
for i in range(noise.shape[0]):
for j in range(noise.shape[1]):
if i > k or j > k:
noise[i][j] = 0
# print('noise:')
# print(noise)
# 对 GaussionNoise 进行 IDCT 失去低频噪声
lowFre_noise = np.zeros(img.shape)
lowFre_noise[0:k, 0:k] = cv2.idct(noise[0:k, 0:k])
# print('lowFre_noise:')
# print(lowFre_noise[0:k, 0:k])
# 将 低频噪声 退出 img_dct
img_dct_AddLowFreNoise = img_dct + lowFre_noise
# print('img_dct_AddLowFreNoise')
# print(img_dct_AddLowFreNoise[0:k, 0:k])
# 解除归一化
img_dct_AddLowFreNoise = img_dct_AddLowFreNoise * 255
# 逆离散余弦变换,变换图像回实数域
img_idct = cv2.idct(img_dct_AddLowFreNoise)
img_idct_Blur = cv2.GaussianBlur(img_idct, (3, 3), 1)
# show result
plt.subplot(241), plt.imshow(img, 'gray'), plt.title('Img')
plt.subplot(242), plt.imshow(noise, 'gray'), plt.title('Gaussion Noise')
plt.subplot(243), plt.imshow(lowFre_noise, 'gray'), plt.title('Low Frequency Noise')
plt.subplot(244), plt.imshow(img_dct, 'gray'), plt.title('Img_dct')
plt.subplot(245), plt.imshow(img_dct_AddLowFreNoise, 'gray'), plt.title('Img_dct_AddLowFreNoise')
plt.subplot(246), plt.imshow(img_idct, 'gray'), plt.title('IDCT Image')
plt.subplot(247), plt.imshow(img_idct_Blur, 'gray'), plt.title('IDCT-Blur Image')
plt.show()
return img_idct
def train_pngAddLowFre(root,root_out,mu,var,k):
files_path = os.listdir(root)
for png_name in files_path:
img = cv2.imread(root + "/" + png_name, 0)
out = dctAddLowFre(img, mu, var, k)
cv2.imwrite(root_out + "/" + png_name, out)
train_pngAddGauss(root_out)
def main():
# # test
# root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test'
# root_out = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test_AddGaussion_NoFiltering'
#
# # # train
# # root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\training\train'
# # root_out = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\training\train_AddGuassion4000_Filtering'
#
# files_path = os.listdir(root)
#
# array = [100,200,500,1000,1200,1500,2000,2500,3000,3500,4000,4500,5000]
# array2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# k = 28
# for sigma in array2:
# for png_name in files_path:
# img = cv2.imread(root + "/" + png_name, 0)
# # out = FourierAddGauss_Blur(img, 0, sigma, k)
# out = FourierAddGauss_NoBlur(img, 0, sigma, k)
# cv2.imwrite(root_out + "/" + png_name, out)
#
# print(sigma)
# train_pngAddGauss(root_out)
#单张图片测试
img = cv2.imread(r'D:\PythonProjects\Fourier\0.png',0) #第一个参数是文件门路,可本人批改
out = FourierAddGauss_NoBlur(img, 0, 50, 10)
# # 单张图片测试
# # 离散余弦变换 并获取其幅频谱
# img = cv2.imread(r'D:\PythonProjects\Fourier\0.png', 0)
# img_addLowFre = dctAddLowFre(img, 0, 0.1, 10)
# # 数据集测试
# root = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test'
# root_out = r'D:\PythonProjects\Fourier\mnist_png_all_files_with_traincsv\testing\test_AddLowFre'
# mu = 0
# array_var = [0, 0.01, 0.02, 0.05, 0.1]
# array_var2 = [0.6, 0.7, 0.8, 0.9, 1]
# k = 10
#
# for var in array_var2:
# print(var)
# train_pngAddLowFre(root, root_out, mu, var, k)
if __name__ == '__main__': main()