% 创建主窗口(采用归一化单位,便于自适应屏幕)
f = figure(‘Name’,‘数字全息成像仿真与滤波处理’,‘NumberTitle’,‘off’,…
‘Units’,‘normalized’,‘Position’,[0.1,0.1,0.95,0.8]);
% 将窗口分为左右两部分:左侧显示图像、右侧为操作面板
leftPanel = uipanel(‘Parent’,f,‘Units’,‘normalized’,‘Position’,[0,0,0.65,1]);
rightPanel = uipanel(‘Parent’,f,‘Units’,‘normalized’,‘Position’,[0.67,0,0.33,1]);
data = struct(); % 用于存储各步骤数据
%% 在左侧面板上创建6个图像显示区域(采用自定义位置)
% 上排:全息图、全息图傅里叶、重现像(未经 Lee 滤波)
ax1 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.05,0.55,0.28,0.4]); title(‘全息图’);
ax2 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.37,0.55,0.28,0.4]); title(‘全息图傅里叶’);
ax3 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.69,0.55,0.28,0.4]); title(‘重现像(未经 Lee 滤波)’);
% 下排:窗口傅里叶滤波后傅里叶域、重现像(Lee 滤波)、原始物体
ax4 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.05,0.05,0.28,0.4]); title(‘窗口傅里叶滤波后 FT’);
ax5 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.37,0.05,0.28,0.4]); title(‘重现像(Lee 滤波)’);
ax6 = axes(‘Parent’,leftPanel,‘Units’,‘normalized’,‘Position’,[0.69,0.05,0.28,0.4]); title(‘原始物体’);
%% 在右侧面板上创建按钮和文本显示控件(均采用中文)
btn1 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.85,0.8,0.08],‘String’,‘加载目标图像’,‘FontSize’,10,…
‘Callback’,@loadObject);
btn2 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.75,0.8,0.08],‘String’,‘仿真全息图’,‘FontSize’,10,…
‘Callback’,@simulateHologram);
btn3 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.65,0.8,0.08],‘String’,‘窗口傅里叶滤波’,‘FontSize’,10,…
‘Callback’,@applyWFFilter);
btn4 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.55,0.8,0.08],‘String’,‘重构图像’,‘FontSize’,10,…
‘Callback’,@reconstructImage);
btn5 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.45,0.8,0.08],‘String’,‘Lee 滤波处理’,‘FontSize’,10,…
‘Callback’,@applyLeeFilter);
btn6 = uicontrol(‘Parent’,rightPanel,‘Style’,‘pushbutton’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.35,0.8,0.08],‘String’,‘计算图像指标’,‘FontSize’,10,…
‘Callback’,@calculateMetrics);
% 用于显示计算指标结果的文本控件
data.metricsText = uicontrol(‘Parent’,rightPanel,‘Style’,‘text’,‘Units’,‘normalized’,…
‘Position’,[0.1,0.1,0.8,0.2],‘String’,‘图像指标:’,‘FontSize’,10);
guidata(f,data);
%% 回调函数
function loadObject(~, ~)
% 加载目标图像(支持 jpg/png/bmp/tif),转换为灰度双精度图
[filename, pathname] = uigetfile({‘.jpg;.png;.bmp;.tif’,‘图像文件’});
if isequal(filename,0)
return;
end
obj = imread(fullfile(pathname,filename));
if size(obj,3)==3
obj = rgb2gray(obj);
end
obj = im2double(obj);
data = guidata(f);
% 调整图像尺寸为256×256
data.object = imresize(obj, [256 256]);
guidata(f,data);
axes(ax6);
imshow(data.object,[]); title(‘原始物体’);
end
function simulateHologram(~, ~)
% 仿真全息图生成
data = guidata(f);
if ~isfield(data, ‘object’)
errordlg(‘请先加载目标图像!’,‘错误提示’);
return;
end
[M, N] = size(data.object);
% 设置全息仿真参数(参考波倾斜频率)
fx = 5; fy = 5;
[x, y] = meshgrid(1:N,1:M);
% 构造物体波:物体振幅与随机相位叠加模拟散斑
phase = 2pirand(M,N);
O = data.object .* exp(1iphase);
% 构造参考波(平面波,off-axis设置)
R = exp(1i2pi(fxx/N + fyy/M));
% 干涉生成全息图(取干涉强度)
H = abs(O + R).^2;
data.hologram = H;
guidata(f,data);
axes(ax1);
imshow(H,[]); title(‘全息图’);
% 显示全息图傅里叶域(对数显示)
F = fftshift(fft2(H));
axes(ax2);
imshow(log(abs(F)+1),[]); title(‘全息图傅里叶’);
end
function applyWFFilter(~, ~)
% 窗口傅里叶滤波:在全息图傅里叶域中选取侧带信息
data = guidata(f);
if ~isfield(data, ‘hologram’)
errordlg(‘请先生成全息图!’,‘错误提示’);
return;
end
H = data.hologram;
[M, N] = size(H);
% 根据全息图的 off-axis 情况设置侧带中心与窗口半径
cx = round(N/2) + 20;
cy = round(M/2) + 20;
radius = 30;
F = fftshift(fft2(H));
[X, Y] = meshgrid(1:N,1:M);
mask = ((X-cx).^2 + (Y-cy).^2) <= radius^2;
F_filtered = F .* mask;
data.F_filtered = F_filtered;
% 利用反傅里叶变换得到滤波后的全息图
H_filtered = abs(ifft2(ifftshift(F_filtered)));
data.hologramWF = H_filtered;
guidata(f,data);
axes(ax4);
imshow(log(abs(F_filtered)+1),[]); title(‘窗口傅里叶滤波后 FT’);
end
function reconstructImage(~, ~)
% 利用窗口傅里叶滤波后的侧带信息重构图像
data = guidata(f);
if isfield(data, ‘F_filtered’)
F_temp = data.F_filtered;
rec = abs(ifft2(ifftshift(F_temp)));
else
rec = abs(ifft2(fft2(data.hologram)));
end
data.recon_noLee = rec;
guidata(f,data);
axes(ax3);
imshow(rec,[]); title(‘重现像(未经 Lee 滤波)’);
end
function applyLeeFilter(~, ~)
% 对重构图像应用 Lee 滤波进行进一步散斑噪声抑制
data = guidata(f);
if ~isfield(data, ‘recon_noLee’)
errordlg(‘请先重构图像!’,‘错误提示’);
return;
end
rec = data.recon_noLee;
% 设置 Lee 滤波窗口尺寸(例如 5×5)
recLee = leeFilter(rec, 5);
data.recon_Lee = recLee;
guidata(f,data);
axes(ax5);
imshow(recLee,[]); title(‘重现像(Lee 滤波)’);
end
function calculateMetrics(~, ~)
% 计算图像指标:散斑对比度(C)、散斑指数(SI)、PSNR及等效视数(ENL)
data = guidata(f);
if ~isfield(data, ‘object’) || ~isfield(data, ‘recon_noLee’) || ~isfield(data, ‘recon_Lee’)
errordlg(‘请确保已加载原始图像并完成重构与 Lee 滤波!’,‘错误提示’);
return;
end
orig = data.object;
rec1 = data.recon_noLee;
rec2 = data.recon_Lee;
[C1, SI1, PSNR1, ENL1] = computeMetrics(orig, rec1);
[C2, SI2, PSNR2, ENL2] = computeMetrics(orig, rec2);
metricStr = sprintf([‘未经 Lee 滤波:\n对比度 C: %.3f\n散斑指数 SI: %.3f\nPSNR: %.3f dB\n等效视数 ENL: %.3f\n\n’,…
‘Lee 滤波:\n对比度 C: %.3f\n散斑指数 SI: %.3f\nPSNR: %.3f dB\n等效视数 ENL: %.3f’],…
C1, SI1, PSNR1, ENL1, C2, SI2, PSNR2, ENL2);
set(data.metricsText, ‘String’, metricStr);
end
function [C, SI, PSNR_val, ENL] = computeMetrics(ref, rec)
% 计算图像各项指标
ref = im2double(ref);
rec = im2double(rec);
% 散斑对比度(C)——标准差与均值的比值
C = std(rec(:)) / (mean(rec(:)) + eps);
% 散斑指数(SI)——方差与均值平方的比值
SI = var(rec(:)) / (mean(rec(:))^2 + eps);
% 均方误差
mse = mean((ref(:) - rec(:)).^2);
% PSNR(假设图像最大值为1)
PSNR_val = 10*log10(1/mse);
% 等效视数(ENL)
ENL = (mean(rec(:))^2) / (var(rec(:)) + eps);
end
function I_out = leeFilter(I, windowSize)
% Lee 滤波:利用局部均值和方差自适应降低散斑噪声
I = double(I);
kernel = ones(windowSize) / (windowSize^2);
localMean = conv2(I, kernel, ‘same’);
localMeanSq = conv2(I.^2, kernel, ‘same’);
localVar = localMeanSq - localMean.^2;
noiseVar = mean(localVar(:));
% 避免局部方差为零
localVar(localVar==0) = eps;
% 计算滤波系数,保证非负
k = max(0,(localVar - noiseVar) ./ localVar);
I_out = localMean + k .* (I - localMean);
end
end
”针对上述代码进行改进:1.要求各图像指标的计算合乎理论(尤其峰值信噪比结果为正值),2.经过一系列滤波处理后,重建像质量要在视觉上好于未经过处理的重建质量,以及所计算的图像指标要对应有所改善(散斑指数和散斑对比度数值降低)。给出完整且能正确运行的代码,未进行改动的代码也要在代码中写出来,不用省略。