关于图像识别:项目

5次阅读

共计 7580 个字符,预计需要花费 19 分钟才能阅读完成。

# 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()
正文完
 0