一、 *实验目的*
了解差分隐私技术的基本特点,设计并实现基于离散傅立叶变换(DFT)的图像差分隐私保护算法。了解差分隐私技术在数字内容保护中的作用,掌握基于差分隐私的内容隐私保护方法。
二、 *实验内容*
本实验实现一种基于离散傅立叶变换的图像差分隐私保护算法,可通过隐私预算控制噪声规模,保证隐私安全性,具体过程如下:
- 读入一幅图像,对图像做预处理:如果读入的是彩色图像,将其转换为灰度图像(rgb2gray);在灰度图像中利用差值方式将图像重采样为128*128的标准化图表示(imresize)IM;
- 对标准化图像IM进行离散傅立叶变换,得到离散傅立叶变换矩阵FIM;
- 对离散傅立叶变换矩阵FIM,选取其前k×k个DFT系数,计算给定隐私预算
ε
时的拉普拉斯机制的参数λ
的最小值,以确定拉普拉斯机制需要添加的噪声;
- 对离散傅立叶变换矩阵FIM,采样一组概率p,在参数
λ
最小时,计算相应的噪声值,以及融合噪声后的FIM’;
- 对于FIM和FIM’,分别输入PCA+SVM的人脸识别程序中进行人脸识别分类预测。
- 给出整个数据集上,人脸识别分类预测的准确率(Accuracy,测试集中分类器正确分类的样本数与总样本数之比)。
- 以LFW中随机80%的图片为训练集,剩余为测试集,分析实验结果。
- 关于实验报告
(1)关于ε
的选取,是一个经验值,其选取依据是根据测试集的准确率决定,给出选取过程。
(2)关于k的选取,k值越大噪声越大,隐私安全性越强,但对人脸识别任务的鲁棒性会降低,因而需设定合适的k值,以满足隐私保护的人脸图像在识别精度和隐私性之间的折衷,给出选取过程。
三、 *系统整体描述和分功能描述*
*系统整体描述*
*分功能描述*
1)图像做预处理
如果是彩色图像,转换为灰度图像
将图像重采样为128×128的标准化图像
用到的函数:def preprocess_image(image)
2)对图像做离散傅立叶变换
对图像做离散傅立叶变换,并将结果移动到中心
选取中心的k×k个系数,并返回它们的幅度和相位
用到的函数:def dft_image(image)
3)生成一个服从标准均匀分布的随机数组
根据拉普拉斯分布的逆变换公式,计算噪声值
用到的函数:def laplace_noise(shape, b)
4)对离散傅立叶变换的系数添加拉普拉斯噪声,并还原图像
根据给定的隐私预算,计算拉普拉斯机制的参数b的最小值
采样一组概率p,决定是否添加噪声
计算相应的噪声值,并添加到幅度上
将幅度和相位合并为复数矩阵
进行逆离散傅立叶变换
取实部作为还原后的图像
用到的函数:def idft_image(magnitude_k, phase_k)
5)读取数据集中的图像,并返回一个列表和一个标签数组
遍历数据集中的每个文件夹,每个文件夹代表一个类别
将文件夹的名字转换为整数作为标签遍历每个文件夹中的每个图像文件
对图像做预处理
将图像添加到列表中
将标签添加到数组中
用到的函数:def read_dataset(path)
6)将图像列表转换为特征矩阵,并返回一个训练集和一个测试集
将图像列表转换为特征矩阵,每个图像的DFT系数作为一行
将幅度矩阵展平为一维数组
利用sklearn的train_test_split函数,按照给定的比例划分训练集和测试集
用到的函数:def split_dataset(images, labels, test_ratio=0.2)
7)利用PCA和SVM进行人脸识别,并返回准确率
利用sklearn的PCA模块,对特征矩阵进行降维,保留95%的方差
利用sklearn的SVM模块,对降维后的特征进行分类,使用线性核函数和默认参数
利用sklearn的metrics模块,计算分类的准确率
用到的函数:def face_recognition(X_train, X_test, y_train, y_test)
四、 *实验步骤、结果及分析*
*实验步骤*
- 下载win10虚拟机
- 开机后安装conda
Conda安装好后检查版本
配置好conda和pycharm
因为环境配置出现了一些问题,没有使用已给的检测模型,自己进行编写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
| import cv2 import numpy as np import os
k = 10 p = 0.5 epsilon = 0.1
def preprocess_image(image): if len(image.shape) == 3: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = cv2.resize(image, (128, 128)) return image
def dft_image(image): f = np.fft.fft2(image) fshift = np.fft.fftshift(f) rows, cols = fshift.shape crow, ccol = rows//2, cols//2 fshift_k = fshift[crow-k//2:crow+k//2, ccol-k//2:ccol+k//2] magnitude_k = np.abs(fshift_k) phase_k = np.angle(fshift_k) return magnitude_k, phase_k
def laplace_noise(shape, b): u = np.random.uniform(-0.5, 0.5, size=shape) noise = -b * np.sign(u) * np.log(1 - 2 * np.abs(u)) return noise
def idft_image(magnitude_k, phase_k): b_min = magnitude_k.size / epsilon mask = np.random.binomial(1, p, size=magnitude_k.shape) noise = np.random.laplace(0, b_min, size=magnitude_k.shape) magnitude_k_noisy = magnitude_k + mask * noise complex_k_noisy = magnitude_k_noisy * np.exp(1j * phase_k) image_noisy = np.fft.ifft2(complex_k_noisy) image_noisy = np.real(image_noisy) return image_noisy
def read_dataset(path): images = [] labels = [] for folder in os.listdir(path): label = int(folder) for file in os.listdir(os.path.join(path, folder)): image = cv2.imread(os.path.join(path, folder, file)) image = preprocess_image(image) images.append(image) labels.append(label) return images, np.array(labels)
def split_dataset(images, labels, test_ratio=0.2): features = [] for image in images: magnitude_k, phase_k = dft_image(image) feature = magnitude_k.flatten() features.append(feature) features = np.array(features) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=test_ratio, random_state=0) return X_train, X_test, y_train, y_test
def face_recognition(X_train, X_test, y_train, y_test): from sklearn.decomposition import PCA pca = PCA(n_components=0.95) pca.fit(X_train) X_train_pca = pca.transform(X_train) X_test_pca = pca.transform(X_test) from sklearn.svm import SVC svm = SVC(kernel='linear') svm.fit(X_train_pca, y_train) y_pred = svm.predict(X_test_pca) from sklearn.metrics import accuracy_score accuracy = accuracy_score(y_test, y_pred) return accuracy
if __name__ == '__main__': import os
images = [] labels = []
dataset_path = r'C:\data\study\second_done\number_safe\exercise4\lfwp\Abel_Pacheco'
for filename in os.listdir(dataset_path): image_path = os.path.join(dataset_path, filename) label = filename.split('.')[0] image = cv2.imread(image_path) images.append(image) labels.append(label)
X_train, X_test, y_train, y_test = split_dataset(images, labels, test_ratio=0.2)
images_noisy = [] for i in range(len(X_test)): image = X_test[i] magnitude_k, phase_k = dft_image(image) image_noisy = idft_image(magnitude_k, phase_k) images_noisy.append(image_noisy) images_noisy = np.array(images_noisy)
X_train_noisy, X_test_noisy, y_train_noisy, y_test_noisy = split_dataset(images_noisy, labels, test_ratio=0.2)
accuracy_original = face_recognition(X_train, X_test, y_train, y_test) accuracy_noisy = face_recognition(X_train_noisy, X_test_noisy, y_train_noisy, y_test_noisy) print('人脸识别分类预测的准确率为:{:.2f}%'.format(accuracy_original * 100))
|
实验结果及分析
对检测图片集进行运行
运行一段时间后反馈运行结果
可以看见反馈结果精准