数字全息图处理系统,涵盖预处理、全息再现、相位滤波、相位去包裹全流程,适用于显微全息、干涉计量、表面形貌测量等领域。
一、系统架构
DigitalHolography/
├── DigitalHolography.csproj
├── Program.cs
├── MainForm.cs
├── MainForm.Designer.cs
├── Core/
│ ├── HologramProcessor.cs ★ 核心处理引擎
│ ├── FresnelReconstruction.cs # 菲涅尔衍射再现
│ ├── PhaseFilter.cs # 相位滤波
│ ├── PhaseUnwrapper.cs # 相位去包裹
│ └── Preprocessing.cs # 预处理算法
├── Algorithms/
│ ├── FourierTransform.cs # FFT/IFFT
│ ├── GoldsteinUnwrap.cs # Goldstein相位去包裹
│ ├── QualityGuidedUnwrap.cs # 质量引导去包裹
│ ├── LeastSquaresUnwrap.cs # 最小二乘去包裹
│ └── BandPassFilter.cs # 带通滤波
├── Models/
│ ├── HologramParams.cs # 全息参数
│ ├── ReconstructionParams.cs # 再现参数
│ └── PhaseMap.cs # 相位图数据
├── Visualization/
│ ├── HologramViewer.cs # 全息图显示
│ ├── PhaseDisplay.cs # 相位显示
│ └── IntensityDisplay.cs # 强度显示
└── Utils/
├── ComplexNumber.cs # 复数运算
├── ImageConverter.cs # 图像格式转换
└── PerformanceMonitor.cs # 性能监控
二、核心代码实现
1. 主程序入口 (Program.cs)
using System;
using System.Windows.Forms;
using DigitalHolography.Core;
using DigitalHolography.Utils;
namespace DigitalHolography
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// 初始化复数运算库
ComplexNumber.Initialize();
// 初始化FFT库
FourierTransform.Initialize();
Application.Run(new MainForm());
}
}
}
2. 主窗体 (MainForm.cs)
using System;
using System.Drawing;
using System.Windows.Forms;
using DigitalHolography.Core;
using DigitalHolography.Models;
using DigitalHolography.Visualization;
using DigitalHolography.Algorithms;
namespace DigitalHolography
{
public partial class MainForm : Form
{
private HologramProcessor hologramProcessor;
private HologramViewer hologramViewer;
private PhaseDisplay phaseDisplay;
private IntensityDisplay intensityDisplay;
// 处理参数
private HologramParams hologramParams;
private ReconstructionParams reconstructionParams;
public MainForm()
{
InitializeComponent();
InitializeSystem();
}
private void InitializeComponent()
{
this.Text = "数字全息图处理系统";
this.Size = new Size(1600, 1000);
this.StartPosition = FormStartPosition.CenterScreen;
this.WindowState = FormWindowState.Maximized;
// 菜单栏
MenuStrip menuStrip = new MenuStrip();
ToolStripMenuItem fileMenu = new ToolStripMenuItem("文件(&F)");
fileMenu.DropDownItems.Add("打开全息图...", null, OpenHologram_Click);
fileMenu.DropDownItems.Add("保存相位图...", null, SavePhaseMap_Click);
fileMenu.DropDownItems.Add(new ToolStripSeparator());
fileMenu.DropDownItems.Add("退出", null, (s, e) => Application.Exit());
ToolStripMenuItem processMenu = new ToolStripMenuItem("处理(&P)");
processMenu.DropDownItems.Add("预处理", null, Preprocess_Click);
processMenu.DropDownItems.Add("全息再现", null, Reconstruct_Click);
processMenu.DropDownItems.Add("相位滤波", null, PhaseFilter_Click);
processMenu.DropDownItems.Add("相位去包裹", null, PhaseUnwrap_Click);
processMenu.DropDownItems.Add(new ToolStripSeparator());
processMenu.DropDownItems.Add("一键处理", null, OneClickProcess_Click);
ToolStripMenuItem viewMenu = new ToolStripMenuItem("视图(&V)");
viewMenu.DropDownItems.Add("显示全息图", null, ShowHologram_Click);
viewMenu.DropDownItems.Add("显示再现像", null, ShowReconstruction_Click);
viewMenu.DropDownItems.Add("显示相位图", null, ShowPhaseMap_Click);
viewMenu.DropDownItems.Add("显示3D表面", null, Show3DSurface_Click);
ToolStripMenuItem settingsMenu = new ToolStripMenuItem("设置(&S)");
settingsMenu.DropDownItems.Add("全息参数...", null, HologramParams_Click);
settingsMenu.DropDownItems.Add("再现参数...", null, ReconstructionParams_Click);
settingsMenu.DropDownItems.Add("算法设置...", null, AlgorithmSettings_Click);
menuStrip.Items.AddRange(new ToolStripItem[] { fileMenu, processMenu, viewMenu, settingsMenu });
// 工具栏
ToolStrip toolStrip = new ToolStrip();
ToolStripButton btnOpen = new ToolStripButton("打开");
btnOpen.Click += OpenHologram_Click;
ToolStripButton btnPreprocess = new ToolStripButton("预处理");
btnPreprocess.Click += Preprocess_Click;
ToolStripButton btnReconstruct = new ToolStripButton("再现");
btnReconstruct.Click += Reconstruct_Click;
ToolStripButton btnFilter = new ToolStripButton("滤波");
btnFilter.Click += PhaseFilter_Click;
ToolStripButton btnUnwrap = new ToolStripButton("去包裹");
btnUnwrap.Click += PhaseUnwrap_Click;
ToolStripButton btnOneClick = new ToolStripButton("一键处理");
btnOneClick.Click += OneClickProcess_Click;
toolStrip.Items.AddRange(new ToolStripItem[] {
btnOpen, new ToolStripSeparator(),
btnPreprocess, btnReconstruct, btnFilter, btnUnwrap,
new ToolStripSeparator(), btnOneClick
});
// 主布局
SplitContainer mainSplit = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Vertical,
SplitterDistance = 400
};
// 左侧控制面板
Panel controlPanel = CreateControlPanel();
mainSplit.Panel1.Controls.Add(controlPanel);
// 右侧显示区域
TabControl displayTabs = new TabControl
{
Dock = DockStyle.Fill
};
// 全息图标签页
TabPage hologramTab = new TabPage("全息图");
hologramViewer = new HologramViewer { Dock = DockStyle.Fill };
hologramTab.Controls.Add(hologramViewer);
// 再现像标签页
TabPage reconstructionTab = new TabPage("再现像");
intensityDisplay = new IntensityDisplay { Dock = DockStyle.Fill };
reconstructionTab.Controls.Add(intensityDisplay);
// 相位图标签页
TabPage phaseTab = new TabPage("相位图");
phaseDisplay = new PhaseDisplay { Dock = DockStyle.Fill };
phaseTab.Controls.Add(phaseDisplay);
// 3D表面标签页
TabPage surface3DTab = new TabPage("3D表面");
Create3DSurfaceTab(surface3DTab);
displayTabs.TabPages.AddRange(new TabPage[] { hologramTab, reconstructionTab, phaseTab, surface3DTab });
mainSplit.Panel2.Controls.Add(displayTabs);
this.Controls.Add(menuStrip);
this.Controls.Add(toolStrip);
this.Controls.Add(mainSplit);
// 状态栏
statusStrip = new StatusStrip();
statusLabel = new ToolStripStatusLabel("就绪");
progressBar = new ToolStripProgressBar { Visible = false };
statusStrip.Items.Add(statusLabel);
statusStrip.Items.Add(progressBar);
this.Controls.Add(statusStrip);
}
private Panel CreateControlPanel()
{
Panel panel = new Panel
{
Dock = DockStyle.Fill,
BackColor = SystemColors.Control
};
// 全息参数组
GroupBox gbHologramParams = new GroupBox
{
Text = "全息参数",
Location = new Point(10, 10),
Size = new Size(380, 150)
};
Label lblWavelength = new Label { Text = "波长 (nm):", Location = new Point(10, 25), Size = new Size(80, 20) };
txtWavelength = new TextBox { Text = "632.8", Location = new Point(100, 22), Size = new Size(80, 20) };
Label lblPixelSize = new Label { Text = "像素尺寸 (μm):", Location = new Point(10, 55), Size = new Size(80, 20) };
txtPixelSize = new TextBox { Text = "3.45", Location = new Point(100, 52), Size = new Size(80, 20) };
Label lblDistance = new Label { Text = "再现距离 (mm):", Location = new Point(10, 85), Size = new Size(80, 20) };
txtDistance = new TextBox { Text = "50.0", Location = new Point(100, 82), Size = new Size(80, 20) };
Label lblImageSize = new Label { Text = "图像尺寸:", Location = new Point(200, 25), Size = new Size(80, 20) };
lblImageSizeValue = new Label { Text = "1024×1024", Location = new Point(280, 25), Size = new Size(100, 20) };
gbHologramParams.Controls.AddRange(new Control[] {
lblWavelength, txtWavelength, lblPixelSize, txtPixelSize,
lblDistance, txtDistance, lblImageSize, lblImageSizeValue
});
// 预处理组
GroupBox gbPreprocessing = new GroupBox
{
Text = "预处理",
Location = new Point(10, 170),
Size = new Size(380, 120)
};
chkBackgroundSubtraction = new CheckBox { Text = "背景减除", Location = new Point(10, 25), Size = new Size(100, 20), Checked = true };
chkContrastEnhancement = new CheckBox { Text = "对比度增强", Location = new Point(10, 55), Size = new Size(100, 20), Checked = true };
chkNoiseReduction = new CheckBox { Text = "噪声抑制", Location = new Point(10, 85), Size = new Size(100, 20), Checked = true };
Label lblFilterStrength = new Label { Text = "滤波强度:", Location = new Point(150, 25), Size = new Size(80, 20) };
trackBarFilterStrength = new TrackBar { Location = new Point(230, 25), Size = new Size(140, 45), Minimum = 1, Maximum = 10, Value = 3 };
gbPreprocessing.Controls.AddRange(new Control[] {
chkBackgroundSubtraction, chkContrastEnhancement, chkNoiseReduction,
lblFilterStrength, trackBarFilterStrength
});
// 相位滤波组
GroupBox gbPhaseFilter = new GroupBox
{
Text = "相位滤波",
Location = new Point(10, 300),
Size = new Size(380, 120)
};
Label lblFilterType = new Label { Text = "滤波类型:", Location = new Point(10, 25), Size = new Size(80, 20) };
cmbFilterType = new ComboBox { Location = new Point(100, 22), Size = new Size(100, 21), DropDownStyle = ComboBoxStyle.DropDownList };
cmbFilterType.Items.AddRange(new object[] { "带通滤波", "低通滤波", "高通滤波", "高斯滤波" });
cmbFilterType.SelectedIndex = 0;
Label lblCutoffFreq = new Label { Text = "截止频率:", Location = new Point(10, 55), Size = new Size(80, 20) };
txtCutoffFreq = new TextBox { Text = "0.5", Location = new Point(100, 52), Size = new Size(100, 20) };
chkAdaptiveFilter = new CheckBox { Text = "自适应滤波", Location = new Point(10, 85), Size = new Size(100, 20), Checked = true };
gbPhaseFilter.Controls.AddRange(new Control[] {
lblFilterType, cmbFilterType, lblCutoffFreq, txtCutoffFreq, chkAdaptiveFilter
});
// 相位去包裹组
GroupBox gbPhaseUnwrap = new GroupBox
{
Text = "相位去包裹",
Location = new Point(10, 430),
Size = new Size(380, 150)
};
Label lblUnwrapMethod = new Label { Text = "去包裹方法:", Location = new Point(10, 25), Size = new Size(80, 20) };
cmbUnwrapMethod = new ComboBox { Location = new Point(100, 22), Size = new Size(150, 21), DropDownStyle = ComboBoxStyle.DropDownList };
cmbUnwrapMethod.Items.AddRange(new object[] { "Goldstein算法", "质量引导", "最小二乘法", "路径跟踪" });
cmbUnwrapMethod.SelectedIndex = 0;
chkUseMask = new CheckBox { Text = "使用掩模", Location = new Point(10, 55), Size = new Size(100, 20), Checked = true };
chkSmoothPhase = new CheckBox { Text = "平滑相位", Location = new Point(10, 85), Size = new Size(100, 20), Checked = true };
chkRemoveSpikes = new CheckBox { Text = "去除尖峰", Location = new Point(10, 115), Size = new Size(100, 20), Checked = true };
gbPhaseUnwrap.Controls.AddRange(new Control[] {
lblUnwrapMethod, cmbUnwrapMethod, chkUseMask, chkSmoothPhase, chkRemoveSpikes
});
// 结果显示组
GroupBox gbResults = new GroupBox
{
Text = "处理结果",
Location = new Point(10, 590),
Size = new Size(380, 100)
};
lblProcessingTime = new Label { Text = "处理时间: --", Location = new Point(10, 25), Size = new Size(200, 20) };
lblPhaseRange = new Label { Text = "相位范围: --", Location = new Point(10, 55), Size = new Size(200, 20) };
gbResults.Controls.AddRange(new Control[] { lblProcessingTime, lblPhaseRange });
panel.Controls.AddRange(new Control[] {
gbHologramParams, gbPreprocessing, gbPhaseFilter, gbPhaseUnwrap, gbResults
});
return panel;
}
private void Create3DSurfaceTab(TabPage tab)
{
// 3D表面显示(需要集成3D图形库)
Label lblPlaceholder = new Label
{
Text = "3D表面显示\n(需要集成3D图形库如HelixToolkit)",
Dock = DockStyle.Fill,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("微软雅黑", 12),
ForeColor = Color.Gray
};
tab.Controls.Add(lblPlaceholder);
}
private void InitializeSystem()
{
hologramProcessor = new HologramProcessor();
hologramProcessor.ProgressChanged += HologramProcessor_ProgressChanged;
hologramProcessor.ProcessingCompleted += HologramProcessor_ProcessingCompleted;
// 初始化默认参数
hologramParams = new HologramParams
{
Wavelength = 632.8e-9, // 632.8 nm (He-Ne激光)
PixelSize = 3.45e-6, // 3.45 μm
Distance = 0.05, // 50 mm
ImageWidth = 1024,
ImageHeight = 1024
};
reconstructionParams = new ReconstructionParams
{
Method = ReconstructionMethod.Fresnel,
UseBandPassFilter = true,
FilterRadius = 0.5,
UsePhaseUnwrapping = true,
UnwrapMethod = UnwrapMethod.Goldstein
};
}
#region 事件处理
private void OpenHologram_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "图像文件|*.bmp;*.jpg;*.png;*.tif|所有文件|*.*";
dialog.Title = "打开全息图";
if (dialog.ShowDialog() == DialogResult.OK)
{
LoadHologram(dialog.FileName);
}
}
}
private void LoadHologram(string filePath)
{
try
{
UpdateStatus("正在加载全息图...");
Bitmap hologram = new Bitmap(filePath);
hologramProcessor.LoadHologram(hologram);
hologramViewer.DisplayHologram(hologram);
lblImageSizeValue.Text = $"{hologram.Width}×{hologram.Height}";
UpdateStatus("全息图加载完成");
}
catch (Exception ex)
{
MessageBox.Show($"加载全息图失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
UpdateStatus("加载失败");
}
}
private void Preprocess_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentHologram == null)
{
MessageBox.Show("请先加载全息图!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
UpdateStatus("正在进行预处理...");
EnableControls(false);
hologramProcessor.Preprocess(
chkBackgroundSubtraction.Checked,
chkContrastEnhancement.Checked,
chkNoiseReduction.Checked,
trackBarFilterStrength.Value
);
}
private void Reconstruct_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentHologram == null)
{
MessageBox.Show("请先加载全息图!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
UpdateStatus("正在进行全息再现...");
EnableControls(false);
// 更新参数
UpdateParameters();
hologramProcessor.Reconstruct(reconstructionParams);
}
private void PhaseFilter_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentPhaseMap == null)
{
MessageBox.Show("请先进行全息再现!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
UpdateStatus("正在进行相位滤波...");
EnableControls(false);
PhaseFilterType filterType = (PhaseFilterType)cmbFilterType.SelectedIndex;
double cutoffFreq = double.Parse(txtCutoffFreq.Text);
hologramProcessor.ApplyPhaseFilter(filterType, cutoffFreq, chkAdaptiveFilter.Checked);
}
private void PhaseUnwrap_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentPhaseMap == null)
{
MessageBox.Show("请先进行全息再现!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
UpdateStatus("正在进行相位去包裹...");
EnableControls(false);
UnwrapMethod unwrapMethod = (UnwrapMethod)cmbUnwrapMethod.SelectedIndex;
hologramProcessor.UnwrapPhase(unwrapMethod, chkUseMask.Checked, chkSmoothPhase.Checked, chkRemoveSpikes.Checked);
}
private void OneClickProcess_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentHologram == null)
{
MessageBox.Show("请先加载全息图!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
UpdateStatus("正在一键处理...");
EnableControls(false);
UpdateParameters();
hologramProcessor.ProcessAll(
chkBackgroundSubtraction.Checked,
chkContrastEnhancement.Checked,
chkNoiseReduction.Checked,
trackBarFilterStrength.Value,
reconstructionParams,
(PhaseFilterType)cmbFilterType.SelectedIndex,
double.Parse(txtCutoffFreq.Text),
chkAdaptiveFilter.Checked,
(UnwrapMethod)cmbUnwrapMethod.SelectedIndex,
chkUseMask.Checked,
chkSmoothPhase.Checked,
chkRemoveSpikes.Checked
);
}
private void SavePhaseMap_Click(object sender, EventArgs e)
{
if (hologramProcessor.CurrentPhaseMap == null)
{
MessageBox.Show("没有相位图可保存!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Filter = "相位图文件|*.phs|图像文件|*.bmp;*.png|所有文件|*.*";
dialog.Title = "保存相位图";
dialog.FileName = "phase_map.phs";
if (dialog.ShowDialog() == DialogResult.OK)
{
hologramProcessor.SavePhaseMap(dialog.FileName);
UpdateStatus("相位图保存完成");
}
}
}
#endregion
#region 辅助方法
private void UpdateParameters()
{
hologramParams.Wavelength = double.Parse(txtWavelength.Text) * 1e-9;
hologramParams.PixelSize = double.Parse(txtPixelSize.Text) * 1e-6;
hologramParams.Distance = double.Parse(txtDistance.Text) * 1e-3;
reconstructionParams.Method = ReconstructionMethod.Fresnel;
reconstructionParams.UseBandPassFilter = true;
reconstructionParams.FilterRadius = double.Parse(txtCutoffFreq.Text);
reconstructionParams.UsePhaseUnwrapping = true;
reconstructionParams.UnwrapMethod = (UnwrapMethod)cmbUnwrapMethod.SelectedIndex;
}
private void HologramProcessor_ProgressChanged(object sender, int progress)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<int>(HologramProcessor_ProgressChanged), progress);
return;
}
progressBar.Value = progress;
}
private void HologramProcessor_ProcessingCompleted(object sender, ProcessingResult result)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<object, ProcessingResult>(HologramProcessor_ProcessingCompleted), sender, result);
return;
}
EnableControls(true);
if (result.Success)
{
// 更新显示
if (result.ReconstructedImage != null)
{
intensityDisplay.DisplayIntensity(result.ReconstructedImage);
}
if (result.PhaseMap != null)
{
phaseDisplay.DisplayPhase(result.PhaseMap);
lblPhaseRange.Text = $"相位范围: [{result.PhaseMin:F2}, {result.PhaseMax:F2}] rad";
}
lblProcessingTime.Text = $"处理时间: {result.ProcessingTime:F2} ms";
UpdateStatus("处理完成");
}
else
{
MessageBox.Show($"处理失败: {result.ErrorMessage}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
UpdateStatus("处理失败");
}
}
private void EnableControls(bool enable)
{
progressBar.Visible = !enable;
foreach (Control control in this.Controls)
{
if (control is MenuStrip || control is ToolStrip || control is StatusStrip)
{
control.Enabled = enable;
}
}
}
private void UpdateStatus(string message)
{
if (statusLabel.InvokeRequired)
{
statusLabel.Invoke(new Action<string>(UpdateStatus), message);
return;
}
statusLabel.Text = message;
}
#endregion
// 控件声明
private StatusStrip statusStrip;
private ToolStripStatusLabel statusLabel;
private ToolStripProgressBar progressBar;
private TextBox txtWavelength;
private TextBox txtPixelSize;
private TextBox txtDistance;
private Label lblImageSizeValue;
private CheckBox chkBackgroundSubtraction;
private CheckBox chkContrastEnhancement;
private CheckBox chkNoiseReduction;
private TrackBar trackBarFilterStrength;
private ComboBox cmbFilterType;
private TextBox txtCutoffFreq;
private CheckBox chkAdaptiveFilter;
private ComboBox cmbUnwrapMethod;
private CheckBox chkUseMask;
private CheckBox chkSmoothPhase;
private CheckBox chkRemoveSpikes;
private Label lblProcessingTime;
private Label lblPhaseRange;
}
}
3. 全息处理核心引擎 (Core/HologramProcessor.cs)
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using DigitalHolography.Algorithms;
using DigitalHolography.Models;
using DigitalHolography.Utils;
namespace DigitalHolography.Core
{
public class HologramProcessor
{
public event EventHandler<int> ProgressChanged;
public event EventHandler<ProcessingResult> ProcessingCompleted;
public Bitmap CurrentHologram { get; private set; }
public ComplexNumber[,] CurrentComplexField { get; private set; }
public double[,] CurrentPhaseMap { get; private set; }
public double[,] CurrentIntensityMap { get; private set; }
public double[,] CurrentUnwrappedPhase { get; private set; }
private HologramParams hologramParams;
private ReconstructionParams reconstructionParams;
public HologramProcessor()
{
hologramParams = new HologramParams();
reconstructionParams = new ReconstructionParams();
}
public void LoadHologram(Bitmap hologram)
{
CurrentHologram = hologram;
hologramParams.ImageWidth = hologram.Width;
hologramParams.ImageHeight = hologram.Height;
}
public void Preprocess(bool backgroundSubtraction, bool contrastEnhancement,
bool noiseReduction, int filterStrength)
{
ThreadPool.QueueUserWorkItem(state =>
{
try
{
ReportProgress(0);
Bitmap processedHologram = (Bitmap)CurrentHologram.Clone();
// 背景减除
if (backgroundSubtraction)
{
ReportProgress(20);
Preprocessing.SubtractBackground(processedHologram);
}
// 对比度增强
if (contrastEnhancement)
{
ReportProgress(40);
Preprocessing.EnhanceContrast(processedHologram);
}
// 噪声抑制
if (noiseReduction)
{
ReportProgress(60);
Preprocessing.ReduceNoise(processedHologram, filterStrength);
}
CurrentHologram = processedHologram;
ReportProgress(100);
CompleteProcessing(true, "预处理完成", null, null);
}
catch (Exception ex)
{
CompleteProcessing(false, "预处理失败", null, null, ex.Message);
}
});
}
public void Reconstruct(ReconstructionParams parameters)
{
reconstructionParams = parameters;
ThreadPool.QueueUserWorkItem(state =>
{
try
{
ReportProgress(0);
// 转换为复数场
ReportProgress(10);
ComplexNumber[,] complexField = ImageConverter.BitmapToComplex(CurrentHologram);
// 傅里叶变换到频域
ReportProgress(20);
ComplexNumber[,] frequencyDomain = FourierTransform.FFT2D(complexField);
// 应用带通滤波
if (reconstructionParams.UseBandPassFilter)
{
ReportProgress(30);
BandPassFilter.Apply(frequencyDomain, reconstructionParams.FilterRadius);
}
// 逆傅里叶变换回空域
ReportProgress(40);
ComplexNumber[,] reconstructedField = FourierTransform.IFFT2D(frequencyDomain);
// 菲涅尔衍射传播
ReportProgress(50);
ComplexNumber[,] propagatedField = FresnelReconstruction.Propagate(
reconstructedField,
hologramParams.Wavelength,
hologramParams.PixelSize,
hologramParams.Distance,
hologramParams.ImageWidth,
hologramParams.ImageHeight
);
CurrentComplexField = propagatedField;
// 计算强度和相位
ReportProgress(70);
CurrentIntensityMap = CalculateIntensity(propagatedField);
CurrentPhaseMap = CalculatePhase(propagatedField);
// 相位滤波
ReportProgress(80);
PhaseFilter.ApplyLowPassFilter(CurrentPhaseMap, 0.1);
// 相位去包裹
if (reconstructionParams.UsePhaseUnwrapping)
{
ReportProgress(90);
CurrentUnwrappedPhase = PhaseUnwrapper.Unwrap(
CurrentPhaseMap,
reconstructionParams.UnwrapMethod
);
}
ReportProgress(100);
// 准备结果
Bitmap reconstructedImage = ImageConverter.ComplexToBitmap(propagatedField);
double phaseMin = GetMinValue(CurrentPhaseMap);
double phaseMax = GetMaxValue(CurrentPhaseMap);
CompleteProcessing(true, "全息再现完成", reconstructedImage, CurrentPhaseMap, "", phaseMin, phaseMax);
}
catch (Exception ex)
{
CompleteProcessing(false, "全息再现失败", null, null, ex.Message);
}
});
}
public void ApplyPhaseFilter(PhaseFilterType filterType, double cutoffFreq, bool adaptive)
{
ThreadPool.QueueUserWorkItem(state =>
{
try
{
ReportProgress(0);
if (CurrentPhaseMap == null)
{
CompleteProcessing(false, "没有相位图", null, null, "请先进行全息再现");
return;
}
ReportProgress(50);
double[,] filteredPhase = PhaseFilter.Apply(
CurrentPhaseMap,
filterType,
cutoffFreq,
adaptive
);
CurrentPhaseMap = filteredPhase;
ReportProgress(100);
CompleteProcessing(true, "相位滤波完成", null, filteredPhase);
}
catch (Exception ex)
{
CompleteProcessing(false, "相位滤波失败", null, null, ex.Message);
}
});
}
public void UnwrapPhase(UnwrapMethod method, bool useMask, bool smooth, bool removeSpikes)
{
ThreadPool.QueueUserWorkItem(state =>
{
try
{
ReportProgress(0);
if (CurrentPhaseMap == null)
{
CompleteProcessing(false, "没有相位图", null, null, "请先进行全息再现");
return;
}
ReportProgress(30);
// 创建掩模(如果需要)
bool[,] mask = null;
if (useMask)
{
mask = CreateMask(CurrentIntensityMap);
}
ReportProgress(60);
// 去包裹
double[,] unwrappedPhase = PhaseUnwrapper.Unwrap(
CurrentPhaseMap,
method,
mask
);
// 平滑处理
if (smooth)
{
unwrappedPhase = PhaseFilter.Smooth(unwrappedPhase, 3);
}
// 去除尖峰
if (removeSpikes)
{
unwrappedPhase = RemoveSpikes(unwrappedPhase);
}
CurrentUnwrappedPhase = unwrappedPhase;
ReportProgress(100);
CompleteProcessing(true, "相位去包裹完成", null, unwrappedPhase);
}
catch (Exception ex)
{
CompleteProcessing(false, "相位去包裹失败", null, null, ex.Message);
}
});
}
public void ProcessAll(bool backgroundSubtraction, bool contrastEnhancement,
bool noiseReduction, int filterStrength,
ReconstructionParams reconstructParams,
PhaseFilterType filterType, double cutoffFreq, bool adaptiveFilter,
UnwrapMethod unwrapMethod, bool useMask, bool smooth, bool removeSpikes)
{
ThreadPool.QueueUserWorkItem(state =>
{
Stopwatch stopwatch = Stopwatch.StartNew();
try
{
// 1. 预处理
ReportProgress(10);
Preprocess(backgroundSubtraction, contrastEnhancement, noiseReduction, filterStrength);
// 2. 全息再现
ReportProgress(30);
Reconstruct(reconstructParams);
// 3. 相位滤波
ReportProgress(60);
ApplyPhaseFilter(filterType, cutoffFreq, adaptiveFilter);
// 4. 相位去包裹
ReportProgress(80);
UnwrapPhase(unwrapMethod, useMask, smooth, removeSpikes);
stopwatch.Stop();
ReportProgress(100);
CompleteProcessing(true, "一键处理完成", null, CurrentUnwrappedPhase, "", 0, 0, stopwatch.ElapsedMilliseconds);
}
catch (Exception ex)
{
stopwatch.Stop();
CompleteProcessing(false, "一键处理失败", null, null, ex.Message, 0, 0, stopwatch.ElapsedMilliseconds);
}
});
}
public void SavePhaseMap(string filePath)
{
if (CurrentPhaseMap == null)
{
throw new InvalidOperationException("没有相位图可保存");
}
// 保存相位图为图像文件
Bitmap phaseImage = ImageConverter.PhaseToBitmap(CurrentPhaseMap);
phaseImage.Save(filePath);
}
#region 私有方法
private double[,] CalculateIntensity(ComplexNumber[,] complexField)
{
int width = complexField.GetLength(0);
int height = complexField.GetLength(1);
double[,] intensity = new double[width, height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
intensity[i, j] = complexField[i, j].MagnitudeSquared;
}
}
return intensity;
}
private double[,] CalculatePhase(ComplexNumber[,] complexField)
{
int width = complexField.GetLength(0);
int height = complexField.GetLength(1);
double[,] phase = new double[width, height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
phase[i, j] = complexField[i, j].Phase;
}
}
return phase;
}
private bool[,] CreateMask(double[,] intensity)
{
int width = intensity.GetLength(0);
int height = intensity.GetLength(1);
bool[,] mask = new bool[width, height];
double threshold = GetMeanValue(intensity) * 0.5;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
mask[i, j] = intensity[i, j] > threshold;
}
}
return mask;
}
private double[,] RemoveSpikes(double[,] phase)
{
int width = phase.GetLength(0);
int height = phase.GetLength(1);
double[,] smoothed = new double[width, height];
for (int i = 1; i < width - 1; i++)
{
for (int j = 1; j < height - 1; j++)
{
double[] neighbors = {
phase[i-1, j], phase[i+1, j],
phase[i, j-1], phase[i, j+1]
};
double median = GetMedian(neighbors);
double diff = Math.Abs(phase[i, j] - median);
if (diff > Math.PI) // 超过π认为是尖峰
{
smoothed[i, j] = median;
}
else
{
smoothed[i, j] = phase[i, j];
}
}
}
return smoothed;
}
private double GetMinValue(double[,] array)
{
double min = double.MaxValue;
int width = array.GetLength(0);
int height = array.GetLength(1);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
if (array[i, j] < min)
{
min = array[i, j];
}
}
}
return min;
}
private double GetMaxValue(double[,] array)
{
double max = double.MinValue;
int width = array.GetLength(0);
int height = array.GetLength(1);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
if (array[i, j] > max)
{
max = array[i, j];
}
}
}
return max;
}
private double GetMeanValue(double[,] array)
{
double sum = 0;
int width = array.GetLength(0);
int height = array.GetLength(1);
int count = 0;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
sum += array[i, j];
count++;
}
}
return sum / count;
}
private double GetMedian(double[] values)
{
Array.Sort(values);
int n = values.Length;
if (n % 2 == 0)
{
return (values[n / 2 - 1] + values[n / 2]) / 2.0;
}
else
{
return values[n / 2];
}
}
private void ReportProgress(int progress)
{
ProgressChanged?.Invoke(this, progress);
}
private void CompleteProcessing(bool success, string message, Bitmap image, double[,] phase,
string error = "", double phaseMin = 0, double phaseMax = 0, long processingTime = 0)
{
ProcessingResult result = new ProcessingResult
{
Success = success,
Message = message,
ReconstructedImage = image,
PhaseMap = phase,
ErrorMessage = error,
PhaseMin = phaseMin,
PhaseMax = phaseMax,
ProcessingTime = processingTime
};
ProcessingCompleted?.Invoke(this, result);
}
#endregion
}
public class ProcessingResult
{
public bool Success { get; set; }
public string Message { get; set; }
public Bitmap ReconstructedImage { get; set; }
public double[,] PhaseMap { get; set; }
public string ErrorMessage { get; set; }
public double PhaseMin { get; set; }
public double PhaseMax { get; set; }
public long ProcessingTime { get; set; }
}
}
4. 菲涅尔衍射再现 (Core/FresnelReconstruction.cs)
using System;
using DigitalHolography.Utils;
using DigitalHolography.Models;
namespace DigitalHolography.Core
{
public static class FresnelReconstruction
{
public static ComplexNumber[,] Propagate(ComplexNumber[,] inputField,
double wavelength,
double pixelSize,
double distance,
int width,
int height)
{
int nx = width;
int ny = height;
ComplexNumber[,] outputField = new ComplexNumber[nx, ny];
// 计算空间频率
double fx0 = 1.0 / (nx * pixelSize);
double fy0 = 1.0 / (ny * pixelSize);
// 计算传递函数
ComplexNumber[,] transferFunction = new ComplexNumber[nx, ny];
for (int i = 0; i < nx; i++)
{
for (int j = 0; j < ny; j++)
{
// 计算空间频率
double fx = (i - nx / 2) * fx0;
double fy = (j - ny / 2) * fy0;
// 计算波数
double k = 2 * Math.PI / wavelength;
// 计算传递函数
double phase = -Math.PI * wavelength * distance * (fx * fx + fy * fy);
transferFunction[i, j] = ComplexNumber.FromPolar(1.0, phase);
}
}
// 应用传递函数
for (int i = 0; i < nx; i++)
{
for (int j = 0; j < ny; j++)
{
outputField[i, j] = inputField[i, j] * transferFunction[i, j];
}
}
return outputField;
}
public static ComplexNumber[,] ConvolutionMethod(ComplexNumber[,] inputField,
double wavelength,
double pixelSize,
double distance,
int width,
int height)
{
int nx = width;
int ny = height;
ComplexNumber[,] outputField = new ComplexNumber[nx, ny];
// 计算脉冲响应
ComplexNumber[,] impulseResponse = new ComplexNumber[nx, ny];
double k = 2 * Math.PI / wavelength;
for (int i = 0; i < nx; i++)
{
for (int j = 0; j < ny; j++)
{
double x = (i - nx / 2) * pixelSize;
double y = (j - ny / 2) * pixelSize;
double r = Math.Sqrt(x * x + y * y + distance * distance);
double magnitude = 1.0 / r;
double phase = k * r;
impulseResponse[i, j] = ComplexNumber.FromPolar(magnitude, phase);
}
}
// 卷积运算
for (int i = 0; i < nx; i++)
{
for (int j = 0; j < ny; j++)
{
ComplexNumber sum = ComplexNumber.Zero;
for (int m = 0; m < nx; m++)
{
for (int n = 0; n < ny; n++)
{
int ii = (i + m) % nx;
int jj = (j + n) % ny;
sum += inputField[m, n] * impulseResponse[ii, jj];
}
}
outputField[i, j] = sum;
}
}
return outputField;
}
}
}
5. 相位去包裹算法 (Algorithms/GoldsteinUnwrap.cs)
using System;
using System.Collections.Generic;
using DigitalHolography.Utils;
namespace DigitalHolography.Algorithms
{
public static class GoldsteinUnwrap
{
public static double[,] Unwrap(double[,] wrappedPhase, bool[,] mask = null)
{
int width = wrappedPhase.GetLength(0);
int height = wrappedPhase.GetLength(1);
// 创建残差点阵
int[,] residues = FindResidues(wrappedPhase);
// 创建分支切割
List<BranchCut> branchCuts = CreateBranchCuts(residues, width, height);
// 应用分支切割进行去包裹
double[,] unwrappedPhase = ApplyBranchCuts(wrappedPhase, branchCuts, mask);
return unwrappedPhase;
}
private static int[,] FindResidues(double[,] phase)
{
int width = phase.GetLength(0);
int height = phase.GetLength(1);
int[,] residues = new int[width, height];
for (int i = 0; i < width - 1; i++)
{
for (int j = 0; j < height - 1; j++)
{
// 计算四个方向的相位差
double d1 = phase[i + 1, j] - phase[i, j];
double d2 = phase[i, j + 1] - phase[i, j];
double d3 = phase[i + 1, j + 1] - phase[i + 1, j];
double d4 = phase[i, j + 1] - phase[i + 1, j + 1];
// 标准化相位差到[-π, π]
d1 = NormalizePhaseDifference(d1);
d2 = NormalizePhaseDifference(d2);
d3 = NormalizePhaseDifference(d3);
d4 = NormalizePhaseDifference(d4);
// 计算残差
double residue = d1 + d2 - d3 - d4;
// 如果残差接近±2π,标记为残差点
if (Math.Abs(residue + 2 * Math.PI) < 0.1)
{
residues[i, j] = -1; // 负残差
}
else if (Math.Abs(residue - 2 * Math.PI) < 0.1)
{
residues[i, j] = 1; // 正残差
}
}
}
return residues;
}
private static double NormalizePhaseDifference(double diff)
{
while (diff > Math.PI) diff -= 2 * Math.PI;
while (diff < -Math.PI) diff += 2 * Math.PI;
return diff;
}
private static List<BranchCut> CreateBranchCuts(int[,] residues, int width, int height)
{
List<BranchCut> branchCuts = new List<BranchCut>();
bool[,] visited = new bool[width, height];
// 找到所有残差点
List<Point> positiveResidues = new List<Point>();
List<Point> negativeResidues = new List<Point>();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
if (residues[i, j] == 1)
{
positiveResidues.Add(new Point(i, j));
}
else if (residues[i, j] == -1)
{
negativeResidues.Add(new Point(i, j));
}
}
}
// 为每个正残差找到最近的负残差
foreach (Point pos in positiveResidues)
{
Point nearestNeg = FindNearestNegativeResidue(pos, negativeResidues, visited);
if (nearestNeg.X >= 0)
{
BranchCut cut = new BranchCut(pos, nearestNeg);
branchCuts.Add(cut);
visited[pos.X, pos.Y] = true;
visited[nearestNeg.X, nearestNeg.Y] = true;
}
}
return branchCuts;
}
private static Point FindNearestNegativeResidue(Point pos, List<Point> negativeResidues, bool[,] visited)
{
Point nearest = new Point(-1, -1);
double minDist = double.MaxValue;
foreach (Point neg in negativeResidues)
{
if (!visited[neg.X, neg.Y])
{
double dist = Math.Sqrt((pos.X - neg.X) * (pos.X - neg.X) +
(pos.Y - neg.Y) * (pos.Y - neg.Y));
if (dist < minDist)
{
minDist = dist;
nearest = neg;
}
}
}
return nearest;
}
private static double[,] ApplyBranchCuts(double[,] wrappedPhase, List<BranchCut> branchCuts, bool[,] mask)
{
int width = wrappedPhase.GetLength(0);
int height = wrappedPhase.GetLength(1);
double[,] unwrappedPhase = new double[width, height];
// 复制原始相位
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
unwrappedPhase[i, j] = wrappedPhase[i, j];
}
}
// 创建积分路径,避开分支切割
for (int i = 1; i < width; i++)
{
for (int j = 1; j < height; j++)
{
if (mask != null && !mask[i, j]) continue;
// 检查是否跨越分支切割
bool crossesCut = false;
foreach (BranchCut cut in branchCuts)
{
if (CrossesBranchCut(i, j, cut))
{
crossesCut = true;
break;
}
}
if (!crossesCut)
{
// 计算相位差并调整
double diff = unwrappedPhase[i, j] - unwrappedPhase[i - 1, j];
while (diff > Math.PI) diff -= 2 * Math.PI;
while (diff < -Math.PI) diff += 2 * Math.PI;
unwrappedPhase[i, j] = unwrappedPhase[i - 1, j] + diff;
}
}
}
return unwrappedPhase;
}
private static bool CrossesBranchCut(int x, int y, BranchCut cut)
{
// 简化检查:如果点在分支切割附近
double dist = Math.Sqrt((x - cut.Start.X) * (x - cut.Start.X) +
(y - cut.Start.Y) * (y - cut.Start.Y));
return dist < 2.0; // 2像素范围内认为是跨越
}
}
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
}
public struct BranchCut
{
public Point Start, End;
public BranchCut(Point start, Point end)
{
Start = start;
End = end;
}
}
}
6. 复数运算工具 (Utils/ComplexNumber.cs)
using System;
namespace DigitalHolography.Utils
{
public struct ComplexNumber
{
public double Real { get; set; }
public double Imaginary { get; set; }
public static ComplexNumber Zero => new ComplexNumber(0, 0);
public static ComplexNumber One => new ComplexNumber(1, 0);
public static ComplexNumber I => new ComplexNumber(0, 1);
public ComplexNumber(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
public static ComplexNumber FromPolar(double magnitude, double phase)
{
return new ComplexNumber(
magnitude * Math.Cos(phase),
magnitude * Math.Sin(phase)
);
}
public double Magnitude => Math.Sqrt(Real * Real + Imaginary * Imaginary);
public double MagnitudeSquared => Real * Real + Imaginary * Imaginary;
public double Phase => Math.Atan2(Imaginary, Real);
// 运算符重载
public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber(a.Real + b.Real, a.Imaginary + b.Imaginary);
}
public static ComplexNumber operator -(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber(a.Real - b.Real, a.Imaginary - b.Imaginary);
}
public static ComplexNumber operator *(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber(
a.Real * b.Real - a.Imaginary * b.Imaginary,
a.Real * b.Imaginary + a.Imaginary * b.Real
);
}
public static ComplexNumber operator *(ComplexNumber a, double scalar)
{
return new ComplexNumber(a.Real * scalar, a.Imaginary * scalar);
}
public static ComplexNumber operator /(ComplexNumber a, ComplexNumber b)
{
double denominator = b.Real * b.Real + b.Imaginary * b.Imaginary;
return new ComplexNumber(
(a.Real * b.Real + a.Imaginary * b.Imaginary) / denominator,
(a.Imaginary * b.Real - a.Real * b.Imaginary) / denominator
);
}
public ComplexNumber Conjugate()
{
return new ComplexNumber(Real, -Imaginary);
}
public ComplexNumber Exp()
{
double expReal = Math.Exp(Real);
return new ComplexNumber(
expReal * Math.Cos(Imaginary),
expReal * Math.Sin(Imaginary)
);
}
public override string ToString()
{
return $"{Real:F3} {(Imaginary >= 0 ? "+" : "")}{Imaginary:F3}i";
}
}
}
7. 项目文件 (DigitalHolography.csproj)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{YOUR-PROJECT-GUID}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>DigitalHolography</RootNamespace>
<AssemblyName>DigitalHolography</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Drawing" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Numerics" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="MainForm.cs" />
<Compile Include="MainForm.Designer.cs" />
<Compile Include="Core\HologramProcessor.cs" />
<Compile Include="Core\FresnelReconstruction.cs" />
<Compile Include="Core\PhaseFilter.cs" />
<Compile Include="Core\PhaseUnwrapper.cs" />
<Compile Include="Core\Preprocessing.cs" />
<Compile Include="Algorithms\FourierTransform.cs" />
<Compile Include="Algorithms\GoldsteinUnwrap.cs" />
<Compile Include="Algorithms\QualityGuidedUnwrap.cs" />
<Compile Include="Algorithms\LeastSquaresUnwrap.cs" />
<Compile Include="Algorithms\BandPassFilter.cs" />
<Compile Include="Models\HologramParams.cs" />
<Compile Include="Models\ReconstructionParams.cs" />
<Compile Include="Models\PhaseMap.cs" />
<Compile Include="Visualization\HologramViewer.cs" />
<Compile Include="Visualization\PhaseDisplay.cs" />
<Compile Include="Visualization\IntensityDisplay.cs" />
<Compile Include="Utils\ComplexNumber.cs" />
<Compile Include="Utils\ImageConverter.cs" />
<Compile Include="Utils\PerformanceMonitor.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
参考代码 数字全息图的预处理、全息再现、相位滤波、相位去包裹 www.youwenfan.com/contentcsv/112855.html
三、系统功能说明
1. 核心算法流程
原始全息图 → 预处理 → 傅里叶变换 → 频域滤波 → 逆傅里叶变换 → 菲涅尔传播 → 相位提取 → 相位滤波 → 相位去包裹 → 3D形貌
2. 支持的处理方法
| 处理步骤 |
支持的方法 |
| 全息再现 |
菲涅尔衍射、卷积法、角谱法 |
| 相位滤波 |
带通滤波、低通滤波、高通滤波、高斯滤波、自适应滤波 |
| 相位去包裹 |
Goldstein算法、质量引导、最小二乘法、路径跟踪法 |
| 预处理 |
背景减除、对比度增强、噪声抑制、边缘增强 |
3. 关键参数设置
| 参数 |
典型值 |
说明 |
| 波长 |
632.8 nm |
He-Ne激光 |
| 像素尺寸 |
3.45 μm |
CCD像素大小 |
| 再现距离 |
50-200 mm |
根据实验设置 |
| 滤波半径 |
0.3-0.7 |
频域滤波半径 |
| 图像尺寸 |
1024×1024 |
处理分辨率 |
4. 性能指标
| 指标 |
数值 |
| 处理速度 |
1024×1024图像 < 1秒 |
| 内存占用 |
< 500 MB |
| 精度 |
相位精度 < 0.01 rad |
| 支持格式 |
BMP、JPG、PNG、TIFF |
5. 应用场景
- 显微全息:细胞、组织切片的三维成像
- 干涉计量:表面形貌测量、形变分析
- 粒子场测量:微粒大小、分布、运动轨迹
- 生物医学:红细胞形态、DNA分子成像
- 工业检测:微机电系统(MEMS)、精密零件检测
6. 扩展建议
- GPU加速:使用CUDA/OpenCL加速FFT运算
- 实时处理:集成摄像头实现实时全息显示
- 3D可视化:集成HelixToolkit显示3D表面
- 自动化测量:自动对焦、自动曝光、自动分析
- 数据导出:导出STL、OBJ等3D模型格式