Skip to content

About

比对两张图的线条、纹样和像素差异,圈出哪里多了、少了、挪了。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

重明比对 · DiffEye / 壁画结构比对与像素比对工具

Version: 1.2.0

重明 DiffEye logo

把两张图叠在一起,把线条、轮廓、纹样上的结构性差异提前照出来: 红色是后图新增的线条,蓝色是后图缺失的线条,黄色是位置发生偏移的线条, 再把相邻的差异点聚成一个个「聚焦区域」,让人按区域逐个复核。

本工具是 大云壁画工具箱的一员:相柳网格 · 精卫 · 白泽评审 · 重明 DiffEye · 工具箱启动台。 (系列仓库并排克隆时,这些名字是相对链接:相柳网格 · 精卫 · 白泽评审 · 工具箱启动台。)

重明是系列里唯一的 Node + Python 双栈工具:HTTP 服务、上传、像素比对在 Node 侧, 结构比对引擎在 Python 侧。原因见下面的「依赖」。


这是什么

AI 修复出一张图,跟原图比,到底哪里变了?肉眼盯久了会疲劳,看两张几乎一样的图尤其容易 漏掉细节——改了三条线、少了一道纹样、笔锋整体偏了两三个像素,这些都很难靠肉眼稳定地找出来。

重明做的事只有一件:把「哪里不一样」标出来,并整理成可以逐个过目的清单。

  • 用 homography 先把第二张图对齐到第一张,压掉拍摄角度、裁切和轻微透视差带来的误报;
  • 把两张图的线条/边缘提出来做比对,分成新增 / 缺失 / 偏移三类;
  • 把相邻的差异点聚合成「聚焦区域」,每个区域给一张三栏对照图(原图局部 / 后图局部 / 差异局部);
  • 每个区域可以人工标记通过 / 复核 / 问题 / 忽略,结论能导出成 JSON 或 Markdown 留档。

重明不替代专家判断。它的作用是把可能有结构变化的位置提前整理出来,减少人工搜索成本, 让人把精力集中在真正需要判断的局部。


缘起

这个工具是在大云禅院壁画修复与重现工作中长出来的。项目需要反复比对原始壁画扫描图与 AI 生成图、人工修复图之间的差异。完全靠人工逐张查看,不仅耗时,也容易漏掉细微的结构变化。

于是把「先找差异、再谈判断」这一步单独抽出来做成工具:机器负责把可疑的地方圈出来, 人负责判断这些地方改得对不对。审查力气花在少数可疑点上,而不是平摊在整张图里。


名称含义

「重明」出自中国古代神话中的重明鸟。传说它双目各有两瞳,能明察秋毫、辨微见著, 还能驱邪避凶、衔火带来光明。

这个名字适合这个工具:它不是替人做决定的,而是一双更耐久的眼睛——把图像里不容易发现的 差异提前照出来,让审核的人看得更快、也更稳。

Logo 就是这层意思:一枚朱砂圆印,中间是双目各带双瞳的重明,顶上三簇火苗。


功能

  • 壁画纹样比对:提取线条/边缘后比对结构,适合壁画、纹样、图纸、线稿。 输出红(新增)/ 蓝(缺失)/ 黄(偏移)三色差异图。
  • 像素差异比对:严格逐像素比较,适合截图、渲染图、导出图的一致性检查。
  • 自动对齐:基于 ORB 特征 + homography,把第二张图对齐到第一张; 对齐质量不稳定时自动退回「只做等比缩放」,不会硬套一个扭曲的矩阵。
  • 聚焦区域:把邻近差异点聚合成外接矩形,过滤掉过大和过小的噪声块,输出区域清单。
  • 三栏局部审查:每个区域一张对照图,可点开放大,支持左右方向键逐个翻。
  • 人工标记:通过 / 复核 / 问题 / 忽略,记在浏览器本地,可随结果一起导出。
  • 批量比对:把多组图片排进队列,一次性跑完。
  • 报告导出:JSON(含全部参数与标记)或 Markdown(含区域表格)。
  • 可选 DexiNed 精细线条模式:用 AI 边缘检测处理特别复杂的纹样。
  • 本地运行:服务只监听 127.0.0.1,图片留在本机 runs\ 目录,局域网内其它机器访问不到。

快速开始

双击:

run.bat

它会自己检查 Node.js、检查依赖、起服务、等健康检查通过、然后打开浏览器。 关闭那个窗口即停止工具。

也可以手动:

node server.js

然后打开 http://127.0.0.1:5055。

第一次使用(还没装依赖)请先双击 install.bat。

run.ps1 支持 -NoBrowser,只起服务不开浏览器,便于自动化验证:

cmd /c run.bat -NoBrowser

依赖

重明是 Node + Python 双栈,两边各管一半:

侧 负责 依赖
Node.js HTTP 服务、上传、静态页面、像素比对(odiff)、调用 Python 引擎 express / multer / odiff-bin(均在 package.json)
Python 3.9+ 壁画纹样比对引擎(mural_compare.py) opencv-python / numpy / Pillow(见 requirements.txt)
  • 「像素差异」模式只用 Node 侧,不需要 Python。
  • 「壁画纹样」模式需要 Python + opencv-python + numpy。缺失时 install.bat 会安装。
  • 便携包里的 runtime\ 已经内置了 Python 和 Node,换机器不用另装;从 git 克隆的话 请自行安装前置环境再跑 install.bat。

安装命令(install.bat 做的就是这两件事):

npm install
py -3 -m pip install -r requirements.txt

可选:DexiNed 精细线条模式

绝大多数人不需要跑 setup-dexined.bat。 默认的快速 Canny 线条模式基于 OpenCV, 不需要任何模型文件,对绝大多数壁画、纹样、图纸已经够用。

只有当你确实需要 AI 边缘检测去啃特别复杂的纹样时,才需要:

  1. 运行 setup-dexined.bat(clone DexiNed 官方仓库到 third_party/DexiNed/, 并安装 torch / torchvision / kornia / h5py 等);
  2. 按官方 README 下载 checkpoint,放到 third_party\DexiNed\checkpoints\BIPED\10\10_model.pth(约 134 MB)。

装好之后页面上的「线条模式」选「精细 DexiNed」即可。没装模型时选它会被服务端明确拒绝, 不会静默失败。


工作流

1 选图 — 拖入或点选两张图,第一张是基准图,第二张是待比对图。也可以从历史记录里挑。

  • 两张图的宽高比必须一致(差异 < 0.03),否则会直接报错并告诉你各自的尺寸。 这是有意的:比例不一致时,后面的对齐和比对结果没有意义。

2 参数 — 按需要调:

参数 默认 范围 说明
灵敏度 5 1–10 越高,参与比对的边缘越多
最小区域 2048 40–5000 小于这个像素数的差异块被过滤
检测数量 120 20–300 最多输出多少个聚焦区域
最大区域% 60 1–95 超过整图这个比例的差异块被当作背景过滤
容错px 10 1–30 越大越忽略轻微错位和笔墨边缘变化
自动对齐 开 — 关掉就只做等比缩放
线条模式 Canny / DexiNed — 见上一节

所有数值参数在服务端也会再 clamp 一次,越界的值不会穿透到算法层。

3 审查 — 看左右两个画布(前后对比 / 完整结构差异图)和右侧的「变化区域」列表。

  • 左画布支持「滑块」和「透明度」两种比对方式;
  • 点区域卡片或差异图上的黄框可以定位,双击放大;
  • 弹窗里用「通过 / 复核 / 问题 / 忽略」打标记,方向键左右翻区域;
  • 完事用「导出 JSON」或「导出 MD」留档。

批量 — 勾「批量模式」,把当前两张图加进队列,重复,然后「运行批量比对」。

更细的参数含义和「误报太多 / 漏检太多怎么办」这类调节建议,见 详细使用教程。


输出文件

每次比对落在 runs\<runId>\ 下(runId 是随机 UUID,默认保留 7 天,服务启动时自动清理):

文件名 含义
mural-overlay.png 主差异图:差异叠在原图上,带红/蓝/黄三色和区域编号框
mural-overlay-base.png 纯底图叠影(原图 56% + 后图 44%),不带差异着色
mural-layer-new.png 只有「后图新增线条」的透明层(红)
mural-layer-missing.png 只有「后图缺失线条」的透明层(蓝)
mural-layer-shifted.png 只有「位置偏移线条」的透明层(黄)
mural-base.png 缩放后的第一张图(比对基准)
mural-aligned-compare.png 对齐到第一张之后的第二张图
mural-diff-mask.png 二值差异掩膜,白色是判定为差异的像素
mural-edges.png 两张图的边缘提取结果并排,用于核对边缘质量
region-001.png … 每个聚焦区域的三栏对照图(原图局部 / 后图局部 / 差异局部)
diff.png 仅「像素差异」模式:odiff 产出的差异图
base-<原文件名> / compare-<原文件名> 上传的原图副本(文件名已清洗)

历史记录写在仓库根目录的 image-history.json(已被 .gitignore 排除)。


API 端点

服务只监听 127.0.0.1,以下接口都是本机内部使用,不对外暴露。

方法 路径 说明
GET /api/health 系列统一健康检查:版本、端口、Python 路径、DexiNed 可用性、runs 清理状态
GET /health 同上(保留旧路径,工具箱启动台兼容用)
GET /history 历史图片列表
DELETE /history 清空历史与 runs\ 缓存
POST /compare 执行比对。mode=mural 结构/纹样比对,mode=pixel 严格像素比对
GET /runs/... 比对产物:原图、对比图、差异图、mask、各区域裁剪

常见问题

Q:报「两张图片宽高比例不一致,无法比对」。

把两张图裁成相同的宽高比再比。差异必须小于 0.03(例如 1600×1200 配 1610×1207 可以, 配 1600×1000 不行)。这不是 bug——比例不同意味着两张图覆盖的画面范围不同, 强行对齐只会制造大量假差异。

Q:报「DexiNed 不可用」。

你选了「精细 DexiNed」但没装模型。切回「快速 Canny」即可,绝大多数情况够用; 确实需要 DexiNed 就见上面的「可选」一节。

Q:检测到很多细碎的区域 / 或者一个区域都没检测到。

调「最小区域」和「容错px」。差异碎就调大最小区域;漏检就调小最小区域、调高灵敏度。 「最大区域%」调小可以压掉整片背景差异。

Q:上传报错说文件太大。

单张上限 120 MB。超限返回 413 和一句中文提示,请先压缩或裁切。

Q:端口 5055 被占用了。

$env:PORT=5066; node server.js

然后用 http://127.0.0.1:5066 打开。

Q:局域网里别人能打开我的重明吗?

不能。服务只绑定 127.0.0.1,/api/health 里会报出实际监听地址。 这是系列安全基线(SERIES-SPEC §7 S7)的要求。

Q:历史记录和 runs\ 会不会越积越多?

服务每次启动会清掉 7 天前的 runs\ 子目录(可用环境变量 RUNS_MAX_AGE_DAYS 调整)。 页面上的「清空历史」会删掉全部 runs\ 缓存并清空 image-history.json,不可撤销。

Q:双击 run.bat 没反应 / 窗口一闪而过。

先看窗口里有没有中文乱码报错。这类问题的根因通常是脚本文件编码 (run.ps1 必须 UTF-8 带 BOM,run.bat 必须纯 ASCII)。可以直接跑一遍自查:

D:\vibecodingtool\_series\tools\fix-ps1-encoding.ps1 -Path .\run.ps1,.\run.bat -Check

Q:node_modules\ / runtime\ / runs\ / third_party\ 要不要提交?

都不要,.gitignore 已经覆盖。这些目录加起来能有好几个 GB, 而且全都能从 package.json、requirements.txt、setup-dexined.bat 重新装出来。


关于 runs/ 目录(请务必看一眼)

runs/ 是比对过程的中间产物目录(原图、对比图、差异图、mask、区域裁剪)。 服务每次启动都会自动清理其中超过 7 天的内容 —— 这是刻意设计,否则它会无限增长。

但这里有一个陷阱,必须知道:

不要把备份目录里的 server.js 启动起来做实验。 它会把这个备份自己的 runs/ 一起清掉 —— 备份就废了。

1.2.0 之前,想保留这些内容也没有办法。现在可以:

set RUNS_MAX_AGE_DAYS=0
node server.js

设成 0 或负数 = 完全关掉自动清理,一个都不会删。启动日志会明确打印当前处于哪种状态, 清理时也会先打印"将要清理哪些目录"再动手。

(1.2.0 之前那行写的是 Number(process.env.RUNS_MAX_AGE_DAYS || 7): 设成 0 会被当成假值而回退成 7,你以为关掉了其实没关; 设成负数更糟 —— 截止时间跑到未来,整个 runs/ 会被清空。这两个坑都已修掉。)

更新日志

见 CHANGELOG.md。


开源协议与品牌

源代码使用 MIT License 发布。

第三方依赖各自的协议见 THIRD_PARTY_NOTICES.md。

关于协议的变更:重明在 1.2.0 之前使用 AGPL-3.0,自 1.2.0 起统一为 MIT, 与「大云壁画工具箱」其余成员一致。合规检查已完成:全部直接依赖都是宽松协议 (express / multer / odiff-bin 为 MIT,opencv-python 为 Apache-2.0,Pillow 为 HPND, numpy 为 BSD-3-Clause,DexiNed 为 MIT),没有 GPL/AGPL 传染。 历史提交里的 AGPL 声明保留在 git 历史中。

The names 重明 / DiffEye, as well as the project logo and visual identity, are reserved by the project author and are not granted as branding or trademark rights under the MIT License.

重明 / DiffEye 的名称、项目 logo 和视觉识别保留为项目作者的品牌资产, 不随 MIT 协议授予商标或品牌使用权。

作者 / Author: SGWinking / 上官文卿

About

比对两张图的线条、纹样和像素差异,圈出哪里多了、少了、挪了。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages