BCI-DCT-watermark
介绍
对脑机数据进行水印嵌入、提取、攻击等操作。
本项目提供了几个传统鲁棒水印嵌入的baseline方法对脑电数据进行水印嵌入以及提取和水印质量检测的工作,同时也提出了基于DWT-DCT的水印嵌入算法模型框架。
参考北京邮电大学的杨瑜老师的教科书《信息隐藏与数字水印》进行python的代码实现基于小波变换的EEGNet的水印嵌入。
研究背景及意义
脑机接口技术
脑机接口(Brain-Computer Interface, BCI)技术近年来取得了显著的进步,它为人类与机器之间建立了直接的通信通道。随着这一技术的应用范围不断扩大,从医疗健康到人机交互等领域都展现出了巨大的潜力然而,随之而来的数据安全问题也日益凸显。脑机数据不仅包含了个体的生理信息,还可能涉及用户的隐私、习惯甚至思维模式,因此确保这些数据的安全性和完整性至关重要。
数字水印技术介绍
数字水印技术作为一种有效的数据保护手段,在多媒体领域已有广泛应用。它通过在原始数据中嵌入不可见或难以察觉的信息标记,来实现对数据所有权的声明、完整性的验证等功能。将数字水印技术应用于脑机数据保护是一个新兴且具有挑战性的研究方向。这种应用能够为脑机数据提供额外的安全保障,防止未经授权的篡改或滥用。 将脑机数据与数字水印结合结合将有着进一步的现实意义。通过对敏感的脑机数据进行加密和水印处理,可以有效防止个人信息泄露,在医疗和法律等应用场景中,确保脑机数据不被恶意修改对于维护公正性至关重要。
促进技术发展:推动脑机接口技术的安全标准建设,为该领域的持续健康发展奠定基础,同时也提升用户对脑机接口产品的信任度,有助于加速这些技术的商业化进程和社会接受度。
综上所述,研究脑机数据中的数字水印技术不仅是学术上的前沿探索,也是实际应用中的迫切需求,对于构建更加安全可靠的脑机接口生态系统具有重要意义。
数字水印研究现状
目前研究最多的是图像水印,其在外观上可以分为两种类型:可见水印和不可见水印。可见水印是可以直接在媒体上看到的水印,即肉眼可以直接识别的水印,也是可用于验证所有者的可见纸质水印。数字水印技术有助于证明所有权,因为它将证据集成到数据中,以代表数据的合法用户。不可见水印现在是一个广泛使用的水印。它被添加到数据中,人眼很难找到,但如果需要验证,可以提取标签以证明所有者。例如,如果图像中包含不可见的水印,则在编辑和分发图像之前可以识别图像水印,并且下一个过程可能会在发现结束时继续。数据的所有者可以通过整合其他水印信息来实现复制和分发图像的目标。根据强度,它可以分为脆弱水印和鲁棒水印。
当数字媒体信息的视觉和听觉质量得到保证时,所谓的脆弱水印被设置为直接将与多媒体内容相关或与多媒体内容相关的标志信息直接与水印集成。这是一个认证水印。在必须验证媒体内容时,可以提供水印来确定它的真实性和完整性。鲁棒水印确保在发生有意或无意的处理或攻击时,确认版权的信息将始终被检测调用。
根据嵌入域是划分标准,可以分为两类:空间域和变换域。其中,空间域水印主要通过略微改变介质的数字大小来整合水印,具有计算机复杂度低、操作效率高的优点。它适用于时间要求高,但该算法的可靠性有限。使用变换域水印。一些信号转换对应于具有转换系数的图像中的像素,然后输入有关水印的信息。与空间域水印算法相比,该算法大大提高了可靠性,但计算复杂性通常更高,操作时间更长。
现有的变换域算法一般都利用奇异值分解、离散傅里叶变换、离散余弦变换、离散小波变换 等数学变换方法对载体图像和水印图像进行处理,从而实现水印的嵌入,并达到图像水印算法的基本设计需求。这些变换方法各有优缺点,离散小波变换拥有优秀的空间定位和多分辨率的特性,这个特性与人类视觉系统(Human visual system,HVS)的特性具有很强的相关性,因为其变换是通过不同的滤波器进行的分层分
级进行的。离散余弦变换则具有很强的去相关特性,能将利用变换的能量特性提高算法性能的鲁棒性。 奇异值分解的一个重要特性就是对奇异值的微小变化不会影响图像的视觉感知。但是基于单一的变换域水印算法在不可见性和抗攻击能力的鲁棒性方面还有很大的提升空间。
相关知识介绍
DWT离散小波变换
离散小波变换(Discrete Wavelet Transform,DWT)可以有效地提取信号中的频率特征,并且可以有效地抑制噪声。因此,离散小波变换可以用于信号处理,可以有效地提取数据中的纹理特征,从而提高数据处理的效率。二维离散小波分解过程如图所示。分解过程中还可以根据需要对得到的水平和垂直方向的低频分量(LL 子带)进行进一步的小波分解,直至达到要求。
一般情况下就图像的四个子带而言,水平方向低频分量和垂直方向高频分量(LH 子带)、水平方向高频分量和垂直方向低频分量(HL 子带)、水平和垂直方向高频分量(HH 子带)则展现了原始图像的边缘、轮廓和纹理细节等特征,这些子带则更容易受到攻击。因此一般选用保留细节部分的 LL自带进行水印的嵌入
四个子带的显示
三次的DWT四个子带的可视化,
LL (Low-Low): 近似子带,包含了图像的低频部分,即图像的基本结构或轮廓。
LH (Low-High): 水平方向的细节子带,捕捉图像中的水平边缘或纹理。
HL (High-Low): 垂直方向的细节子带,捕捉图像中的垂直边缘或纹理。
HH (High-High): 对角方向的细节子带,捕捉图像中的对角边缘或纹理。
但是针对于EEG的数据没有所谓的边缘与纹理,可以将水印都嵌入到其中的四个子带,目前的大部分图像水印都是嵌入到LL子带中在对于
DCT离散余弦变换
离散余弦变换是一种线性变换,可以将一个信号从时域转换到频域,从而实现信号的压缩和滤波。基本原理是,将一个信号分解成一组正交函数的线性组合,这组正交函数称为离散余弦基(Discrete Cosine Basis),然后将这组正交函数的系数进行滤波。从而消除信号中的噪声,减少数据的存储空间。离散余弦变换的应用非常广泛,它可以用于图像处理、声音处理、视频处理等领域。
DCT的相关物理特性
DCT可以被视为一种频谱分析工具,它将信号分解成 一系列不同频率的余弦波的组合。与傅里叶变换类似,DCT 提供了一种将时域信号转换为频域表示的方法,但与傅里叶变换不同的是,DCT 只使用实数表示,因此计算更简单。 同时能够将信号的能量集中在较低频率的系数上。这意味着对于大多数自然信号来说,经过 DCT 变换之后,大部分能量都集中在前几个系数上,而后面的系数则接近于零。这种特性使得 DCT 成为了数据压缩的理想选择,因为可以舍去高频部分的系数而不损失太多信号质量。
希尔伯特变换(hilbert)
希尔伯特变换是通信中用于将实信号转换为复信号的工具,便于信号处理。它将正负频率分别相移Π/2,实现单边带化,简化分析并节省计算资源。希尔伯特变换在处理实信号时,将其转换为复信号,通过IQ解调获取幅度和相位信息。这对于窄带调频波和调幅波的分析至关重要,尤其在降低采样频率需求和提高信号处理效率方面具有重要意义。
瞬时幅度和相位:希尔伯特变换生成的解析信号包含了瞬时幅度和瞬时相位信息,这些信息对于水印嵌入来说非常有用。瞬时幅度可以反映信号在某一时点的强度,而瞬时相位则提供了信号在该时刻的相位信息。这些特性可以用来选择信号中的最佳嵌入位置,比如选择瞬时幅度较高且相位变化较小的地方嵌入水印,这样可以提高水印的不可见性和鲁棒性。
希尔伯特变换在水印嵌入的缺陷
边界效应: 希尔伯特变换可能会在信号的开始和结束处产生边界效应,这可能会影响到水印的嵌入和提取。非线性操作: 希尔伯特变换是非线性操作,它可能会改变信号的某些特性,导致水印提取困难
伪随机数据
AES-256 以及 OFB分组密码
AES-256 加密算法将会生成32字节的密钥,进行生成密钥,OFB是一个反馈的生成随机伪序列的算法,可以生成一个伪随机序列,这个序列通常用于流加密。
AES-256 加密算法
AES-256 是一种对称加密算法,意味着加密和解密使用相同的密钥。AES-256 使用 256 位的密钥长度,提供了较高的安全性。
加密过程概述:
密钥扩展:从原始的 256 位密钥扩展出一系列子密钥。
初始轮:明文与第一个子密钥进行异或操作。
主循环:多轮包含 SubBytes, ShiftRows, MixColumns, AddRoundKey 的操作。
最终轮:SubBytes, ShiftRows, AddRoundKey。
OFB 模式
OFB 模式是一种分组密码的工作模式,它将块密码转换为流密码。OFB 模式的特性是输出反馈,这意味着它
通过将前一个密文块的输出作为下一次加密的输入来产生一个连续的伪随机序列。
初始化向量 (IV):选择一个任意的初始向量(通常是一个随机数)。
生成密钥流:使用 IV 和 AES-256 密钥加密产生第一个密钥流块。
加密数据:将明文与密钥流进行逐比特的异或操作。
更新密钥流:将产生的密钥流块再次作为输入,使用相同的密钥进行 AES-256 加密,生成新的密钥流块。
重复步骤 3 和 4:直到所有的数据都被加密完成。
实验数据介绍
脑电信号 (EEG) 使用Synamps2系统(Neuroscan公司)采集,采样率为1000 Hz。放大器的频率通带范围从0.15 Hz到200 Hz。64个电极覆盖了参与者的整个头皮,并按照国际10-20系统排列。接地电极位于Fz和FPz之间的中点位置。参考电极位于头顶。电极阻抗保持在10kΩ下。为了去除常见的50 Hz电力线噪声,在数据记录过程中应用了一个50 Hz的陷波滤波器。由计算机生成并记录在事件通道上的事件触发与EEG数据同步。
清华脑机数据SSVEP集是一组记录了35名健康参与者(17名女性,年龄17至34岁)在进行基于稳态视觉诱发电位(Steady-State Visual Evoked Potential, SSVEP)的脑机接口实验时的数据。每位参与者面对40个以不同频率闪烁的字符,进行了6轮实验,每轮包含40次试验。使用Synamps2系统以1000 Hz的采样率采集脑电信号,数据被处理并存储为MATLAB文件,用于后续分析。参与者被分为有经验与新手组。
评价水印的嵌入质量的指标
PSNR 峰值信噪比
PSNR 是衡量两个图像之间的差异的一种指标,通常用于量化图像压缩中的失真程度。它基于均方误差 (MSE)
def calculate_psnr(img1, img2, max_pixel_value=200):
"""
计算两个图像之间的峰值信噪比 (PSNR)。
参数:
img1 : numpy.ndarray
第一个图像,通常是原始图像。
img2 : numpy.ndarray
第二个图像,通常是含有水印的图像。
max_pixel_value : float
图像中像素的最大可能值,默认为 255 对于 8 位图像。
返回:
float
PSNR 值。
"""
# 计算均方误差 (MSE)
mse = np.mean((img1 - img2) ** 2)
if mse == 0:
# 如果 MSE 为 0,则表示两个图像完全相同
return float('inf')
# 根据 PSNR 公式计算 PSNR
psnr = 20 * np.log10(max_pixel_value / np.sqrt(mse))
return psnr
SSIM系数
虽然 SSIM 主要用于二维图像的相似性度量,理论上也可以扩展到一维信号的情况。然而,需要注意的是,一维信号通常不具备二维图像所具有的结构信息,因此直接应用 SSIM 可能并不合适。不过,我们可以尝试模拟 SSIM 的思想来衡量一维信号的相似性。
一维信号的 SSIM 模拟实现 为了模拟 SSIM 在一维信号中的应用,我们可以采用类似的计算方法,但需要注意的是,这种方法并不是严格意义上的 SSIM,而是借鉴其思想来衡量一维信号的相似性。
def calculate_ssim_for_1d(signal1, signal2, k1=0.01, k2=0.03, dynamic_range=1.0):
"""
计算两个一维信号之间的 SSIM 值。
参数:
signal1 : numpy.ndarray
第一个一维信号。
signal2 : numpy.ndarray
第二个一维信号。
k1 : float
SSIM 公式中的常数。
k2 : float
SSIM 公式中的常数。
dynamic_range : float
信号值的动态范围,默认为 1.0。
返回:
float
SSIM 值。
"""
# 确保信号长度相同
assert len(signal1) == len(signal2), "Signals must have the same length."
# 计算平均值
mu1 = np.mean(signal1)
mu2 = np.mean(signal2)
# 计算方差
sigma1 = np.var(signal1)
sigma2 = np.var(signal2)
# 计算协方差
sigma12 = np.cov(signal1, signal2)[0, 1]
# 计算 SSIM
c1 = (k1 * dynamic_range) ** 2
c2 = (k2 * dynamic_range) ** 2
numerator = (2 * mu1 * mu2 + c1) * (2 * sigma12 + c2)
denominator = (mu1 ** 2 + mu2 ** 2 + c1) * (sigma1 + sigma2 + c2)
ssim_value = numerator / denominator
return ssim_value
NCC归一化互相关系数
NCC系数的特点
尺度无关性:NCC能够消除信号之间的尺度差异。;平移不变性:NCC不受信号平移的影响。 ;旋转和缩放:对于一维信号而言,旋转和平移的概念不适用,但NCC仍然可以处理信号的缩放问题。
NCC系数可以用来评估一维数据中水印嵌入的质量。一个好的水印应该能够在不影响原始信号质量的情况下保持其完整性和鲁棒性。因此,一个较高的NCC值意味着原始信号和嵌入水印后的信号非常相似,即水印嵌入对信号的影响较小。
def calculate_ncc(x, y):
"""
计算两个一维信号之间的归一化互相关系数。
"""
# 确保信号长度相同
assert len(x) == len(y), "Signals must have the same length."
# 计算均值
mean_x = np.mean(x)
mean_y = np.mean(y)
# 计算偏差
deviation_x = x - mean_x
deviation_y = y - mean_y
# 计算分子
numerator = np.sum(deviation_x * deviation_y)
# 计算分母
denominator = np.sqrt(np.sum(deviation_x ** 2)) * np.sqrt(np.sum(deviation_y ** 2))
# 避免除以零
if denominator == 0:
return 0
# 返回NCC值
return numerator / denominator
KCD系数
假设KCD系数(Kernel Correlation Distance)是基于核函数的相似性度量,它通过计算两个信号在高维空间中的相关性来衡量它们的相似度。这里我们简单地将其视为与NCC相同的度量方法。系数接近1的水印的嵌入的质量就高
def calculate_kcd(original_signal, watermarked_signal):
"""
计算两个一维信号之间的KCD系数(假设为NCC)。
"""
# 确保信号长度相同
assert len(original_signal) == len(watermarked_signal), "Signals must have the same length."
# 计算均值
mean_original = np.mean(original_signal)
mean_watermarked = np.mean(watermarked_signal)
# 计算偏差
deviation_original = original_signal - mean_original
deviation_watermarked = watermarked_signal - mean_watermarked
# 计算分子
numerator = np.sum(deviation_original * deviation_watermarked)
# 计算分母
denominator = np.sqrt(np.sum(deviation_original ** 2)) * np.sqrt(np.sum(deviation_watermarked ** 2))
# 避免除以零
if denominator == 0:
return 0
# 返回KCD值
return numerator / denominator
JSD系数
JSD(Jensen-Shannon Divergence,詹森-香农散度)是一种衡量两个概率分布之间差异的统计量。在水印技术中,如果我们想要量化嵌入水印后数据的概率分布与原始数据的概率分布之间的相似性,JSD可以作为一个有用的度量标准.相似度小于0.1的相似度较高
def jensen_shannon_divergence(p, q):
"""
计算两个概率分布p和q之间的JSD。
"""
m = 0.5 * (p + q)
return 0.5 * entropy(p, m) + 0.5 * entropy(q, m)
def signal_to_distribution(signal):
"""
将信号转换为概率分布。
"""
min_val = np.min(signal)
max_val = np.max(signal)
bins = np.linspace(min_val, max_val, num=100)
hist, _ = np.histogram(signal, bins=bins, density=True)
return hist
def calculate_jsd(original_signal, watermarked_signal):
"""
计算原始信号和嵌入水印后信号之间的JSD。
"""
p = signal_to_distribution(original_signal)
q = signal_to_distribution(watermarked_signal)
return jensen_shannon_divergence(p, q)
水印模块
水印嵌入算法
各个py文件的解释
util文件
AES.py
这些函数共同实现了一个基于作者信息和时间戳生成伪随机数序列的过程。具体来说:
generate_random_sequence: 使用作者名称经过哈希处理后的结果与当前时间戳的组合来初始化Python的标准随机数生成器,进而生成一个包含500个浮点数的随机序列。
generate_key: 根据作者信息和时间戳生成一个用于AES-256加密的32字节密钥。这里使用SHA-256哈希函数对作者信息和时间戳的组合进行哈希处理,并截取前32字节作为密钥。
generate_prng_sequence: 利用给定的密钥和初始向量(IV)通过AES-256算法的输出反馈模式(OFB)生成指定长度的伪随机数序列。每次加密一个128位(16字节)的数据块,直到达到所需的序列长度。
DCT.py
这段代码定义了一个名为 DCT 的类,用于实现离散余弦变换 (DCT) 方法来嵌入和检测水印。具体功能包括:
水印嵌入 (water_in 方法): 使用DCT将水印信号嵌入到原始信号(如音频或脑电图EEG数据)中。水印信号被嵌入到原始信号的DCT系数中,并通过调整系数值来反映水印的存在。
水印检测 (is_water 方法): 从带有水印的信号中提取水印,并计算提取出的水印与原始水印之间的相关性,以此评估水印的保真度。
此外,还定义了一个辅助函数 plot_eeg 用于绘制EEG数据的波形图。
DWT.py
这段代码定义了一个名为 DWT 的类,用于实现离散小波变换 (DWT) 方法来嵌入和检测水印。它使用小波变换将水印信号嵌入到原始信号(如脑电图 EEG
数据)中,并能从带有水印的信号中提取水印并计算提取出的水印与原始水印之间的相关性。
主要功能包括:水印嵌入 (water_in 方法): 使用 DWT 将水印信号嵌入到原始信号的细节系数中,通过调整选定系数的值来反映水印的存在。
水印检测 (is_water 方法): 从带有水印的信号中提取水印,并计算提取出的
水印与原始水之间的相关性,以此评估水印的保真度。
QUA.py
这段代码定义了一系列函数,用于评估两个信号(如图像或一维信号如脑电图EEG数据)的质量和相似度。主要包括以下几种度量:
峰值信噪比 (PSNR): 用于衡量两个图像之间的差异程度,通常用于评估图像压缩或处理过程的质量损失。
结构相似性指数 (SSIM): 用于评估两个一维信号之间的相似度,特别适用于评估信号处理后的保真度。
归一化互相关系数 (NCC): 用于衡量两个信号之间的线性相关性,通常用于信号匹配或别任务。
KCD系数: 在此上下文中,KCD系数被假定为NCC,用于评估信号的相似度。
Jensen-Shannon Divergence (JSD): 用于比较两个信号的概率分布之
间的差异,适用于评估信号处理前后概率特征的变化
test.py
实现main函数的测试函数
实验结果展示
不可见性测试
PSNR
<![if supportMisalignedColumns]> <![endif]>1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
ues_1 | 29.61 | 35.29 | 32.73 | 33.32 | 34.54 | 35.39 | 35.11 | 34.90 | 35.19 |
ues_2 | 29.83 | 37.11 | 34.24 | 34.42 | 35.55 | 37.27 | 36.76 | 36.58 | 37.25 |
ues_3 | 30.28 | 36.31 | 33.42 | 34.65 | 36.66 | 38.93 | 37.14 | 37.15 | 38.23 |
ues_4 | 30.17 | 35.10 | 32.47 | 33.44 | 34.92 | 37.23 | 35.26 | 35.29 | 36.51 |
ues_5 | 29.57 | 36.66 | 33.84 | 34.61 | 35.88 | 37.63 | 36.90 | 36.88 | 37.34 |
ues_6 | 31.30 | 37.44 | 34.39 | 35.11 | 36.43 | 38.05 | 37.37 | 37.36 | 38.04 |
ues_7 | 35.99 | 39.62 | 38.74 | 38.12 | 40.03 | 40.23 | 38.04 | 37.80 | 38.93 |
ues_8 | 35.53 | 39.93 | 39.25 | 36.87 | 38.37 | 38.50 | 38.27 | 37.75 | 38.58 |
ues_9 | 33.71 | 37.53 | 36.79 | 35.63 | 36.29 | 36.36 | 36.44 | 36.34 | 37.06 |
ues_10 | 34.84 | 40.05 | 38.58 | 36.86 | 39.44 | 39.59 | 39.47 | 38.68 | 39.85 |
ues_11 | 34.27 | 38.72 | 37.50 | 36.66 | 37.99 | 38.20 | 38.67 | 38.34 | 38.08 |
ues_12 | 33.42 | 38.74 | 38.05 | 35.01 | 37.53 | 37.61 | 36.80 | 36.31 | 37.28 |
ues_13 | 29.48 | 34.21 | 34.20 | 33.57 | 35.37 | 35.38 | 35.89 | 36.47 | 35.52 |
ues_14 | 27.44 | 32.82 | 32.90 | 31.72 | 35.24 | 35.25 | 35.06 | 35.59 | 35.39 |
ues_15 | 26.05 | 32.41 | 32.41 | 30.45 | 34.04 | 34.03 | 34.66 | 35.16 | 34.12 |
ues_16 | 28.29 | 34.27 | 34.23 | 32.50 | 35.41 | 35.46 | 35.79 | 36.42 | 35.62 |
ues_17 | 27.65 | 33.84 | 33.86 | 31.74 | 35.57 | 35.49 | 35.54 | 36.68 | 35.74 |
ues_18 | 26.75 | 32.47 | 32.48 | 30.58 | 34.38 | 34.37 | 34.17 | 34.99 | 34.54 |
ues_19 | 28.85 | 33.73 | 33.71 | 33.64 | 33.27 | 33.27 | 35.84 | 35.75 | 35.50 |
ues_20 | 30.18 | 34.12 | 34.09 | 35.52 | 35.74 | 35.71 | 34.76 | 37.38 | 39.41 |
PSNR值越大,意味着重建图像与原始图像越接近,图像质量越好。一般来说,PSNR值在30 dB以上时,人眼很难察觉到重建图像与原始图像之间的区别。由下图看,PSNR值在大部分的通道上在35 dB以上的结果表明算法在数据处理方面表现出色,能够产生高质量的输出
SSIM
NCC
KCD
JSD
水印提取相似度测试
未来展望
由于传统的鲁棒嵌入水印方法对于脑电数据的嵌入在频域中,而且脑电的数据需要利用才有实际的价值,科可以提供扩散模型等生成模型,生成与拥护者脑电相同的数字指纹,在特定的额使用场景中可以充当水印的效果,不仅仅停留在传统的鲁棒水印的阶段。
若技术存在问题或有好的建议,请联系我
邮箱2916600479@qq.com
相关图片如有侵权或者需要相关源码请联系我