By wangchaoqiang, 30 June, 2026
Forums

【金山文档 | WPS云文档】 LeaflaminaMap改进版 https://www.kdocs.cn/l/ccABDSwAjlRw

基于之前的leaflaminamap软件,做了以下改进,增加了k值、w值模块和invert模块,同时增加了单指数展叶率计算和contrast滑块微调细节

k 值(Sigmoid 敏感度)

位置:代码_update_display 方法中,控制 sigmoid 映射曲线的陡峭程度。

公式:display = 255 / (1 + exp(-(x - μ) / (k × σ / 4)))

其中 μ 为冠层内指数值的均值,σ 为标准差。k 出现在分母的 spread 项中,k 越大则 spread 越大、sigmoid 越平缓。

物理含义:k 控制指数图像的黑白对比度。k=0.1 时曲线近乎阶跃函数——μ 两侧的像素被分别推向纯黑和纯白,丢失中间灰阶但反差极大;k=1.0 时为正常 S 形过渡,灰阶丰富;k=5.0 时曲线几乎线性,大量像素聚集在中灰区,画面低反差。默认值 1.0,范围 0.1–5.0,由界面左上角 k 滑块调节。

总结为一句话:k 是"你要的动态范围有多大"。k 小→黑白分明,k 大→灰阶柔和。

w 值(空间先验权重)

位置:代码_update_display 和 _run_detection 中,控制边界邻近度加权的强度。

前置概念——边界邻近度 (prox):对冠层二值掩码做欧氏距离变换,得到每个像素到最近边界的距离 dist,取冠层内距离分布的 30% 分位数为 σ,prox = exp(-dist/σ)。边缘像素 dist≈0→prox≈1.0,深处像素 dist 大→prox≈0。

公式:spatial_factor = 1 − w + w × prox

物理含义:新叶和芽头天然生长于冠层外围末端——这是一个可靠的形态学先验。w 决定了"你有多相信这个先验"。w=0 时 spatial_factor 恒为 1.0,所有像素等权,完全不用空间信息;w=1 时 spatial_factor = prox,内部深处像素完全抹黑,仅边缘保留亮度。默认值 0.5,即内部像素得分压缩到边缘的 50%。w 越大→非边缘区域越暗→新叶芽头越突出。

也总结为一句话:w 是"你有多相信新叶长在冠层边缘"。w=0→全图等权;w=1→只看边缘。

Invert(方向翻转)

位置:代码_update_display 和 _run_detection 中,由界面 Invert 复选框触发。

前置概念——自动方向检测:植被指数分为两类。比值归一化型(如 ExG)消掉了亮度,新叶/芽头可能在数值低端(因为 RGB 三通道都高,绿占比反而下降);亮度保留型(如 Green intensity)中芽头天然在高端。软件通过 _detect_new_leaf_direction 自动判断——比较冠层边缘 top 5% 和内部 bottom 50% 的中位数,边缘中位数≥内部→new=high 方向,否则 new=low 方向。

手动翻转的作用:当自动方向检测判断反了时,指数图中新叶区域会呈现"阴影状"——本该亮的区域变暗。这是天然的视觉提示。勾选 Invert 将 z_dir 取反,纠正方向错误,使芽头重新映射到亮端。值 = True/False,由界面 Invert 复选框控制。

总结:自动方向判断可能反——看到叶片阴影就勾 Invert 翻转回来。

Contrast(灰度阈值偏移)

核心思想:直接移植 label_tool 的手动灰度阈值原理,但将其自动化。label_tool 的做法极其简单——将彩色原图转灰度图,手动拖滑块找一个阈值,灰度值高于阈值的是新叶(亮),低于的是老叶(暗)。Contrast 滑块把这个思路变成一个可调的自动参数。

计算步骤:

第一步——灰度图计算。 从原始彩色图像计算每个像素的标准灰度值:

gray = 0.299×R + 0.587×G + 0.114×B

芽头嫩绿反光强→灰度值高(约 180–220);茎秆木质化暗沉→灰度值低(约 50–120);成熟老叶深绿→灰度值居中(约 80–160)。这是物理事实,不依赖任何指数公式。

第二步——Otsu 自动找分界。 对冠层内所有像素的灰度值应用大津法(Otsu),自动找到亮像素和暗像素的最佳分割点 gray_otsu。这个值完全由数据驱动,无需人工指定。

第三步——滑块偏移。 Otsu 的自然分界是一个参考点,但实际使用时需要调节严格程度:

cutoff = gray_otsu + (cl − 0.5) × 160

cl=0.5 时 cutoff = gray_otsu,即 Otsu 原始分界;cl=0 时 cutoff 下移 80 个灰度级,门槛更低→更多像素被判为"亮"→宽检测;cl=1 时 cutoff 上移 80 个灰度级,门槛更高→只有最亮的芽头像素通过→精检测。

第四步——软阈值掩码。 不做硬二值化(亮/暗),而是用 sigmoid 生成平滑过渡:

soft_mask = 1 / (1 + exp(−(gray − cutoff) / 5))

灰度远高于 cutoff 的像素→mask≈1(完全保留指数图亮度);灰度远低于 cutoff 的→mask≈0(被压暗到 25%);灰度在 cutoff 附近的→mask 在 0~1 之间平滑过渡,避免生硬边界。

第五步——叠加到指数图。 在原版 sigmoid 指数图上乘以掩码:

final = sigmoid_index_image × (0.25 + 0.75 × soft_mask)

非新叶区域最低保留 25% 亮度——不会完全黑掉,保持指数图的整体可读性,但明显暗于新叶区域。