1. 项目概述当光学加密遇上数字实现最近在整理一些图像处理的老项目翻到了一个挺有意思的玩意儿基于双随机相位结构和菲涅尔变换的图像加密。这玩意儿听起来有点“光学玄学”但用Matlab实现起来其实是一套非常精妙且实用的数字图像加密方案。它最早脱胎于光学信息处理领域核心思想是模拟光波在自由空间传播时的衍射效应来打乱图像信息再结合随机相位板引入的“密钥”从而实现高强度的加密。现在很多研究者把它纯数字化用Matlab来仿真整个光学过程既保留了其理论上的高安全性又具备了软件实现的灵活性和可重复性。简单来说这个项目就是给你一张明文图像比如一张照片你通过一套包含菲涅尔衍射和随机相位调制的算法把它变成一堆看起来像白噪声的、完全无法识别的密文图像。解密时只有持有正确“密钥”即特定的随机相位分布和系统参数的人才能通过逆过程完美地恢复出原图。它特别适合那些对安全性要求高又希望加密过程具备一定物理意义或抗攻击特性的场景比如医学影像的隐私保护、遥感图像的保密传输或者数字水印的底层嵌入。对于想入门图像加密或者对光学与数字信号处理交叉领域感兴趣的朋友来说这个项目是个绝佳的练手材料。它不单单是调用几个加密函数而是需要你真正理解菲涅尔变换的物理意义、随机相位的作用以及如何用离散的数学计算来模拟连续的物理过程。接下来我就结合源码把这套方案的里里外外、实操细节以及我踩过的坑给大家掰开揉碎了讲清楚。2. 核心原理拆解光学的“锁”与数字的“钥”要搞懂这个加密系统得先明白它的两大支柱双随机相位编码和菲涅尔变换。它们一个负责引入密钥一个负责提供变换域共同构成了加密的基石。2.1 双随机相位编码信息打乱的“搅拌机”双随机相位编码是这套方案安全性的核心。它的想法非常直观在图像的傅里叶域频率域和空间域分别放置两块随机相位板。第一块相位板输入面对原始的明文图像进行相位调制。假设明文图像是f(x, y)第一块随机相位板是exp[j * n1(x, y)]其中n1(x, y)是在区间[0, 2π]上均匀分布的随机数。调制后得到f(x, y) * exp[j * n1(x, y)]。这一步相当于给图像的每个像素点附加了一个随机的相位延迟破坏了图像原有的空间相关性。第二块相位板傅里叶面对经过一次傅里叶变换后的信号进行第二次相位调制。将上一步的结果进行傅里叶变换得到F(u, v)然后用第二块随机相位板exp[j * n2(u, v)]进行调制得到F(u, v) * exp[j * n2(u, v)]。n2(u, v)是另一组独立的[0, 2π]均匀分布随机数。这一步是在频率域进行二次搅拌使得图像的频谱信息也变得杂乱无章。为什么是“相位”而不是“振幅”这是关键。如果直接对图像的振幅即像素亮度值加随机数会明显改变图像的视觉效果可能引入无法消除的噪声。而相位调制在视觉上如果只取振幅可能变化不大但它彻底改变了光波或信号的波前结构。在解密时只要拥有完全相同的相位板密钥通过共轭相位进行补偿就能完美抵消这些随机扰动恢复原始信息。振幅密钥则很难做到无损恢复。这两块随机相位板n1和n2就是整个系统的密钥。它们的统计特性均匀分布和巨大的密钥空间对于一个N×N的图像密钥量级是(2π)^(2*N^2)使得暴力破解几乎不可能。2.2 菲涅尔变换引入物理参数的“变换域”传统的双随机相位编码通常在傅里叶变换域进行。而这个项目的特色在于它用菲涅尔变换替代了标准的傅里叶变换。菲涅尔变换描述的是光波在自由空间中近距离传播时的衍射效应。它与傅里叶变换最大的区别在于菲涅尔变换的结果依赖于传播距离z和光波长λ。其数学表达式是一个卷积形式Uz(x, y) (exp(jkz) / (jλz)) * exp[jπ/(λz) * (x^2 y^2)] * [U0(x, y) * exp[jπ/(λz) * (x^2 y^2)]]其中*表示卷积U0是输入光场Uz是传播距离z后的光场k2π/λ。在数字实现中我们利用菲涅尔变换的卷积性质通过两次快速傅里叶变换来高效计算Uz IFFT2( FFT2(U0 .* Q1) .* H )这里Q1 exp[jπ/(λz) * (x^2 y^2)]是输入面的二次相位因子H是传递函数。引入菲涅尔变换带来的好处增加密钥维度传播距离z和光波长λ成为了新的系统密钥。即使攻击者猜到了随机相位板不知道正确的z和λ也无法正确进行逆菲涅尔变换解密必然失败。增强非线性菲涅尔变换本身是线性变换但与随机相位调制结合后整个系统对密钥参数 (z,λ,n1,n2) 表现出高度的敏感性和非线性抗攻击能力更强。物理意义明确整个加密过程可以看作模拟了一个真实的光学4f系统或衍射系统的简化模型为光学图像加密提供了数字验证平台。在Matlab中如何实现核心就是根据上述公式构造出离散化的Q1和H。需要特别注意采样间隔dx,dy的设定它们需要满足菲涅尔变换的采样定理否则会出现混叠导致加密/解密错误。通常dx dy λz / (N * Δu)其中Δu是频率域采样间隔N是图像尺寸。在源码中这部分往往被封装成一个函数FresnelPropagation(U0, lambda, z, dx, dy)。3. 完整加密解密流程与Matlab实现要点理解了原理我们来看完整的操作链条。整个系统分为加密器和解密器它们是对称的逆过程。3.1 加密流程分步详解假设我们有一幅灰度图像I尺寸为M×N。步骤1图像预处理与光场初始化明文图像I的像素值代表光强振幅的平方。我们需要将其转换为复振幅。最常用的方法是取平方根作为振幅并赋予一个初始的平面波相位通常为0或常数。A0 sqrt(double(I)); % 振幅 P0 zeros(size(I)); % 初始相位通常为0 U0 A0 .* exp(1i * P0); % 初始复振幅光场这里1i是Matlab中的虚数单位。将图像转换为双精度浮点数是关键一步避免后续复数运算中的精度损失和类型错误。步骤2第一次随机相位调制输入面生成第一块随机相位板RM1其相位值n1在[0, 2π]均匀分布。这里有一个至关重要的细节RM1必须保存下来作为密钥的一部分。n1 2 * pi * rand(M, N); % 生成MxN的均匀随机相位 RM1 exp(1i * n1); U1 U0 .* RM1; % 第一次调制rand函数生成[0,1)的均匀分布乘以2π得到[0, 2π)。确保使用rand而不是randn后者是高斯分布不符合理论要求。步骤3第一次菲涅尔变换将调制后的光场U1进行菲涅尔变换传播距离为z1波长为lambda。[U2, x2, y2] FresnelPropagation(U1, lambda, z1, dx, dy);这个函数需要自己实现或从源码中获取。它内部完成了Q1因子的乘法和传递函数H的卷积通过FFT2和IFFT2。输出U2是变换域的光场复振幅x2, y2是输出面的坐标网格可能用于后续计算或显示。步骤4第二次随机相位调制变换域在菲涅尔变换域进行第二次调制。生成并保存第二块随机相位板RM2。n2 2 * pi * rand(M, N); RM2 exp(1i * n2); U3 U2 .* RM2;步骤5第二次菲涅尔变换将二次调制后的光场再进行一次菲涅尔变换传播距离为z2。[U_enc, x_enc, y_enc] FresnelPropagation(U3, lambda, z2, dx2, dy2);这里dx2, dy2需要是步骤3输出面U2的采样间隔通常由FresnelPropagation函数根据输入参数计算得出。保持采样间隔的连贯性是正确仿真的关键很多错误源于此。步骤6生成密文最终得到的U_enc是一个复数矩阵。直接存储复数不方便通常我们取其振幅强度作为最终的密文图像。也可以同时存储相位但振幅图已足以作为无法识别的密文。Ciphertext abs(U_enc).^2; % 密文强度图 % 或者归一化到0-255以便显示和保存 Ciphertext_uint8 uint8(255 * mat2gray(Ciphertext)); imwrite(Ciphertext_uint8, ciphertext.png);至此加密完成。系统的密钥包Key {RM1, RM2, lambda, z1, z2, dx, dy, ...}。在实际应用中RM1和RM2这两个巨大的随机矩阵需要安全地存储和传输。3.2 解密流程与逆操作解密是加密的逆过程前提是拥有全部正确的密钥。步骤1密文初始化读取密文强度图并假设其初始相位为0这是一个近似在无噪声的理想情况下可行。C double(imread(ciphertext.png)); U_enc_dec sqrt(C); % 振幅步骤2第一次逆菲涅尔变换对密文光场进行逆菲涅尔变换。注意菲涅尔变换的逆变换在数学上等同于以-z为距离进行正向菲涅尔变换。[U3_dec, ~, ~] FresnelPropagation(U_enc_dec, lambda, -z2, dx_enc, dy_enc);步骤3第二次随机相位解调使用共轭密钥用第二块随机相位板RM2的共轭进行解调。因为调制时是乘以exp(j*n2)解调就需要乘以exp(-j*n2)来抵消它。U2_dec U3_dec .* conj(RM2); % conj() 求共轭步骤4第二次逆菲涅尔变换[U1_dec, ~, ~] FresnelPropagation(U2_dec, lambda, -z1, dx2, dy2);步骤5第一次随机相位解调用第一块随机相位板RM1的共轭进行解调。U0_dec U1_dec .* conj(RM1);步骤6获取解密图像解密得到的光场U0_dec的振幅应该近似等于原始图像的振幅A0。Decrypted_Amplitude abs(U0_dec); Decrypted_Image uint8(255 * mat2gray(Decrypted_Amplitude.^2)); % 转换回强度图并归一化如果一切正确Decrypted_Image将与原始图像I视觉上几乎完全相同。衡量解密质量通常使用峰值信噪比PSNR和结构相似性指数SSIMPSNR值越高通常30dB、SSIM越接近1说明解密效果越好。4. 源码关键函数剖析与参数设置心得拿到Matlab源码假设是4324期里面通常包含主程序main.m和几个核心函数。我们重点剖析最核心的FresnelPropagation函数和参数设置逻辑。4.1FresnelPropagation函数实现细节一个典型且正确的菲涅尔衍射数值实现函数如下function [Uout, x2, y2] FresnelPropagation(Uin, lambda, z, dx, dy) % Uin: 输入复振幅场 % lambda: 波长 (米) % z: 传播距离 (米) % dx, dy: 输入面采样间隔 (米) % Uout: 输出复振幅场 % x2, y2: 输出面坐标网格 [M, N] size(Uin); k 2 * pi / lambda; % 1. 生成输入面坐标网格 x1 (-N/2 : N/2-1) * dx; y1 (-M/2 : M/2-1) * dy; [X1, Y1] meshgrid(x1, y1); % 2. 计算输入面的二次相位因子 Q1 Q1 exp(1i * k/(2*z) * (X1.^2 Y1.^2)); % 3. 计算传递函数H的频域形式注意采样定理 % 输出面采样间隔由菲涅尔衍射公式决定 dx2 lambda * z / (N * dx); dy2 lambda * z / (M * dy); x2 (-N/2 : N/2-1) * dx2; y2 (-M/2 : M/2-1) * dy2; [X2, Y2] meshgrid(x2, y2); % 传递函数 H H exp(1i * k * z) / (1i * lambda * z) .* exp(1i * k/(2*z) * (X2.^2 Y2.^2)); % 4. 通过FFT实现卷积 U_temp Uin .* Q1; U_temp_fft fft2(fftshift(U_temp)); % fftshift将零频移到中心 Uout_fft U_temp_fft .* fftshift(H); % H也需要频移 Uout ifftshift(ifft2(Uout_fft)); % 逆变换后移回 % 5. 乘以一个常数相位因子有时可省略不影响强度 % Uout Uout * exp(1i*k*z); end关键点解析fftshift和ifftshift的使用至关重要它们确保了空间域和频率域坐标的正确对应。顺序错了结果会完全错乱。输出面采样间隔dx2, dy2的计算公式λz/(N*dx)来源于菲涅尔衍射的频域分析它保证了计算满足采样定理避免混叠。传递函数H中的exp(1i*k*z)/(1i*λz)是菲涅尔衍射的复常数因子虽然不影响输出强度图但影响相位在需要精确复振幅信息的场合必须保留。4.2 系统参数选择与调优经验参数设置直接决定了加密效果和系统的稳定性。以下是我在多次实验中总结的经验波长 (lambda)通常选择可见光波段如632.8e-9(氦氖激光) 或532e-9(绿光)。在纯数字仿真中它的具体数值影响不大但必须与距离z匹配保证λz乘积在一个合理的量级避免计算溢出或下溢。建议范围1e-7到1e-5米。传播距离 (z1,z2)这是最重要的参数之一。z不能太小否则菲涅尔变换退化为近场衍射算法可能不稳定也不能太大否则计算出的dx2会非常大导致输出图像“尺度”变化剧烈。经验公式z max(N*dx, M*dy)^2 / lambda。这是一个粗略的远场条件确保使用菲涅尔近似是有效的。实操建议对于256x256dxdy1e-5mlambda632.8e-9m的情况z可以设置在0.01到0.1米之间进行尝试。两个距离z1和z2最好设置成不同的值以增加密钥空间。采样间隔 (dx,dy)它代表了数字图像中一个像素对应的物理尺寸。这个值需要与你设定的z和lambda自洽。核心约束dx2 lambda * z / (N * dx)。你必须检查计算出的dx2是否合理。如果dx2比dx大好几个数量级意味着输出面一个像素代表的物理尺寸巨大解密图像可能会“缩”成一个点。反之如果dx2太小图像则会“扩散”开。调试技巧固定lambda和图像尺寸N先假设一个理想的dx2比如希望和dx差不多反推出需要的z值z (dx2 * N * dx) / lambda。用这个z作为初始值进行实验。随机相位板生成务必使用rand生成均匀分布。为了可重复性比如论文复现在加密和解密时必须使用相同的随机数种子。rng(2025); % 设置随机种子2025可以换成任意整数 RM1 exp(1i * 2*pi*rand(M,N)); rng(2026); % 使用不同的种子生成RM2 RM2 exp(1i * 2*pi*rand(M,N));在解密程序开始时也需要用rng(2025)和rng(2026)重新生成完全相同的RM1和RM2。5. 常见问题、调试技巧与安全性分析在实际编写和运行代码时你肯定会遇到各种问题。下面是我踩过坑后总结的排查清单和进阶思考。5.1 实操问题速查与解决方案问题现象可能原因排查步骤与解决方案解密图像全黑或全白1. 随机相位板密钥不匹配。2. 菲涅尔变换参数 (z,lambda) 加密解密不一致。3.fftshift/ifftshift使用错误或遗漏。1.检查密钥确保加密和解密程序中的rng种子完全一致生成的RM1,RM2相同。可以保存密钥矩阵为.mat文件加解密时加载。2.检查参数在命令行打印并对比加解密函数中的lambda,z1,z2,dx,dy是否一字不差。3.检查FFT移位在FresnelPropagation函数中仔细核对fftshift和ifftshift包裹fft2和ifft2的顺序。可以尝试注释掉所有fftshift看是否出现对称的、但位置错误的解密图。解密图像有重影或周期性噪声采样定理不满足出现频谱混叠。1.检查dx2公式确认dx2 lambda*z/(N*dx)计算正确。2.调整距离z增大z值使dx2变大从而降低输出面的最高空间频率。3.对输入图像进行预处理在加密前对图像进行轻微的高斯滤波衰减其高频成分可以减少混叠风险。解密图像模糊PSNR低1. 使用了强度图而非复振幅进行解密。2. 相位信息丢失。在加密最后只保存了强度abs(U_enc).^2解密时假设相位为0这会引入误差。1.理想仿真在仿真中为了测试算法极限可以直接保存加密后的复振幅U_enc作为密文。这样解密时能获得完美重建。2.实际应用如果只能传输强度图那么解密时的相位恢复问题是一个研究难点属于相位恢复问题。可以尝试使用迭代算法如GS算法从强度图中估计相位但这会引入误差且不是本项目的标准流程。标准流程默认在理想信道下进行。程序运行特别慢对于大图频繁进行fft2和矩阵运算特别是meshgrid生成大网格。1.预计算并保存网格X1, Y1, X2, Y2这些网格只与参数和尺寸有关与图像内容无关。可以在程序初始化时计算一次并保存避免在每次调用FresnelPropagation时都重新计算。2.使用gpuArray如果拥有NVIDIA GPU和Parallel Computing Toolbox可以将矩阵转换为gpuArray利用GPU加速FFT运算速度提升显著。密文图像看起来不像均匀噪声仍有原图轮廓加密强度不够。可能原因1. 随机相位板统计特性不好如不是均匀分布。2. 菲涅尔变换距离z太小变换不够“充分”。1.验证随机数用histogram(angle(RM1(:)))查看相位角的直方图是否在[0, 2π]基本均匀。2.增大z适当增加z1和z2的值让衍射效应更明显。3.叠加更多变换可以在系统中引入第三个随机相位板或额外的线性变换如分数傅里叶变换来进一步增强混淆效果。5.2 安全性分析与扩展思考这个方案的安全性建立在几个基础上巨大的密钥空间两个MxN的随机相位矩阵每个元素有2π的精度密钥空间近乎无限。密钥的敏感性系统对密钥极度敏感。即使RM1或RM2有极微小的误差比如只错一个像素或者z,lambda有微小偏差解密结果都会迅速退化为噪声PSNR急剧下降。你可以做一个实验将解密用的z1增加千分之一看看解密图会变成什么样子。已知明文攻击的抵抗性由于使用了两次非线性的随机相位调制即使攻击者拥有一些“明文-密文”对想反推出密钥也极其困难。然而它并非无懈可击在实战中需要考虑密钥管理RM1和RM2是两个和图像一样大的矩阵传输和存储它们本身就是一个安全问题。如何安全分发这些密钥一种思路是使用一个主密钥种子通过密码学安全的伪随机数生成器CSPRNG在加解密两端同步生成这两个矩阵这样只需传输一个短种子。抗噪声干扰实际传输中密文图像可能会被压缩如JPEG或加入噪声。该方案对噪声比较敏感因为噪声会破坏密文的振幅和相位信息。可以考虑在加密前对图像进行纠错编码或者研究鲁棒性更强的双随机相位结构变体。选择明文攻击有学术论文指出经典的双随机相位编码系统在特定条件下可能遭受选择明文攻击。改进方案包括引入非线性操作、使用像素置乱如Arnold变换与相位编码结合、或者使用更复杂的变换域如分数傅里叶变换、Gyrator变换。这个Matlab项目提供了一个完美的起点和验证平台。你可以基于此尝试改进密钥生成方式、加入像素置乱步骤、或者替换变换域来构建更健壮、更实用的图像加密系统。编程实现的过程也是你深入理解光学信息处理和安全编码原理的过程。
基于双随机相位与菲涅尔变换的Matlab图像加密实现
1. 项目概述当光学加密遇上数字实现最近在整理一些图像处理的老项目翻到了一个挺有意思的玩意儿基于双随机相位结构和菲涅尔变换的图像加密。这玩意儿听起来有点“光学玄学”但用Matlab实现起来其实是一套非常精妙且实用的数字图像加密方案。它最早脱胎于光学信息处理领域核心思想是模拟光波在自由空间传播时的衍射效应来打乱图像信息再结合随机相位板引入的“密钥”从而实现高强度的加密。现在很多研究者把它纯数字化用Matlab来仿真整个光学过程既保留了其理论上的高安全性又具备了软件实现的灵活性和可重复性。简单来说这个项目就是给你一张明文图像比如一张照片你通过一套包含菲涅尔衍射和随机相位调制的算法把它变成一堆看起来像白噪声的、完全无法识别的密文图像。解密时只有持有正确“密钥”即特定的随机相位分布和系统参数的人才能通过逆过程完美地恢复出原图。它特别适合那些对安全性要求高又希望加密过程具备一定物理意义或抗攻击特性的场景比如医学影像的隐私保护、遥感图像的保密传输或者数字水印的底层嵌入。对于想入门图像加密或者对光学与数字信号处理交叉领域感兴趣的朋友来说这个项目是个绝佳的练手材料。它不单单是调用几个加密函数而是需要你真正理解菲涅尔变换的物理意义、随机相位的作用以及如何用离散的数学计算来模拟连续的物理过程。接下来我就结合源码把这套方案的里里外外、实操细节以及我踩过的坑给大家掰开揉碎了讲清楚。2. 核心原理拆解光学的“锁”与数字的“钥”要搞懂这个加密系统得先明白它的两大支柱双随机相位编码和菲涅尔变换。它们一个负责引入密钥一个负责提供变换域共同构成了加密的基石。2.1 双随机相位编码信息打乱的“搅拌机”双随机相位编码是这套方案安全性的核心。它的想法非常直观在图像的傅里叶域频率域和空间域分别放置两块随机相位板。第一块相位板输入面对原始的明文图像进行相位调制。假设明文图像是f(x, y)第一块随机相位板是exp[j * n1(x, y)]其中n1(x, y)是在区间[0, 2π]上均匀分布的随机数。调制后得到f(x, y) * exp[j * n1(x, y)]。这一步相当于给图像的每个像素点附加了一个随机的相位延迟破坏了图像原有的空间相关性。第二块相位板傅里叶面对经过一次傅里叶变换后的信号进行第二次相位调制。将上一步的结果进行傅里叶变换得到F(u, v)然后用第二块随机相位板exp[j * n2(u, v)]进行调制得到F(u, v) * exp[j * n2(u, v)]。n2(u, v)是另一组独立的[0, 2π]均匀分布随机数。这一步是在频率域进行二次搅拌使得图像的频谱信息也变得杂乱无章。为什么是“相位”而不是“振幅”这是关键。如果直接对图像的振幅即像素亮度值加随机数会明显改变图像的视觉效果可能引入无法消除的噪声。而相位调制在视觉上如果只取振幅可能变化不大但它彻底改变了光波或信号的波前结构。在解密时只要拥有完全相同的相位板密钥通过共轭相位进行补偿就能完美抵消这些随机扰动恢复原始信息。振幅密钥则很难做到无损恢复。这两块随机相位板n1和n2就是整个系统的密钥。它们的统计特性均匀分布和巨大的密钥空间对于一个N×N的图像密钥量级是(2π)^(2*N^2)使得暴力破解几乎不可能。2.2 菲涅尔变换引入物理参数的“变换域”传统的双随机相位编码通常在傅里叶变换域进行。而这个项目的特色在于它用菲涅尔变换替代了标准的傅里叶变换。菲涅尔变换描述的是光波在自由空间中近距离传播时的衍射效应。它与傅里叶变换最大的区别在于菲涅尔变换的结果依赖于传播距离z和光波长λ。其数学表达式是一个卷积形式Uz(x, y) (exp(jkz) / (jλz)) * exp[jπ/(λz) * (x^2 y^2)] * [U0(x, y) * exp[jπ/(λz) * (x^2 y^2)]]其中*表示卷积U0是输入光场Uz是传播距离z后的光场k2π/λ。在数字实现中我们利用菲涅尔变换的卷积性质通过两次快速傅里叶变换来高效计算Uz IFFT2( FFT2(U0 .* Q1) .* H )这里Q1 exp[jπ/(λz) * (x^2 y^2)]是输入面的二次相位因子H是传递函数。引入菲涅尔变换带来的好处增加密钥维度传播距离z和光波长λ成为了新的系统密钥。即使攻击者猜到了随机相位板不知道正确的z和λ也无法正确进行逆菲涅尔变换解密必然失败。增强非线性菲涅尔变换本身是线性变换但与随机相位调制结合后整个系统对密钥参数 (z,λ,n1,n2) 表现出高度的敏感性和非线性抗攻击能力更强。物理意义明确整个加密过程可以看作模拟了一个真实的光学4f系统或衍射系统的简化模型为光学图像加密提供了数字验证平台。在Matlab中如何实现核心就是根据上述公式构造出离散化的Q1和H。需要特别注意采样间隔dx,dy的设定它们需要满足菲涅尔变换的采样定理否则会出现混叠导致加密/解密错误。通常dx dy λz / (N * Δu)其中Δu是频率域采样间隔N是图像尺寸。在源码中这部分往往被封装成一个函数FresnelPropagation(U0, lambda, z, dx, dy)。3. 完整加密解密流程与Matlab实现要点理解了原理我们来看完整的操作链条。整个系统分为加密器和解密器它们是对称的逆过程。3.1 加密流程分步详解假设我们有一幅灰度图像I尺寸为M×N。步骤1图像预处理与光场初始化明文图像I的像素值代表光强振幅的平方。我们需要将其转换为复振幅。最常用的方法是取平方根作为振幅并赋予一个初始的平面波相位通常为0或常数。A0 sqrt(double(I)); % 振幅 P0 zeros(size(I)); % 初始相位通常为0 U0 A0 .* exp(1i * P0); % 初始复振幅光场这里1i是Matlab中的虚数单位。将图像转换为双精度浮点数是关键一步避免后续复数运算中的精度损失和类型错误。步骤2第一次随机相位调制输入面生成第一块随机相位板RM1其相位值n1在[0, 2π]均匀分布。这里有一个至关重要的细节RM1必须保存下来作为密钥的一部分。n1 2 * pi * rand(M, N); % 生成MxN的均匀随机相位 RM1 exp(1i * n1); U1 U0 .* RM1; % 第一次调制rand函数生成[0,1)的均匀分布乘以2π得到[0, 2π)。确保使用rand而不是randn后者是高斯分布不符合理论要求。步骤3第一次菲涅尔变换将调制后的光场U1进行菲涅尔变换传播距离为z1波长为lambda。[U2, x2, y2] FresnelPropagation(U1, lambda, z1, dx, dy);这个函数需要自己实现或从源码中获取。它内部完成了Q1因子的乘法和传递函数H的卷积通过FFT2和IFFT2。输出U2是变换域的光场复振幅x2, y2是输出面的坐标网格可能用于后续计算或显示。步骤4第二次随机相位调制变换域在菲涅尔变换域进行第二次调制。生成并保存第二块随机相位板RM2。n2 2 * pi * rand(M, N); RM2 exp(1i * n2); U3 U2 .* RM2;步骤5第二次菲涅尔变换将二次调制后的光场再进行一次菲涅尔变换传播距离为z2。[U_enc, x_enc, y_enc] FresnelPropagation(U3, lambda, z2, dx2, dy2);这里dx2, dy2需要是步骤3输出面U2的采样间隔通常由FresnelPropagation函数根据输入参数计算得出。保持采样间隔的连贯性是正确仿真的关键很多错误源于此。步骤6生成密文最终得到的U_enc是一个复数矩阵。直接存储复数不方便通常我们取其振幅强度作为最终的密文图像。也可以同时存储相位但振幅图已足以作为无法识别的密文。Ciphertext abs(U_enc).^2; % 密文强度图 % 或者归一化到0-255以便显示和保存 Ciphertext_uint8 uint8(255 * mat2gray(Ciphertext)); imwrite(Ciphertext_uint8, ciphertext.png);至此加密完成。系统的密钥包Key {RM1, RM2, lambda, z1, z2, dx, dy, ...}。在实际应用中RM1和RM2这两个巨大的随机矩阵需要安全地存储和传输。3.2 解密流程与逆操作解密是加密的逆过程前提是拥有全部正确的密钥。步骤1密文初始化读取密文强度图并假设其初始相位为0这是一个近似在无噪声的理想情况下可行。C double(imread(ciphertext.png)); U_enc_dec sqrt(C); % 振幅步骤2第一次逆菲涅尔变换对密文光场进行逆菲涅尔变换。注意菲涅尔变换的逆变换在数学上等同于以-z为距离进行正向菲涅尔变换。[U3_dec, ~, ~] FresnelPropagation(U_enc_dec, lambda, -z2, dx_enc, dy_enc);步骤3第二次随机相位解调使用共轭密钥用第二块随机相位板RM2的共轭进行解调。因为调制时是乘以exp(j*n2)解调就需要乘以exp(-j*n2)来抵消它。U2_dec U3_dec .* conj(RM2); % conj() 求共轭步骤4第二次逆菲涅尔变换[U1_dec, ~, ~] FresnelPropagation(U2_dec, lambda, -z1, dx2, dy2);步骤5第一次随机相位解调用第一块随机相位板RM1的共轭进行解调。U0_dec U1_dec .* conj(RM1);步骤6获取解密图像解密得到的光场U0_dec的振幅应该近似等于原始图像的振幅A0。Decrypted_Amplitude abs(U0_dec); Decrypted_Image uint8(255 * mat2gray(Decrypted_Amplitude.^2)); % 转换回强度图并归一化如果一切正确Decrypted_Image将与原始图像I视觉上几乎完全相同。衡量解密质量通常使用峰值信噪比PSNR和结构相似性指数SSIMPSNR值越高通常30dB、SSIM越接近1说明解密效果越好。4. 源码关键函数剖析与参数设置心得拿到Matlab源码假设是4324期里面通常包含主程序main.m和几个核心函数。我们重点剖析最核心的FresnelPropagation函数和参数设置逻辑。4.1FresnelPropagation函数实现细节一个典型且正确的菲涅尔衍射数值实现函数如下function [Uout, x2, y2] FresnelPropagation(Uin, lambda, z, dx, dy) % Uin: 输入复振幅场 % lambda: 波长 (米) % z: 传播距离 (米) % dx, dy: 输入面采样间隔 (米) % Uout: 输出复振幅场 % x2, y2: 输出面坐标网格 [M, N] size(Uin); k 2 * pi / lambda; % 1. 生成输入面坐标网格 x1 (-N/2 : N/2-1) * dx; y1 (-M/2 : M/2-1) * dy; [X1, Y1] meshgrid(x1, y1); % 2. 计算输入面的二次相位因子 Q1 Q1 exp(1i * k/(2*z) * (X1.^2 Y1.^2)); % 3. 计算传递函数H的频域形式注意采样定理 % 输出面采样间隔由菲涅尔衍射公式决定 dx2 lambda * z / (N * dx); dy2 lambda * z / (M * dy); x2 (-N/2 : N/2-1) * dx2; y2 (-M/2 : M/2-1) * dy2; [X2, Y2] meshgrid(x2, y2); % 传递函数 H H exp(1i * k * z) / (1i * lambda * z) .* exp(1i * k/(2*z) * (X2.^2 Y2.^2)); % 4. 通过FFT实现卷积 U_temp Uin .* Q1; U_temp_fft fft2(fftshift(U_temp)); % fftshift将零频移到中心 Uout_fft U_temp_fft .* fftshift(H); % H也需要频移 Uout ifftshift(ifft2(Uout_fft)); % 逆变换后移回 % 5. 乘以一个常数相位因子有时可省略不影响强度 % Uout Uout * exp(1i*k*z); end关键点解析fftshift和ifftshift的使用至关重要它们确保了空间域和频率域坐标的正确对应。顺序错了结果会完全错乱。输出面采样间隔dx2, dy2的计算公式λz/(N*dx)来源于菲涅尔衍射的频域分析它保证了计算满足采样定理避免混叠。传递函数H中的exp(1i*k*z)/(1i*λz)是菲涅尔衍射的复常数因子虽然不影响输出强度图但影响相位在需要精确复振幅信息的场合必须保留。4.2 系统参数选择与调优经验参数设置直接决定了加密效果和系统的稳定性。以下是我在多次实验中总结的经验波长 (lambda)通常选择可见光波段如632.8e-9(氦氖激光) 或532e-9(绿光)。在纯数字仿真中它的具体数值影响不大但必须与距离z匹配保证λz乘积在一个合理的量级避免计算溢出或下溢。建议范围1e-7到1e-5米。传播距离 (z1,z2)这是最重要的参数之一。z不能太小否则菲涅尔变换退化为近场衍射算法可能不稳定也不能太大否则计算出的dx2会非常大导致输出图像“尺度”变化剧烈。经验公式z max(N*dx, M*dy)^2 / lambda。这是一个粗略的远场条件确保使用菲涅尔近似是有效的。实操建议对于256x256dxdy1e-5mlambda632.8e-9m的情况z可以设置在0.01到0.1米之间进行尝试。两个距离z1和z2最好设置成不同的值以增加密钥空间。采样间隔 (dx,dy)它代表了数字图像中一个像素对应的物理尺寸。这个值需要与你设定的z和lambda自洽。核心约束dx2 lambda * z / (N * dx)。你必须检查计算出的dx2是否合理。如果dx2比dx大好几个数量级意味着输出面一个像素代表的物理尺寸巨大解密图像可能会“缩”成一个点。反之如果dx2太小图像则会“扩散”开。调试技巧固定lambda和图像尺寸N先假设一个理想的dx2比如希望和dx差不多反推出需要的z值z (dx2 * N * dx) / lambda。用这个z作为初始值进行实验。随机相位板生成务必使用rand生成均匀分布。为了可重复性比如论文复现在加密和解密时必须使用相同的随机数种子。rng(2025); % 设置随机种子2025可以换成任意整数 RM1 exp(1i * 2*pi*rand(M,N)); rng(2026); % 使用不同的种子生成RM2 RM2 exp(1i * 2*pi*rand(M,N));在解密程序开始时也需要用rng(2025)和rng(2026)重新生成完全相同的RM1和RM2。5. 常见问题、调试技巧与安全性分析在实际编写和运行代码时你肯定会遇到各种问题。下面是我踩过坑后总结的排查清单和进阶思考。5.1 实操问题速查与解决方案问题现象可能原因排查步骤与解决方案解密图像全黑或全白1. 随机相位板密钥不匹配。2. 菲涅尔变换参数 (z,lambda) 加密解密不一致。3.fftshift/ifftshift使用错误或遗漏。1.检查密钥确保加密和解密程序中的rng种子完全一致生成的RM1,RM2相同。可以保存密钥矩阵为.mat文件加解密时加载。2.检查参数在命令行打印并对比加解密函数中的lambda,z1,z2,dx,dy是否一字不差。3.检查FFT移位在FresnelPropagation函数中仔细核对fftshift和ifftshift包裹fft2和ifft2的顺序。可以尝试注释掉所有fftshift看是否出现对称的、但位置错误的解密图。解密图像有重影或周期性噪声采样定理不满足出现频谱混叠。1.检查dx2公式确认dx2 lambda*z/(N*dx)计算正确。2.调整距离z增大z值使dx2变大从而降低输出面的最高空间频率。3.对输入图像进行预处理在加密前对图像进行轻微的高斯滤波衰减其高频成分可以减少混叠风险。解密图像模糊PSNR低1. 使用了强度图而非复振幅进行解密。2. 相位信息丢失。在加密最后只保存了强度abs(U_enc).^2解密时假设相位为0这会引入误差。1.理想仿真在仿真中为了测试算法极限可以直接保存加密后的复振幅U_enc作为密文。这样解密时能获得完美重建。2.实际应用如果只能传输强度图那么解密时的相位恢复问题是一个研究难点属于相位恢复问题。可以尝试使用迭代算法如GS算法从强度图中估计相位但这会引入误差且不是本项目的标准流程。标准流程默认在理想信道下进行。程序运行特别慢对于大图频繁进行fft2和矩阵运算特别是meshgrid生成大网格。1.预计算并保存网格X1, Y1, X2, Y2这些网格只与参数和尺寸有关与图像内容无关。可以在程序初始化时计算一次并保存避免在每次调用FresnelPropagation时都重新计算。2.使用gpuArray如果拥有NVIDIA GPU和Parallel Computing Toolbox可以将矩阵转换为gpuArray利用GPU加速FFT运算速度提升显著。密文图像看起来不像均匀噪声仍有原图轮廓加密强度不够。可能原因1. 随机相位板统计特性不好如不是均匀分布。2. 菲涅尔变换距离z太小变换不够“充分”。1.验证随机数用histogram(angle(RM1(:)))查看相位角的直方图是否在[0, 2π]基本均匀。2.增大z适当增加z1和z2的值让衍射效应更明显。3.叠加更多变换可以在系统中引入第三个随机相位板或额外的线性变换如分数傅里叶变换来进一步增强混淆效果。5.2 安全性分析与扩展思考这个方案的安全性建立在几个基础上巨大的密钥空间两个MxN的随机相位矩阵每个元素有2π的精度密钥空间近乎无限。密钥的敏感性系统对密钥极度敏感。即使RM1或RM2有极微小的误差比如只错一个像素或者z,lambda有微小偏差解密结果都会迅速退化为噪声PSNR急剧下降。你可以做一个实验将解密用的z1增加千分之一看看解密图会变成什么样子。已知明文攻击的抵抗性由于使用了两次非线性的随机相位调制即使攻击者拥有一些“明文-密文”对想反推出密钥也极其困难。然而它并非无懈可击在实战中需要考虑密钥管理RM1和RM2是两个和图像一样大的矩阵传输和存储它们本身就是一个安全问题。如何安全分发这些密钥一种思路是使用一个主密钥种子通过密码学安全的伪随机数生成器CSPRNG在加解密两端同步生成这两个矩阵这样只需传输一个短种子。抗噪声干扰实际传输中密文图像可能会被压缩如JPEG或加入噪声。该方案对噪声比较敏感因为噪声会破坏密文的振幅和相位信息。可以考虑在加密前对图像进行纠错编码或者研究鲁棒性更强的双随机相位结构变体。选择明文攻击有学术论文指出经典的双随机相位编码系统在特定条件下可能遭受选择明文攻击。改进方案包括引入非线性操作、使用像素置乱如Arnold变换与相位编码结合、或者使用更复杂的变换域如分数傅里叶变换、Gyrator变换。这个Matlab项目提供了一个完美的起点和验证平台。你可以基于此尝试改进密钥生成方式、加入像素置乱步骤、或者替换变换域来构建更健壮、更实用的图像加密系统。编程实现的过程也是你深入理解光学信息处理和安全编码原理的过程。