# image-duplicate-check **Repository Path**: pandacouple/image-duplicate-check ## Basic Information - **Project Name**: image-duplicate-check - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-15 - **Last Updated**: 2026-03-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Image Duplicate - 图片相似度对比工具 一个基于 Node.js 和 TypeScript 开发的图片相似度对比工具,支持多种对比算法,可用于比较两张图片的相似度或查找文件夹中的重复图片。 ## 特性 - 🎯 支持多种对比算法:Pixelmatch、SSIM、Average Hash、Combined(综合算法) - ⚡ 高性能图像处理,支持并发处理 - 📁 支持文件夹批量处理和文件夹对比 - 🎨 彩色命令行输出 - 📊 详细的对比结果报告 - 🔧 灵活的配置选项 - 📱 支持多种图片格式 - 📦 支持函数式调用和类实例化两种方式 ## 安装 ### 前提条件 - Node.js >= 16.0.0 ### 全局安装 ```bash # 克隆或下载项目到本地 git clone cd image-duplicate # 安装依赖 npm install # 构建项目 npm run build # 全局安装 npm link --global ``` ### 在项目中安装 ```bash # 在项目中安装 npm install @mocha/image-comparer ``` ## 使用 ### 命令行接口 ```bash image-duplicate [command] [options] ``` ### 可用命令 #### 1. 比较两张图片 ```bash image-duplicate compare [options] ``` **示例:** ```bash # 基本用法 image-duplicate compare image1.jpg image2.jpg # 使用 SSIM 算法 image-duplicate compare image1.jpg image2.jpg --algorithm ssim # 统一缩放到 500x500 尺寸 image-duplicate compare image1.jpg image2.jpg --resize-to 500x500 # 输出差异图片 image-duplicate compare image1.jpg image2.jpg --output-diff diff.png # 静默模式,只输出结果 image-duplicate compare image1.jpg image2.jpg -q ``` #### 2. 查找文件夹中的重复图片 ```bash image-duplicate find [options] ``` **示例:** ```bash # 基本用法 image-duplicate find ./images # 递归查找子文件夹 image-duplicate find ./images -r # 设置最小相似度阈值为 95% image-duplicate find ./images -m 95 ``` #### 3. 列出支持的算法 ```bash image-duplicate algorithms ``` #### 4. 比较两个文件夹 ```bash image-duplicate compare-folders [options] ``` **示例:** ```bash # 基本用法 image-duplicate compare-folders ./folderA ./folderB # 递归查找子文件夹 image-duplicate compare-folders ./folderA ./folderB -r # 设置最小相似度阈值为 95% image-duplicate compare-folders ./folderA ./folderB -m 95 # 忽略特定文件模式 image-duplicate compare-folders ./folderA ./folderB --ignore "*.tmp,*.backup" # 统一缩放尺寸 image-duplicate compare-folders ./folderA ./folderB --resize-to 500x500 ``` **选项:** | 选项 | 描述 | 默认值 | |------|------|--------| | `-r, --recursive` | 递归查找子文件夹 | `false` | | `-m, --min-similarity ` | 最小相似度阈值,0-100 | `90` | | `--ignore ` | 忽略的文件模式,逗号分隔 | - | **输出结果:** - 仅存在于文件夹A的图片列表 - 仅存在于文件夹B的图片列表 - 相似度超过阈值的图片对及其相似度百分比 - 相似度低于阈值的图片对及其相似度百分比 - 总对比时间和对比图片对数 ### 全局选项 | 选项 | 描述 | 默认值 | |------|------|--------| | `-q, --quiet` | 静默模式,只输出结果 | `false` | | `--algorithm ` | 对比算法,可选值:`pixelmatch`, `ssim`, `averageHash`, `combined` | `combined` | | `--threshold ` | 相似度阈值,0-1 | `0.1` | | `--resize-to x` | 统一缩放尺寸,如:`500x500` | - | | `--grayscale` | 转为灰度图进行对比 | `false` | | `--output-diff ` | 差异图片输出路径 | - | ## 算法说明 ### 1. Pixelmatch - **类型**:像素级对比 - **特点**:精确比较每个像素,返回差异像素数量 - **优势**:简单直观,适合需要精确差异的场景 - **劣势**:对颜色和亮度变化敏感,可能不符合人眼感知 ### 2. SSIM(结构相似性指数) - **类型**:结构相似性对比 - **特点**:更符合人眼感知,考虑亮度、对比度和结构 - **优势**:结果更接近人眼判断,适合比较视觉相似的图片 - **劣势**:计算复杂度较高,速度较慢 ### 3. Average Hash(平均哈希算法) - **类型**:哈希值对比 - **特点**:生成图像的哈希值,通过汉明距离计算相似度 - **优势**:计算速度快,适合快速筛选和早期终止 - **劣势**:精度较低,可能会误判某些图片 ### 4. Combined(综合算法) - **类型**:多种算法加权平均 - **特点**:结合Pixelmatch、SSIM和Average Hash算法的优点,计算加权平均值 - **优势**:综合考虑像素级差异、结构相似性和哈希值相似度,结果更准确 - **劣势**:计算时间较长,因为需要运行多种算法 - **权重**:Pixelmatch (60%) + SSIM (30%) + Average Hash (10%) ## API 调用 除了命令行工具,还可以作为库在 Node.js 项目中使用。 ### 安装 ```bash # 在项目中安装 npm install @mocha/image-comparer ``` ### 示例 #### 类实例化方式 ```typescript // CommonJS 导入 const { ImageComparator, AlgorithmType } = require('@mocha/image-comparer'); // ES6 导入 import { ImageComparator, AlgorithmType } from '@mocha/image-comparer'; // 使用示例 const comparator = new ImageComparator(); async function compareImages() { // 使用综合算法(默认) const result = await comparator.compare('image1.jpg', 'image2.jpg', { resizeTo: { width: 500, height: 500 } }); console.log(`综合算法相似度: ${result.similarity}%`); console.log(`使用算法: ${result.algorithm}`); // 使用特定算法 const pixelmatchResult = await comparator.compare('image1.jpg', 'image2.jpg', { algorithm: AlgorithmType.PIXELMATCH, resizeTo: { width: 500, height: 500 } }); console.log(`Pixelmatch相似度: ${pixelmatchResult.similarity}%`); const ssimResult = await comparator.compare('image1.jpg', 'image2.jpg', { algorithm: AlgorithmType.SSIM, resizeTo: { width: 500, height: 500 } }); console.log(`SSIM相似度: ${ssimResult.similarity}%`); const averageHashResult = await comparator.compare('image1.jpg', 'image2.jpg', { algorithm: AlgorithmType.AVERAGE_HASH, resizeTo: { width: 500, height: 500 } }); console.log(`Average Hash相似度: ${averageHashResult.similarity}%`); } compareImages(); // 查找文件夹中的重复图片 async function findDuplicates() { const duplicates = await comparator.findDuplicates('./images', { algorithm: AlgorithmType.COMBINED, // 使用综合算法 resizeTo: { width: 500, height: 500 }, minSimilarity: 90 }); console.log(`找到 ${duplicates.length} 对重复图片`); duplicates.forEach((pair, index) => { console.log(`${index + 1}. ${pair.image1} vs ${pair.image2}`); console.log(` 相似度: ${pair.result.similarity}%`); }); } findDuplicates(); // 比较两个文件夹 async function compareFolders() { const result = await comparator.compareFolders('./folderA', './folderB', { algorithm: AlgorithmType.COMBINED, resizeTo: { width: 500, height: 500 }, minSimilarity: 90, recursive: false }); console.log('仅存在于文件夹A的图片:', result.onlyInFolderA); console.log('仅存在于文件夹B的图片:', result.onlyInFolderB); console.log('相似图片对:', result.similarPairs); console.log('不相似图片对:', result.dissimilarPairs); } compareFolders(); ``` #### 函数式调用方式 ```typescript // CommonJS 导入 const { compare, findDuplicates, compareFolders, AlgorithmType } = require('@mocha/image-comparer'); // ES6 导入 import { compare, findDuplicates, compareFolders, AlgorithmType } from '@mocha/image-comparer'; // 比较两张图片 async function compareImagesFunc() { const result = await compare('image1.jpg', 'image2.jpg', { algorithm: AlgorithmType.COMBINED, resizeTo: { width: 500, height: 500 } }); console.log(`相似度: ${result.similarity}%`); } compareImagesFunc(); // 查找文件夹中的重复图片 async function findDuplicatesFunc() { const duplicates = await findDuplicates('./images', { algorithm: AlgorithmType.COMBINED, resizeTo: { width: 500, height: 500 }, minSimilarity: 90 }); console.log(`找到 ${duplicates.length} 对重复图片`); } findDuplicatesFunc(); // 比较两个文件夹 async function compareFoldersFunc() { const result = await compareFolders('./folderA', './folderB', { algorithm: AlgorithmType.COMBINED, resizeTo: { width: 500, height: 500 }, minSimilarity: 90 }); console.log('比较结果:', result); } compareFoldersFunc(); ``` ## 项目结构 ``` image-duplicate/ ├── src/ │ ├── index.ts # 主入口文件 │ ├── cli.ts # 命令行工具实现 │ ├── core/ │ │ ├── comparator.ts # 相似度对比核心逻辑 │ │ ├── algorithms/ # 各种对比算法实现 │ │ │ ├── pixelmatch.ts │ │ │ ├── ssim.ts │ │ │ └── averageHash.ts │ │ └── types.ts # 类型定义 │ ├── utils/ │ │ ├── imageLoader.ts # 图片加载工具 │ │ └── logger.ts # 日志工具 │ └── config/ # 配置文件目录 │ └── index.ts ├── test/ # 测试用例 ├── package.json ├── tsconfig.json ├── tsup.config.ts # tsup构建配置 └── README.md ``` ## 性能优化建议 1. **统一缩放尺寸**:使用 `--resize-to` 选项将图片缩放到较小尺寸,可以显著提高对比速度 2. **使用灰度图**:使用 `--grayscale` 选项可以减少计算量 3. **选择合适的算法**:Pixelmatch 算法速度更快,SSIM 算法结果更准确,Average Hash 算法适合快速筛选 4. **批量处理**:对于大量图片,建议使用文件夹批量处理功能 5. **多核并行处理**:系统会自动使用多核CPU进行并行处理,提高处理速度 6. **动态并发调整**:系统会根据任务大小自动调整并发数,对于小任务使用顺序处理以减少线程开销 7. **合理设置阈值**:对于文件夹对比,设置合适的相似度阈值可以减少不必要的计算 ## 支持的图片格式 - JPEG - PNG - WebP - TIFF - GIF - SVG ## 常见问题 ### Q: 为什么对比结果与预期不符? A: 可能的原因: - 图片尺寸差异较大,建议使用 `--resize-to` 统一尺寸 - 光照条件差异,建议使用 `--grayscale` 转为灰度图 - 选择了不适合的算法,尝试切换算法类型 ### Q: 如何提高对比速度? A: 可以尝试以下方法: - 使用 `--resize-to` 缩小图片尺寸 - 使用 `--grayscale` 转为灰度图 - 使用 Pixelmatch 算法 - 减少文件夹递归深度 ## 开发 ### 构建项目 ```bash npm run build ``` 项目使用 tsup 进行构建优化,包括: - 代码压缩和混淆 - 移除注释和未使用的代码 - 生成多种模块格式(CommonJS 和 ES6) - 并行构建以提高速度 构建产物位于 `dist` 目录中。 ### 运行开发模式 ```bash npm run dev ``` ### 运行测试 ```bash npm run test ``` ### 代码检查 ```bash npm run lint ``` ## 贡献 欢迎提交 Issue 和 Pull Request! ## 许可证 MIT License