Rust图像处理第24节- 噪声模型 + 中心极限定理:椒盐噪声 + CLT 可视化

🦀 Rust + WASM 实战系列 第 24 篇 阅读时间:约 5 分钟 | 实战可运行

📌 写在前面

任务 23 讲了怎么采 高斯和泊松噪声------这一篇讲第三种噪声(椒盐) + 一个为什么高斯无处不在的原理(中心极限定理)。

内容 物理场景 算法
椒盐噪声 老电视雪花、损坏照片 概率置 0/255
中心极限定理 解释"为什么高斯无处不在" 多个均匀之和 → 钟形

🚀 TL;DR

核心概念

  • 椒盐噪声 = 每个像素 density 的概率被随机设为 0(黑)或 255(白)

  • CLT = 多个独立同分布随机变量之和 → 趋向正态分布(无论单个是什么分布)

    1 个均匀 → 矩形分布
    2 个之和 → 三角形
    4 个之和 → 鼓包
    12 个之和 → 几乎完美的正态


📖 目录

  1. 椒盐噪声:最简单也最暴力
  2. [3 种噪声对比(高斯 / 泊松 / 椒盐)](#3 种噪声对比(高斯 / 泊松 / 椒盐) "#%E4%BA%8C3-%E7%A7%8D%E5%99%AA%E5%A3%B0%E5%AF%B9%E6%AF%94%E9%AB%98%E6%96%AF--%E6%B3%8A%E6%9D%BE--%E6%A4%92%E7%9B%90")
  3. 中心极限定理:为什么高斯无处不在
  4. [CLT 可视化实现](#CLT 可视化实现 "#%E5%9B%9Bclt-%E5%8F%AF%E8%A7%86%E5%8C%96%E5%AE%9E%E7%8E%B0")
  5. 关键代码
  6. 前端效果展示
  7. 踩坑提醒
  8. 接下来

一、椒盐噪声:最简单也最暴力

算法(伪代码):

csharp 复制代码
for each pixel:
    if random() < density:
        if random() < 0.5:
            pixel = 0        // 黑点
        else:
            pixel = 255      // 白点
  • density:噪声像素占比(0~1)
  • 黑点白点各 50%------所以叫"椒盐"

Rust 代码

rust 复制代码
#[wasm_bindgen]
pub fn salt_pepper_noise(pixels: &[u8], w: u32, h: u32, density: f32) -> Vec<u8> {
    for i in 0..n {
        let r = uniform_random();
        if r < density {
            // 随机设黑或白
            if (x & 1) == 0 {
                out[idx] = 0;
                // ...
            } else {
                out[idx] = 255;
                // ...
            }
        }
    }
}

二、3 种噪声对比(高斯 / 泊松 / 椒盐)

噪声 物理模型 算法 视觉 真实场景
高斯 N(0,σ2)N(0, \sigma^2) N(0,σ2) Box-Muller 平滑小波动 传感器热噪声
泊松 Poisson(λ)\text{Poisson}(\lambda) Poisson(λ) Knuth 颗粒感(暗处明显) 暗光摄影、医学影像
椒盐 概率置 0/255 随机数 黑白点散布 老电视、数据错误

三、中心极限定理:为什么高斯无处不在

定理(简化版):

多个独立的随机变量之和当数量足够大时趋向正态分布

不管单个变量是什么分布

直觉例子

n 个均匀分布之和 形状
1 矩形
2 三角形
3 鼓包
4 接近钟形
8 几乎正态
12 完全正态

关键 :每个均匀都是平的,但 12 个加起来 → 漂亮的钟形

现实世界

几乎所有"复杂现象"都符合 CLT:

  • 测量误差 = 仪器误差 + 读数误差 + 温度漂移 + ...(多个独立随机)
  • 人类身高 = 基因 + 营养 + 运动 + 睡眠 + ...(多个独立因素)
  • 股票价格变化 = 无数交易者的买卖决策之和
  • 图像噪声 = 多个电路/光学噪声源叠加

都近似正态高斯无处不在


四、CLT 可视化实现

CLT 不需要 WASM------Math.random() 算就行,更简单更快:

javascript 复制代码
function computeHistogram(n) {
  // n = 几个均匀分布之和
  const N_SAMPLES = 10000
  const N_BINS = 40
  const bins = new Array(N_BINS).fill(0)

  for (let i = 0; i < N_SAMPLES; i++) {
    let sum = 0
    for (let j = 0; j < n; j++) {
      sum += Math.random()  // 0~1
    }
    // sum ∈ [0, n],归一化到 bin
    const bin = Math.floor(sum / n * N_BINS)
    bins[bin]++
  }
  return bins
}

滑块 n=1~12------读者拖动看柱状图从"矩形"变成"钟形"。

五、关键代码

rust 复制代码
#[wasm_bindgen]
pub fn salt_pepper_noise(pixels: &[u8], width: u32, height: u32, density: f32) -> Vec<u8> {
    let mut out = pixels.to_vec();
    let n = (width * height) as usize;
    let d = density.clamp(0.0, 1.0) as f64;

    for i in 0..n {
        // xorshift64 PRNG(同任务 23 的实现)
        let r = (xorshift_next() >> 11) as f64 / (1u64 << 53) as f64;
        
        if r < d {
            let idx = i * 4;
            if /* random bit */ {
                out[idx] = 0; out[idx+1] = 0; out[idx+2] = 0;  // 黑
            } else {
                out[idx] = 255; out[idx+1] = 255; out[idx+2] = 255;  // 白
            }
        }
    }
    out
}

核心 5 行------和第 23 节一样用自实现 PRNG。


六、前端效果展示

七、踩坑提醒

1. 椒盐 density 不能超过 0.5

rust 复制代码
let d = density.clamp(0.0, 1.0) as f64;

50% 时图基本全黑/全白------没有意义。前端限制 0~0.5

2. 椒盐 = 模拟"传输错误",不是"自然噪声"

用途 适合
模拟老电视、坏照片 ✅ 椒盐
模拟真实相机噪声 ❌ 用泊松
模拟电子电路噪声 ❌ 用高斯

不要混用------它们是不同的物理模型。

3. CLT 需要 n > 30 才严格成立

我们画 n=1~12 主要是直觉演示------严格数学上 n ≥ 30 才"近似"。


八、接下来

任务 25:图像增强(自适应阈值 + 直方图均衡化)

任务 24 讲怎么加噪(破坏) 任务 25 讲怎么还原(修复)

两个工具:

  • 自适应阈值:处理光照不均
  • 直方图均衡化:让暗图变清晰

任务 26:概率驱动图像生成(随机游走 + 马尔可夫链 + 图像合成 + 修复)


一句话总结

椒盐噪声 = 概率置 0/255(最简单、最暴力)。

CLT = 多个独立随机变量之和 → 正态分布。

滑块 1~12 看柱状图从"平"变"钟"------为什么高斯无处不在的直觉。


📦 项目地址pixel-math-wasm 🦀 Rust + WebAssembly 实战系列


🏷️ 标签#Rust #WebAssembly #图像处理 #椒盐噪声 #中心极限定理 #高斯分布 #CLT

相关推荐
爱吃牛肉的大老虎3 小时前
Rust对象之结构体,枚举,特性
开发语言·后端·rust
TunerT_TQ6 小时前
Valhalla 静态工程审阅 #008|RisingWave 源码证据驱动评测【大厂开源基础设施特辑】
rust·开源·github·实时数据处理·流式数据库·apacheflink·streamingsql
SmalBox9 小时前
【节点】[IsNaN节点]原理解析与实际应用
unity3d·游戏开发·图形学
TunerT_TQ10 小时前
Valhalla 静态工程审阅 #007|AgentENV 源码证据驱动评测【大厂开源基础设施特辑】
rust·开源·go·github·sandbox·分布式系统·ai基础设施
爱吃牛肉的大老虎10 小时前
Rust基础之函数和错误
java·开发语言·rust
NutShell Wang11 小时前
Vite 8.1 深度拆解:Rolldown 统一打包器如何终结前端构建的「双引擎时代」
前端·rust·开源·vite·开发者工具·vibe coding
寒水馨12 小时前
macOS下载、安装uv-0.12.0(附安装包uv-aarch64-apple-darwin.tar.gz)
python·macos·rust·项目管理·包管理器·astral·pip替代
寒水馨13 小时前
macOS下载、安装ripgrep-15.2.0(附安装包ripgrep-15.2.0-aarch64-apple-darwin.tar.gz)
macos·正则表达式·rust·ripgrep·rg·命令行搜索·代码搜索
SomeB1oody1 天前
【RustyML入门】1.0. 快速上手
开发语言·后端·机器学习·rust·教程