自动对焦流程图.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>自动对焦标定流程图 · AutoFocusTool</title>
  7. <style>
  8. * { box-sizing: border-box; margin: 0; padding: 0; }
  9. body { font-family: "Microsoft YaHei", sans-serif; background: #1e1e1e; color: #ddd; padding: 30px; line-height: 1.6; }
  10. h1 { color: #4ec9b0; font-size: 26px; margin-bottom: 6px; }
  11. h2 { color: #9cdcfe; font-size: 20px; margin: 28px 0 12px; border-left: 4px solid #4ec9b0; padding-left: 10px; }
  12. .sub { color: #888; font-size: 13px; margin-bottom: 20px; }
  13. .flow { display: flex; flex-direction: column; align-items: center; gap: 0; }
  14. .step { background: #2d2d30; border: 2px solid #3c3c3c; border-radius: 8px; padding: 14px 20px; width: 760px; position: relative; }
  15. .step.start { border-color: #1a7f37; background: #14301c; }
  16. .step.phase { border-color: #4ec9b0; background: #18302c; }
  17. .step.decision { border-color: #d79a3c; background: #332a18; border-radius: 30px; }
  18. .step.done { border-color: #0e639c; background: #15293a; }
  19. .step .t { font-size: 16px; font-weight: bold; color: #fff; margin-bottom: 6px; }
  20. .step.phase .t { color: #4ec9b0; }
  21. .step .d { font-size: 13px; color: #bbb; }
  22. .step .p { font-size: 12px; color: #dcdcaa; margin-top: 8px; background: #1e1e1e; padding: 6px 10px; border-radius: 4px; font-family: Consolas, monospace; }
  23. .arrow { width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent; border-top: 14px solid #555; margin: 4px 0; }
  24. .arrow-label { font-size: 12px; color: #888; margin: 2px 0; }
  25. table { border-collapse: collapse; width: 100%; margin: 12px 0; font-size: 13px; }
  26. th, td { border: 1px solid #3c3c3c; padding: 8px 10px; text-align: left; }
  27. th { background: #252526; color: #9cdcfe; }
  28. td.param { font-family: Consolas, monospace; color: #dcdcaa; white-space: nowrap; }
  29. td.val { font-family: Consolas, monospace; color: #4ec9b0; white-space: nowrap; }
  30. .note { background: #332a18; border-left: 4px solid #d79a3c; padding: 10px 14px; margin: 14px 0; font-size: 13px; border-radius: 4px; }
  31. .loop { border: 1px dashed #d79a3c; border-radius: 8px; padding: 10px; width: 800px; margin: 4px 0; }
  32. .loop-title { color: #d79a3c; font-size: 13px; margin-bottom: 8px; text-align: center; }
  33. </style>
  34. </head>
  35. <body>
  36. <h1>自动对焦标定流程图</h1>
  37. <div class="sub">AutoFoczool · CalibrationEngine.CalibrateWell · 生成于 2026-06-16 · 所有参数取自当前代码真实默认值</div>
  38. <h2>一、整体流程(一键全自动初始化)</h2>
  39. <div class="flow">
  40. <div class="step start"><div class="t">开始:一键全自动初始化</div><div class="d">扫描设备 → 连接舱室(相机+串口) → 勾选 well → 点击启动</div>
  41. <div class="p">相机分辨率 2592×1944 · 串口 9600 8N1 · 移动读超时 12000ms / 查询读超时 3000ms</div></div>
  42. <div class="arrow"></div>
  43. <div class="step phase"><div class="t">开灯 + 准备</div><div class="d">OpenLED() → 等待 200ms → 创建 CalibrationEngine</div></div>
  44. <div class="arrow"></div>
  45. <div class="loop">
  46. <div class="loop-title">↓↓↓ 对每个勾选的 well 循环执行 ↓↓↓</div>
  47. <div class="flow">
  48. <div class="step"><div class="t">读取该 well 的 EEPROM 参数</div>
  49. <div class="d">ReadWellHorizontalPos(well) → 水平位置;ReadWellFocusZero(well) → Z零点(仅记录,粗对焦不依赖它)</div></div>
  50. <div class="arrow"></div>
  51. <div class="step"><div class="t">移到 EEPROM 水平位置 + 设中低曝光</div>
  52. <div class="d">HorizontalMoveTo(钳位后位置),失败重试最多 3 次;SetExposure(60)</div>
  53. <div class="p">水平钳位范围 [0, 220000] · 中低曝光 CenterScanExposure=60 (×100µs)</div></div>
  54. <div class="arrow"></div>
  55. <div class="arrow-label">① 粗对焦</div>
  56. <div class="step" style="border-color:#d79a3c;background:#332a18;"><div class="t" style="color:#d79a3c;">⏱ 开扫前停稳(防运动拖影伪峰)</div>
  57. <div class="d">先把 Z 移到扫描起点(60000),再额外等待停稳 + 丢弃到位前残留帧,然后才开始逐层扫描。<br>修复偶发问题:手动复位会把 Z 打到远端,正式标定大行程冲到起点,若不停稳,前几层抓到运动拖影帧会形成伪峰(如74000)带偏对焦。</div>
  58. <div class="p">移到起点 lo=60000 · 额外停稳 CoarseSettleMs=2000ms · 丢1帧</div></div>
  59. <div class="arrow"></div>
  60. <div class="step phase"><div class="t">① 粗对焦(找大致焦面)</div>
  61. <div class="d">固定中心大窗口逐层扫描,中央40%ROI算清晰度(Tenengrad÷mean),取最高分层;每层分数落盘便于排查伪峰</div>
  62. <div class="p">中心 90000 · 半幅 ±30000 → 区间 [60000,120000] · 步距 2000 → 31层 · 每层移动后等 350ms + 丢1帧</div></div>
  63. <div class="arrow"></div>
  64. <div class="arrow-label">② 水平居中</div>
  65. <div class="step phase"><div class="t">② 水平微调居中(优化Y偏移)</div>
  66. <div class="d">以EEPROM水平位为中心小范围扫描,检测well圆,选|Y偏移|最小且完整的位置</div>
  67. <div class="p">半幅 ±2000 (远小于well间距9000的一半) · 9步 → 步距≈500 · 每步等800ms · 居中容差 |Y|<12%</div></div>
  68. <div class="arrow"></div>
  69. <div class="arrow-label">③ 曝光</div>
  70. <div class="step phase"><div class="t">③ 曝光二分(well内ROI测光)</div>
  71. <div class="d">二分搜索曝光值,使well盘面亮度适中(不过曝/不死黑),按 Over/Good/Under 判定</div>
  72. <div class="p">曝光范围 [10, 800] (×100µs) · 每次设曝光后等 max(200, e/5)ms + 丢1帧</div></div>
  73. <div class="arrow"></div>
  74. <div class="arrow-label">④ 精对焦</div>
  75. <div class="step phase"><div class="t">④ 精对焦(围绕粗焦点细扫 + 平滑插值)</div>
  76. <div class="d">围绕粗对焦Z小范围密扫,well圆内0.95r ROI(未检出降级中央40%),3点平滑+抛物线插值求峰顶</div>
  77. <div class="p">半幅 ±6000 · 步距 500 → 25层 · 中心=粗对焦Z · 每层等350ms+丢1帧 · Z钳位[0,125000]</div></div>
  78. <div class="arrow"></div>
  79. <div class="step"><div class="t">移到最清晰Z + 存图 + 记录结果</div>
  80. <div class="d">VerticalMoveTo(focusZ);存标定后BMP;记录 水平/Y偏/曝光/focusZ/峰比</div>
  81. <div class="p">合格判定:|Y偏|<12% 且 检出圆 且 峰比(max/mean)>1.2</div></div>
  82. </div>
  83. </div>
  84. <div class="arrow"></div>
  85. <div class="arrow-label">所有 well 完成</div>
  86. <div class="step done"><div class="t">关灯 + 存档</div><div class="d">CloseLED();写 calibration.json;刷新缓存(转well立即用新结果)</div></div>
  87. </div>
  88. <h2>二、四个对焦阶段参数详表</h2>
  89. <table>
  90. <tr><th>阶段</th><th>电机轴</th><th>中心</th><th>范围/半幅</th><th>步距(脉冲)</th><th>层数/步数</th><th>每步延时</th><th>ROI</th></tr>
  91. <tr><td>①粗对焦</td><td>垂直Z</td><td class="val">90000(固定)</td><td class="val">±30000</td><td class="val">2000</td><td class="val">31</td><td class="val">350ms<br>(开扫前额外停稳2000ms)</td><td>中央40%</td></tr>
  92. <tr><td>②水平居中</td><td>水平</td><td class="val">EEPROM水平位</td><td class="val">±2000</td><td class="val">≈500</td><td class="val">9</td><td class="val">800ms</td><td>well圆检测</td></tr>
  93. <tr><td>③曝光二分</td><td>—</td><td>—</td><td class="val">[10,800]</td><td>二分</td><td class="val">~log₂</td><td class="val">max(200,e/5)ms</td><td>well内</td></tr>
  94. <tr><td>④精对焦</td><td>垂直Z</td><td class="val">粗对焦Z</td><td class="val">±6000</td><td class="val">500</td><td class="val">25</td><td class="val">350ms</td><td>well圆0.95r</td></tr>
  95. </table>
  96. <h2>三、电机行程限位(安全钳位)</h2>
  97. <table>
  98. <tr><th>轴</th><th>下限</th><th>上限</th><th>说明</th></tr>
  99. <tr><td>水平(皿孔旋转)</td><td class="val">0</td><td class="val">220000</td><td>实测16个well EEPROM位置 70800~205800,间距约9000</td></tr>
  100. <tr><td>垂直Z(对焦)</td><td class="val">0</td><td class="val">125000</td><td>旧工程软上限;实测焦面集中在 86000~92000</td></tr>
  101. </table>
  102. <div class="note">所有 HorizontalMoveTo / VerticalMoveTo 调用前都经 ClampH / ClampZ 钳位,越界写日志并截断到边界,防止撞机械限位。</div>
  103. <h2>四、清晰度算法(Sharpness.Compute)</h2>
  104. <table>
  105. <tr><th>项</th><th>值/说明</th></tr>
  106. <tr><td>主指标</td><td class="val">Tenengrad(Sobel梯度幅值平方和)</td></tr>
  107. <tr><td>归一化</td><td class="val">sumSq / 像素数 / mean(除以亮度均值一次方)</td></tr>
  108. <tr><td>峰值精修</td><td>3点滑动平均平滑 + 抛物线插值峰顶</td></tr>
  109. <tr><td>对焦质量</td><td>峰比 max/mean,&lt;1.2 判定弱峰(可能空well/对焦失败)并告警</td></tr>
  110. </table>
  111. <div class="note">注:归一化用 ÷mean 而非 ÷mean²。早期用 ÷mean² 会因 Z 增大时画面变亮而把清晰帧压垮,导致选错最暗最糊层。改 ÷mean 后峰值正确落在真实焦面。</div>
  112. <h2>五、串口协议关键参数</h2>
  113. <table>
  114. <tr><th>项</th><th>值</th></tr>
  115. <tr><td>波特率</td><td class="val">9600 8N1</td></tr>
  116. <tr><td>移动类命令读超时(CMD_MOTOR=0x05)</td><td class="val">12000ms(覆盖大行程移动到位耗时)</td></tr>
  117. <tr><td>查询类命令读超时(握手/读EEPROM/读位置)</td><td class="val">3000ms</td></tr>
  118. <tr><td>电机到位延时 MotorDelayMs</td><td class="val">默认1500ms(扫描时用更短的350/800ms提速)</td></tr>
  119. </table>
  120. <div class="note">移动命令是开环+固定延时:下位机回复只代表"收到指令",机械到位靠延时保证。大行程移动耗时随距离增长,故移动类读超时给到12秒。</div>
  121. <h2>六、设备发现流程(扫描设备按钮)</h2>
  122. <div class="flow">
  123. <div class="step start"><div class="t">点击「扫描设备」</div></div>
  124. <div class="arrow"></div>
  125. <div class="step"><div class="t">① 枚举相机</div><div class="d">相机索引 0..9 逐个 Init 读序列号(SN),建 index→SN 字典</div>
  126. <div class="p">最多枚举 10 台 · 分辨率 2592×1944 · 初始曝光 400(×100µs)</div></div>
  127. <div class="arrow"></div>
  128. <div class="step"><div class="t">② 扫描串口</div><div class="d">遍历所有 COM 口(跳过 COM1/COM2),逐个握手得 houseSn,读 EEPROM 的 CCDSN</div>
  129. <div class="p">握手命令 5E 01... · 读CCDSN(EEPROM)</div></div>
  130. <div class="arrow"></div>
  131. <div class="step"><div class="t">③ 配对</div><div class="d">用 CCDSN 把舱室(串口)配对到相机 index,得到「舱室+相机+串口」三元组</div></div>
  132. <div class="arrow"></div>
  133. <div class="step done"><div class="t">填入舱室下拉框 → 选舱室 → 连接</div>
  134. <div class="d">连接:打开串口 + 按界面增益(R/G/B)和曝光 Init 相机 + SetOpMode(0)拍照模式</div></div>
  135. </div>
  136. <h2>七、手动测试台 — 全部控件与参数</h2>
  137. <h3 style="color:#dcdcaa;margin:14px 0 6px;">相机参数</h3>
  138. <table>
  139. <tr><th>控件</th><th>默认值</th><th>范围</th><th>作用</th></tr>
  140. <tr><td>曝光 TxtExposure</td><td class="val">400</td><td class="val">[1,1000] ×100µs</td><td>感光时间,越大越亮。对焦标定用中低曝光(~60)避免well盘过曝</td></tr>
  141. <tr><td>增益 R TxtGainR</td><td class="val">25</td><td class="val">0-255</td><td>红通道信号放大倍数</td></tr>
  142. <tr><td>增益 G TxtGainG</td><td class="val">14</td><td class="val">0-255</td><td>绿通道放大(默认最低,因绿通道传感器灵敏度最高,压低防偏绿)</td></tr>
  143. <tr><td>增益 B TxtGainB</td><td class="val">25</td><td class="val">0-255</td><td>蓝通道放大倍数</td></tr>
  144. </table>
  145. <div class="note">增益作用 = 整体提亮 + 白平衡校色偏。实测(曝光60):全低 R5G5B5→灰度均值92(偏暗),默认→219,全高 R60G60B60→255(过曝饱和丢细节)。对焦需中灰区(~120-220),过曝/过暗都会让清晰度算法失准。</div>
  146. <h3 style="color:#dcdcaa;margin:14px 0 6px;">Z 对焦轴(垂直电机)</h3>
  147. <table>
  148. <tr><th>控件</th><th>默认值</th><th>说明</th></tr>
  149. <tr><td>步距 TxtZStep</td><td class="val">128</td><td>Z+正转 / Z-反转 每次走的脉冲数</td></tr>
  150. <tr><td>绝对位置 TxtZAbs</td><td class="val">0</td><td>「移动」按钮:直接移到该 Z 绝对脉冲位置</td></tr>
  151. <tr><td>Z复位</td><td class="val">复位脉冲 2000(0x07D0)</td><td>固定帧 5E 05 00 0B 23...07 D0,回机械零点。脉冲值固化、不可配</td></tr>
  152. </table>
  153. <h3 style="color:#dcdcaa;margin:14px 0 6px;">水平轴(皿孔旋转电机)</h3>
  154. <table>
  155. <tr><th>控件</th><th>默认值</th><th>说明</th></tr>
  156. <tr><td>步距 TxtHStep</td><td class="val">100</td><td>正转/反转 每次走的脉冲数</td></tr>
  157. <tr><td>到位延时 TxtMotorDelay</td><td class="val">1500 ms</td><td>移动后等待机械稳定的时间(MotorDelayMs)</td></tr>
  158. <tr><td>水平复位</td><td class="val">复位脉冲 3000(0x0BB8)</td><td>固定帧 5E 05 00 0B 13...0B B8,回机械零点。脉冲值固化、不可配</td></tr>
  159. <tr><td>转到该well</td><td>—</td><td>读该well EEPROM水平位→移过去;若有合格标定结果则优先用标定的水平/Z/曝光</td></tr>
  160. </table>
  161. <h3 style="color:#dcdcaa;margin:14px 0 6px;">手动 Z 扫描(扫描选层,找最清晰层)</h3>
  162. <table>
  163. <tr><th>控件</th><th>默认值</th><th>说明</th></tr>
  164. <tr><td>起点 TxtScanStart</td><td class="val">0</td><td>扫描起始 Z 脉冲</td></tr>
  165. <tr><td>层距 TxtScanStep</td><td class="val">128</td><td>每层 Z 增量</td></tr>
  166. <tr><td>层数 TxtScanCount</td><td class="val">11</td><td>扫描层数(至少2)</td></tr>
  167. </table>
  168. <div class="note">流程:从起点起逐层 VerticalMoveTo(start + i×step),每层抓帧算清晰度,画清晰度曲线,选分数最高层。与自动粗对焦同理,但参数全手动、范围由用户定。</div>
  169. <h3 style="color:#dcdcaa;margin:14px 0 6px;">其他操作</h3>
  170. <table>
  171. <tr><th>按钮</th><th>作用</th></tr>
  172. <tr><td>开光源/关光源</td><td>LED 开关(固定帧 5E 09...),对焦/拍照需开灯</td></tr>
  173. <tr><td>抓一帧</td><td>GrabRgb 抓单帧显示 + 算中央50%ROI清晰度</td></tr>
  174. <tr><td>实时预览</td><td>连续抓帧实时显示(切换开关)</td></tr>
  175. <tr><td>存图</td><td>把当前帧存为 BMP</td></tr>
  176. <tr><td>设置(曝光/增益)</td><td>把输入框的曝光/增益值下发给相机</td></tr>
  177. </table>
  178. <h2>八、标定结果与合格判定</h2>
  179. <table>
  180. <tr><th>记录项</th><th>含义</th></tr>
  181. <tr><td>HorizontalPulse</td><td>居中后的水平脉冲位置</td></tr>
  182. <tr><td>FocusZ</td><td>精对焦求得的最清晰 Z(抛物线插值后)</td></tr>
  183. <tr><td>Exposure</td><td>曝光二分求得的曝光值</td></tr>
  184. <tr><td>CenterOffsetPct</td><td>well圆 Y 方向偏移百分比</td></tr>
  185. <tr><td>PeakRatio</td><td>对焦峰强度 max/mean,&lt;1.2 判弱峰告警</td></tr>
  186. <tr><td class="val">合格判定</td><td class="val">|Y偏移|&lt;12% 且 检出圆 且 峰比&gt;1.2</td></tr>
  187. </table>
  188. <div class="note">标定结果存 calibration.json;转well时优先用合格的标定参数(水平/Z/曝光),不合格则降级用 EEPROM 原始值。</div>
  189. <h2>九、错误处理与降级策略</h2>
  190. <table>
  191. <tr><th>情况</th><th>检测</th><th>处理</th></tr>
  192. <tr><td>电机移动失败</td><td>下位机无回复/超时</td><td>RetryMove 重试最多 3 次(每次间隔400ms);仍失败→跳过该well,记 Note="电机移动失败"</td></tr>
  193. <tr><td>抓帧失败</td><td>GetSourceBuffer 返回空/异常</td><td>Grab 重试最多 3 次(每次间隔50ms);仍失败→抛异常终止该well</td></tr>
  194. <tr><td>精对焦未检出well圆</td><td>WellDetector.Detect 未找到圆</td><td>对焦ROI降级为中央40%(绝不用全图,避免背景/反光干扰),继续对焦</td></tr>
  195. <tr><td>对焦峰过弱</td><td>峰比 max/mean &lt; 1.2</td><td>告警"可能空well或对焦失败",记 Note;结果仍保留但标记不合格</td></tr>
  196. <tr><td>粗对焦峰落区间边界</td><td>bestZ ≤ 下界 或 ≥ 上界</td><td>告警"真实焦面可能在窗口外,建议调整 ZCoarseCenter/ZCoarseHalf"</td></tr>
  197. <tr><td>脉冲越界</td><td>目标 &lt; 下限 或 &gt; 上限</td><td>ClampH/ClampZ 钳到边界并写日志,不发越界指令(防撞机械限位)</td></tr>
  198. <tr><td>水平全程未检出圆</td><td>居中扫描所有位置都没well圆</td><td>跳过该well,记 Note="水平全程未检出圆"</td></tr>
  199. </table>
  200. <div class="note">设计原则:单个well失败不中断整批标定(跳过并记Note继续下一个);所有降级都有日志,便于事后排查。</div>
  201. </body>
  202. </html>