扫描模式
点位扫描:定一个点 → 移过去停下 → 拍一张 X 光图(查特定位置)
连续扫描:不停车一直走 → 边走边连续拍 X 光图(查整片区域)
点位扫描模式
给芯片的某个固定位置拍特写:
你告诉设备「去 X=50,Y=0 这个位置」,设备精准移动过去,停稳,然后拍一张 X 光图像,检测这个点有没有缺陷。
关键特点
有固定目标:靠 TargetX、TargetY 定位
移动后停止:到点就不动了
单次采图:只拍一张图
用途:芯片特定位置复查、定点检测、精准缺陷排查
连续扫描模式(全域检测)
就像给芯片从头到尾扫一遍:设备不停车,以设定的速度一直匀速移动,边走边不停拍 X 光图,直到走完整个行程,完成整片芯片的检测。
关键特点
无固定目标:靠 ScanSpeed 控制移动速度
持续移动:全程不停车
循环采图:不停拍图
用途:芯片全域扫描、大面积缺陷筛查、批量检测
(半导体 X 光检测)的真实用途
点位扫描
工程师发现芯片某个位置可能有缺陷,输入坐标,让设备精准定位到这个点,拍高清 X 光图确认缺陷。
连续扫描
生产线上批量检测芯片,让设备自动从头走到尾,全程拍图,快速筛查整片芯片的所有缺陷。
1
csharp
public bool CanEditParam
=> Status == STATUS_READY || Status == STATUS_STOP || Status == STATUS_FAULT || Status == STATUS_LIMIT;
//=>:表达式属性,意思是直接返回后面的判断结果
csharp
当设备状态 是 以下4种情况之一时:
1. 已就绪(STATUS_READY)
2. 已停止(STATUS_STOP)
3. 故障(STATUS_FAULT)
4. 限位报警(STATUS_LIMIT)
→ CanEditParam = true (可以修改参数)
其他所有状态(运行中、点位到位、检测完成)
→ CanEditParam = false (禁止修改参数)
2
这是一段**「广播监听」代码**:
专门监听扫描开始/停止的消息 ,收到消息就打印日志提示用户 → 参数已锁定/已解锁。
csharp
// 注册一个消息监听器(打开收音机)
WeakReferenceMessenger.Default.Register<ValueChangedMessage<string>>(this, (sender, msg) =>
{
// 收到消息:X光扫描开始
if (msg.Value == "XrayScanStart")
{
AddLog("参数已锁定,不可修改"); // 打印日志提示
}
// 收到消息:X光扫描停止
if (msg.Value == "XrayScanStop")
{
AddLog("参数已解锁"); // 打印日志提示
}
});
关键名词解释
WeakReferenceMessenger
MVVM工具包的全局广播器 ,可以在代码的任何地方发消息 ,也可以在任何地方收消息。Register
注册监听 = 打开收音机,等待接收指定的广播。ValueChangedMessage<string>
监听文本类型的消息 (这里是XrayScanStart/XrayScanStop)。
二、谁发的消息?(发信人)
在 RunScan 方法里,扫描开始和结束时主动发消息:
csharp
// 扫描开始 → 发消息
WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>("XrayScanStart"));
// 扫描结束 → 发消息
finally
{
WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>("XrayScanStop"));
}
三、这段代码只做一件事
✅ 收到扫描开始 → 打印日志:参数已锁定
✅ 收到扫描结束 → 打印日志:参数已解锁
四、为什么注释掉 CanEditParam = true/false?
csharp
public bool CanEditParam => 状态判断;
这是只读属性,不能赋值!
所以这两行被注释掉了,只保留日志提示功能。
真正的参数锁定/解锁,是靠
Status状态自动控制的 ,这段代码只负责提示用户,不负责控制!
五、通俗比喻
-
RunScan= 广播电台扫描开始时喊:
XrayScanStart扫描结束时喊:
XrayScanStop -
这段代码 = 收音机
听到电台的声音,就立刻播报:
参数已锁定,不可修改/参数已解锁
六、极简总结
- 这是消息监听,接收扫描的开始/停止通知;
- 唯一作用:打印日志提示用户参数状态;
- 不控制参数锁定,纯提示功能;
- 是MVVM模式中解耦代码的标准写法。
3
csharp
_scanAxis = new XYScanAxis();
_halconWinFormsControl = halconControl ?? throw new ArgumentNullException(nameof(halconControl));
TestImageC = new RelayCommand(TestShowImage);
PointScanC = new RelayCommand(StartPointScan, CanStartScan);
ContinueScanC = new RelayCommand(StartContinueScan, CanStartScan);
//StartC = new RelayCommand(Start, CanStart);
StopC = new RelayCommand(NormalStop, CanStop);
EmergencyStopC = new RelayCommand(EmergencyStop);
ResetC = new RelayCommand(ResetAlarm, CanReset);
SimulateXrayFaultC = new RelayCommand(SimulateXrayHardwareFault);
Loading();
StartAxisStatusRefresh();
_scanAxis:设备的 XY 轴电机控制器,管移动、定位、扫描
_scanAxis = XY 运动轴控制器
负责指挥设备的机械平台前后左右移动,是点位扫描、连续扫描能运行的核心硬件逻辑层。
二、通俗比喻
_scanAxis = 设备的司机 + 导航 + 安全员
导航:知道要去哪个坐标(TargetX/Y)
司机:负责开车移动(点位 / 连续扫描)
安全员:防止撞车、急停、报警保护
三、极简总结
管移动:点位定位、连续行走
管位置:实时上报 X/Y 坐标
管状态:运行 / 到位 / 报警
管安全:急停、限位、复位
4
csharp
Application.Current.Dispatcher.Invoke(() =>
{
_halconWinFormsControl.HalconWindow.ClearWindow();
using (HImage rawImage = new HImage())
{
int grayBase = 80 + ExposureTime / 10;
rawImage.GenImageConst("byte", 800, 500);
using (HImage brightImage = rawImage.ScaleImage(1.0, grayBase - 128))
{
using (HImage smoothImage = brightImage.MeanImage(3, 3))
{
using (HImage enhanceImage = smoothImage.ScaleImage(1.5, 0.0))
{
_halconWinFormsControl.HalconWindow.DispObj(enhanceImage);
_halconWinFormsControl.HalconWindow.SetColor("green");
_halconWinFormsControl.HalconWindow.SetLineWidth(2);
_halconWinFormsControl.HalconWindow.DispRectangle1(120.0, 120, 380, 680);
}
}
}
}
AddLog($"X光图像采集成功|曝光:{ExposureTime}ms");
在界面的Halcon窗口中,清空画面 → 用曝光参数生成模拟X光图像 → 做滤波/增强处理 → 显示图像 → 画出绿色检测框 → 打印成功日志
(完全模拟真实X光探测器采图、图像处理的流程)
1. 跨线程操作UI
csharp
Application.Current.Dispatcher.Invoke(() => { 全部代码 });
- 作用 :切回UI主线程更新界面
- 原因:扫描/图像处理在后台线程运行,不能直接改界面,必须用这句调用UI线程
2. 清空图像窗口
csharp
_halconWinFormsControl.HalconWindow.ClearWindow();
- 清空上一次的X光图像/画面,防止画面重叠、残留
3. 创建基础X光图像(模拟采集)
csharp
using (HImage rawImage = new HImage())
{
// 用曝光时间计算图像基础亮度
int grayBase = 80 + ExposureTime / 10;
// 创建 800x500 大小的空白灰度图(模拟X光原始图像)
rawImage.GenImageConst("byte", 800, 500);
using:自动释放图像内存,防止卡顿/内存泄漏grayBase:曝光时间决定图像亮度(曝光越高,图越亮)GenImageConst:生成模拟的X光原始底片
4. 三步图像处理(工业X光标准流程)
第一步:调整亮度(绑定曝光参数)
csharp
using (HImage brightImage = rawImage.ScaleImage(1.0, grayBase - 128))
- 根据曝光时间,把图像调到合适亮度
- 你界面改
ExposureTime,这里实时生效
第二步:平滑去噪(滤波)
csharp
using (HImage smoothImage = brightImage.MeanImage(3, 3))
- 均值滤波,去掉图像噪点
- 模拟真实X光图像的平滑效果,更清晰
第三步:对比度增强
csharp
using (HImage enhanceImage = smoothImage.ScaleImage(1.5, 0.0))
- 增强图像对比度,让芯片缺陷/细节更明显
5. 显示最终图像 + 画检测框
csharp
// 显示处理好的高清X光图像
_halconWinFormsControl.HalconWindow.DispObj(enhanceImage);
// 设置画笔:绿色、2像素宽
_halconWinFormsControl.HalconWindow.SetColor("green");
_halconWinFormsControl.HalconWindow.SetLineWidth(2);
// 画固定的检测矩形框(X光检测的核心区域)
_halconWinFormsControl.HalconWindow.DispRectangle1(120.0, 120, 380, 680);
- 界面上你看到的绿色方框,就是这行画的
- 代表半导体芯片的检测区域
6. 打印日志
csharp
AddLog($"X光图像采集成功|曝光:{ExposureTime}ms");
- 日志框显示采图成功,同步记录当前曝光参数
Dispatcher.Invoke:保证界面能正常刷新图像(跨线程安全)ExposureTime:曝光时间直接控制X光图亮度- 3步图像处理:去噪→调亮度→增强,模拟真实X光成像
- 绿色矩形:芯片检测区域框
- 全程
using:自动释放内存,设备不卡顿