Skip to content

sergioperezcheco/DeDeBayer

Repository files navigation

DeDeBayer Logo

DeDeBayer

交互式 Bayer CFA 解拜耳算法可视化 Interactive Demosaic Algorithm Visualization

从像素级别理解数码相机如何从马赛克传感器数据还原出彩色图像

Live Demo

Cloudflare Pages Docker CI License: MIT

纯前端 · 零上传 · 隐私安全 · 支持 RAW 文件


📷 支持 RAW 格式 🔬 像素级演示 📐 5 种经典算法
NEF / CR2 / ARW / DNG 100% ~ 1600% 缩放 最近邻 → 边缘导向
自动解析 TIFF 结构 看清每个滤色片像素 逐步动画对比效果

目录


什么是 Bayer 滤色阵列

数码相机成像原理

数码相机的图像传感器(CCD/CMOS)本质上是一个光电转换器阵列。每个像素(photosite)只能测量落在其上的光的总强度,无法区分颜色。为了获得彩色图像,1976 年柯达工程师 Bryce Bayer 发明了一种巧妙的方案:在传感器前方放置一层微型彩色滤光片阵列(Color Filter Array, CFA)。

Bayer 模式

最常见的 CFA 排列是 RGGB(也称 Bayer 模式):

┌───┬───┬───┬───┬───┬───┐
│ R │ G │ R │ G │ R │ G │
├───┼───┼───┼───┼───┼───┤
│ G │ B │ G │ B │ G │ B │
├───┼───┼───┼───┼───┼───┤
│ R │ G │ R │ G │ R │ G │
├───┼───┼───┼───┼───┼───┤
│ G │ B │ G │ B │ G │ B │
└───┴───┴───┴───┴───┴───┘

关键特征:

  • 绿色像素占 50%:人眼对绿色(亮度信息)最敏感,因此绿色采样密度是红蓝的两倍
  • 红色和蓝色各占 25%
  • 每个像素只记录了一个颜色通道的信息,另外两个通道完全缺失

为什么需要解拜耳(Demosaicing)

由于每个像素只有一个颜色通道的数据,要得到完整的 RGB 彩色图像,必须通过算法估算(插值)每个像素缺失的两个通道。这个过程称为解拜耳(Demosaicing / Debayering)。

解拜耳算法的质量直接影响最终图像的:

  • 锐度:差的算法会模糊边缘
  • 伪色(Color Artifacts):在高频纹理区域产生不存在的彩色条纹
  • 摩尔纹(Moiré):规则纹理与 Bayer 模式产生干涉
  • 拉链效应(Zipper Effect):边缘处出现锯齿状彩色伪影

其他 Bayer 变体

除了 RGGB,还有三种旋转变体:

  • BGGR:蓝色在左上角
  • GRBG:绿色在左上角,红色在右上角
  • GBRG:绿色在左上角,蓝色在右上角

不同相机厂商使用不同的排列,但算法原理相同。

光学低通滤波器(OLPF)

为了减少摩尔纹和伪色,大部分数码相机在传感器前还放置了一片光学低通滤波器(Anti-Aliasing Filter)。它轻微模糊入射光,使得高频细节不会超过 Bayer 阵列的奈奎斯特频率。代价是牺牲了一些锐度。

近年来一些相机(如 Nikon Z9、Sony A7R V、Fujifilm X-T5)取消了光学低通滤波器,依赖更先进的解拜耳算法和机内处理来抑制伪色问题。


项目功能

  1. 上传图片:支持 RAW 格式(NEF/CR2/ARW/DNG 等)和普通图片(JPEG/PNG)
  2. Bayer 马赛克可视化
    • 灰度模式:模拟传感器原始输出
    • 彩色模式:用红/绿/蓝着色显示每个像素的滤色片归属
  3. 解拜耳算法演示
    • 从图片中选择任意 200×200 区域
    • 像素级放大显示
    • 逐步动画展示插值过程
    • 5 种经典算法对比
  4. 图片查看器:滚轮缩放、拖拽平移、旋转
  5. 保存功能:任意视图可导出为 PNG
  6. RAW 文件支持:自动解析 TIFF 结构,提取内嵌全尺寸 JPEG 预览,正确处理 EXIF Orientation

解拜耳算法

本项目实现了 5 种经典解拜耳算法,按复杂度递增排列:

1. 最近邻(Nearest Neighbor)

最简单的方法。对于每个缺失的颜色通道,直接复制距离最近的同色像素值。

  • 优点:计算极快,实现简单
  • 缺点:产生严重的块状伪影和锯齿
  • 复杂度:O(1) per pixel

2. 双线性插值(Bilinear Interpolation)

对缺失通道取周围同色像素的算术平均值。

  • 优点:简单有效,比最近邻平滑很多
  • 缺点:在边缘处模糊,会产生拉链效应
  • 复杂度:O(1) per pixel(3×3 邻域)

3. 平滑色调(Smooth Hue / Constant Hue-Based)

基于 Kimmel (1999) 的思路。核心观察:自然图像中色调(hue)的空间变化比亮度(luminance)更平滑。

算法步骤:

  1. 先用双线性插值得到完整的 G(亮度)通道
  2. 计算色调比率 R/G 和 B/G
  3. 对色调比率进行插值(而非直接对 R、B 插值)
  4. 用插值后的比率乘以 G 得到 R 和 B
  • 优点:显著减少伪色,边缘保持更好
  • 缺点:在 G 接近 0 的暗区可能不稳定
  • 复杂度:O(1) per pixel,两遍扫描

4. Malvar-He-Cutler(2004)

微软研究院提出的高质量线性插值方法。使用 4 种 5×5 卷积核,关键创新是利用其他颜色通道的高频信息来修正插值结果。

核心思想:在估计某个位置的 G 值时,不仅看周围的 G 像素,还利用当前位置已知的 R 或 B 值(它们包含了局部高频信息)来修正估计。

4 种卷积核(所有系数除以 8):

  • Pattern 1:在 R/B 位置估计 G

  • Pattern 2:在 G 位置估计水平方向的 R 或 B

  • Pattern 3:在 G 位置估计垂直方向的 R 或 B

  • Pattern 4:在 R 位置估计 B(或反之,对角方向)

  • 优点:线性算法中质量最高,计算效率好

  • 缺点:仍是线性方法,无法完全消除边缘伪色

  • 复杂度:O(1) per pixel(5×5 固定核)

5. 边缘导向插值(Edge-Directed / Hamilton & Adams)

基于 Hamilton & Adams (1997) 的思路。核心创新:在插值前先检测局部边缘方向,然后只沿边缘方向插值,避免跨越边缘。

算法步骤:

  1. 计算水平梯度 dH 和垂直梯度 dV
  2. 如果 dH < dV:沿水平方向插值(垂直方向有边缘)
  3. 如果 dV < dH:沿垂直方向插值(水平方向有边缘)
  4. 如果 dH ≈ dV:取两个方向的平均
  5. 利用色差(R-G, B-G)的平滑性恢复 R 和 B
  • 优点:边缘保持优秀,伪色少
  • 缺点:在对角边缘处仍可能产生伪影
  • 复杂度:O(1) per pixel,但常数较大

技术栈

技术 用途
Vite 6 构建工具
React 19 UI 框架
TypeScript 5.8 类型安全
Tailwind CSS 4 样式
Canvas API 图像渲染与像素操作
Web Worker 后台计算(可选)

纯前端,零后端依赖,适合部署到任何静态托管平台。


项目结构

DeDeBayer/
├── src/
│   ├── components/
│   │   ├── CanvasView.tsx        # 通用 Canvas 图像显示组件
│   │   ├── DemosaicPlayer.tsx    # 解拜耳演示交互组件(局部放大 + 动画)
│   │   ├── ImageUploader.tsx     # 图片/RAW 上传组件
│   │   └── ImageViewer.tsx       # 全屏图片查看器(缩放/平移/旋转)
│   ├── lib/
│   │   ├── bayer.ts              # Bayer CFA 核心:RGB→马赛克、可视化
│   │   ├── demosaic.ts           # 5 种解拜耳算法实现
│   │   ├── tiff-parser.ts        # TIFF/NEF/CR2 结构解析器
│   │   ├── raw-loader.ts         # RAW 文件加载(提取内嵌 JPEG)
│   │   ├── animation.ts          # 动画帧生成
│   │   ├── downsample.ts         # Bayer 感知下采样
│   │   ├── download.ts           # PNG 导出
│   │   └── theme.ts              # 明暗主题管理
│   ├── styles/
│   │   └── index.css             # Tailwind 入口 + 主题配置
│   ├── App.tsx                   # 主应用组件
│   └── main.tsx                  # 入口
├── public/
│   └── vite.svg                  # Favicon(Bayer 模式图标)
├── .github/workflows/
│   └── deploy.yml                # CI/CD:构建 + Cloudflare Pages + Docker
├── Dockerfile                    # 多阶段构建(Node + Nginx)
├── docker-compose.yml            # 一键启动
├── nginx.conf                    # Nginx 配置(SPA + 缓存)
├── wrangler.toml                 # Cloudflare Pages 配置
├── vite.config.ts                # Vite 配置
├── tsconfig.json                 # TypeScript 配置
└── package.json

本地开发

# 克隆
git clone https://github.com/sergioperezcheco/DeDeBayer.git
cd DeDeBayer

# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 构建生产版本
npm run build

# 预览生产构建
npm run preview

部署

Cloudflare Pages(推荐)

方式一:GitHub 集成(自动)

  1. Fork 本仓库
  2. 在 Cloudflare Dashboard 创建 Pages 项目,连接 GitHub 仓库
  3. 构建设置:
    • 构建命令:npm run build
    • 输出目录:dist
  4. 每次 push 到 main 自动部署

方式二:GitHub Actions(本仓库已配置)

在仓库 Settings → Secrets 中添加:

  • CLOUDFLARE_API_TOKEN:Cloudflare API Token(需要 Pages 编辑权限)
  • CLOUDFLARE_ACCOUNT_ID:你的 Cloudflare Account ID

Push 到 main 即自动部署。

CI/CD 配置详细步骤

第一步:获取 Cloudflare 凭证

  1. 登录 Cloudflare Dashboard
  2. 获取 Account ID:
    • 进入任意域名 → 右侧栏 → Account ID(32 位十六进制字符串)
    • 或者:首页 → 左下角 → Account ID
  3. 创建 API Token:
    • 进入 API Tokens 页面
    • 点击 Create Token
    • 选择模板 Edit Cloudflare Workers 或自定义:
      • Permissions: AccountCloudflare PagesEdit
    • 创建后复制 Token(只显示一次)

第二步:在 GitHub 仓库添加 Secrets

  1. 打开仓库页面 → Settings → 左侧 Secrets and variablesActions
  2. 点击 New repository secret,添加:
    • Name: CLOUDFLARE_API_TOKEN,Value: 上面创建的 API Token
    • Name: CLOUDFLARE_ACCOUNT_ID,Value: 你的 Account ID

第三步:触发部署

  • 自动触发:Push 代码到 main 分支即自动触发
  • 手动触发:进入仓库 → Actions → 选择 workflow → Run workflow
  • PR 触发:向 main 提交 Pull Request 时会自动构建(但不部署)

第四步:Docker 镜像(自动)

Docker 镜像会自动推送到 GitHub Container Registry (ghcr.io),无需额外配置。GITHUB_TOKEN 是 Actions 自动提供的。

构建完成后可以这样拉取:

docker pull ghcr.io/sergioperezcheco/dedebayer:latest

Docker

# 使用 docker-compose(推荐)
docker compose up -d

# 或手动构建运行
docker build -t dedebayer .
docker run -p 4321:4321 dedebayer

访问 http://localhost:4321

也可以直接拉取 GitHub Container Registry 的镜像:

docker pull ghcr.io/sergioperezcheco/dedebayer:latest
docker run -p 4321:4321 ghcr.io/sergioperezcheco/dedebayer:latest

其他平台

本项目是纯静态站点,npm run build 后将 dist/ 目录部署到任何静态托管即可:

  • Vercel:零配置,连接 GitHub 即可
  • Netlify:构建命令 npm run build,发布目录 dist
  • GitHub Pages:使用 gh-pages 分支或 Actions

参考文献

  1. Bayer, B. E. (1976). Color imaging array. U.S. Patent 3,971,065. Google Patents

  2. Hamilton, J. F., & Adams, J. E. (1997). Adaptive color plan interpolation in single sensor color electronic camera. U.S. Patent 5,629,734. Google Patents — 边缘导向插值的奠基性专利。

  3. Kimmel, R. (1999). Demosaicing: Image reconstruction from color CCD samples. IEEE Transactions on Image Processing, 8(9), 1221-1228. IEEE Xplore — 提出利用色调平滑性的解拜耳方法。

  4. Malvar, H. S., He, L., & Cutler, R. (2004). High-quality linear interpolation for demosaicing of Bayer-patterned color images. IEEE ICASSP, vol. 3, pp. 485-488. Microsoft Research PDF — 微软研究院提出的 5×5 卷积核方法。

  5. Gunturk, B. K., Glotzbach, J., Altunbasak, Y., Schafer, R. W., & Mersereau, R. M. (2005). Demosaicking: Color filter array interpolation. IEEE Signal Processing Magazine, 22(1), 44-54. IEEE Xplore — 解拜耳算法的综述论文。

  6. Menon, D., Andriani, S., & Calvagno, G. (2007). Demosaicing with directional filtering and a posteriori decision. IEEE Transactions on Image Processing, 16(1), 132-141. IEEE Xplore — 更先进的方向性滤波方法。

  7. Li, X., Gunturk, B., & Zhang, L. (2008). Image demosaicing: A systematic survey. Proceedings of SPIE, vol. 6822. SPIE — 全面的解拜耳算法调研。


License

MIT

About

Interactive Bayer CFA & demosaic algorithm visualization. Supports RAW files (NEF/CR2/ARW/DNG). 5 classic algorithms with pixel-level demo.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages