图片批量去重工具保留最优

联启 电脑工具 14

本文目录导读:

图片批量去重工具保留最优-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

  1. 方案一:Python脚本(推荐)
  2. 方案二:使用现有工具
  3. 使用建议

我来帮你设计一个图片批量去重工具,它会自动比较图片并保留质量最好的那张。

Python脚本(推荐)

import os
import hashlib
import shutil
from PIL import Image
import concurrent.futures
from pathlib import Path
class ImageDeduplicator:
    def __init__(self, source_dir, output_dir="unique_images"):
        self.source_dir = Path(source_dir)
        self.output_dir = Path(output_dir)
        self.hash_dict = {}
        self.processed_count = 0
    def get_image_hash(self, image_path):
        """计算图片的感知哈希(用于相似度比较)"""
        try:
            with Image.open(image_path) as img:
                # 缩放到统一大小以提高比较速度
                img = img.resize((32, 32), Image.LANCZOS).convert('L')
                # 计算平均像素值
                pixels = list(img.getdata())
                avg = sum(pixels) / len(pixels)
                # 生成哈希值
                hash_str = ''.join(['1' if p > avg else '0' for p in pixels])
                return hash_str
        except Exception as e:
            print(f"处理图片 {image_path} 时出错: {e}")
            return None
    def get_file_hash(self, image_path):
        """计算文件的MD5哈希(用于精确重复检测)"""
        hasher = hashlib.md5()
        with open(image_path, 'rb') as f:
            buf = f.read(65536)  # 64KB chunks
            while len(buf) > 0:
                hasher.update(buf)
                buf = f.read(65536)
        return hasher.hexdigest()
    def get_image_quality(self, image_path):
        """评估图片质量(分辨率、文件大小等)"""
        try:
            with Image.open(image_path) as img:
                width, height = img.size
                file_size = os.path.getsize(image_path)
                # 质量评分:分辨率高 + 文件大小适中(不压缩过度)
                resolution_score = width * height
                file_score = min(file_size / 1000, 10000)  # 限制大小影响
                return resolution_score + file_score
        except:
            return 0
    def deduplicate(self, similarity_threshold=0.9):
        """执行去重操作"""
        os.makedirs(self.output_dir, exist_ok=True)
        # 获取所有图片文件
        image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'}
        image_files = []
        for ext in image_extensions:
            image_files.extend(list(self.source_dir.glob(f'**/*{ext}')))
            image_files.extend(list(self.source_dir.glob(f'**/*{ext.upper()}')))
        print(f"发现 {len(image_files)} 个图片文件")
        # 第一轮:MD5精确去重
        print("第一轮:MD5精确去重...")
        unique_md5 = {}
        for img_path in image_files:
            md5_hash = self.get_file_hash(img_path)
            if md5_hash not in unique_md5:
                unique_md5[md5_hash] = img_path
            else:
                # 比较质量,保留最优
                current_quality = self.get_image_quality(img_path)
                stored_quality = self.get_image_quality(unique_md5[md5_hash])
                if current_quality > stored_quality:
                    unique_md5[md5_hash] = img_path
        # 第二轮:感知哈希相似度去重
        print("第二轮:相似度去重...")
        unique_images = []
        for img_path in unique_md5.values():
            is_duplicate = False
            phash = self.get_image_hash(img_path)
            if phash is None:
                continue
            for stored_path, stored_hash in self.hash_dict.items():
                # 计算汉明距离
                if len(phash) == len(stored_hash):
                    distance = sum(c1 != c2 for c1, c2 in zip(phash, stored_hash))
                    similarity = 1 - (distance / len(phash))
                    if similarity >= similarity_threshold:
                        is_duplicate = True
                        # 比较质量
                        current_quality = self.get_image_quality(img_path)
                        stored_quality = self.get_image_quality(stored_path)
                        if current_quality > stored_quality:
                            # 替换为质量更好的
                            del self.hash_dict[stored_path]
                            self.hash_dict[img_path] = phash
                            unique_images.remove(stored_path)
                            unique_images.append(img_path)
                        break
            if not is_duplicate:
                self.hash_dict[img_path] = phash
                unique_images.append(img_path)
        # 复制保留的图片到输出目录
        print("复制保留的图片到输出目录...")
        for idx, img_path in enumerate(unique_images, 1):
            output_path = self.output_dir / f"unique_{idx}{img_path.suffix}"
            shutil.copy2(img_path, output_path)
            self.processed_count += 1
        print(f"\n去重完成!")
        print(f"原始图片数: {len(image_files)}")
        print(f"保留图片数: {len(unique_images)}")
        print(f"删除重复数: {len(image_files) - len(unique_images)}")
        print(f"结果保存在: {self.output_dir}")
# 使用示例
if __name__ == "__main__":
    # 创建去重器实例
    deduplicator = ImageDeduplicator(
        source_dir="your_images_folder",  # 替换为你的图片文件夹路径
        output_dir="deduplicated_images"  # 输出目录
    )
    # 执行去重(可调整相似度阈值,0-1之间,默认0.9)
    deduplicator.deduplicate(similarity_threshold=0.85)

使用现有工具

Duplicate Photo Fixer(推荐)

  • 支持智能相似度比较
  • 自动保留最高质量图片
  • 支持批量处理
  • 有免费版可用

AntiDupl.NET

  • 开源免费
  • 支持多种比较算法
  • 可自定义保留策略

ImageDupeless

  • 专注图片去重
  • 支持感知哈希比较
  • 可批量处理

使用建议

保留最优图片的标准:

  1. 分辨率:更高的分辨率优先
  2. 文件大小:适中的文件大小(避免过度压缩或膨胀)
  3. 格式:无损格式优先(PNG > JPEG)
  4. 拍摄信息:保留包含EXIF信息的图片

批量处理流程:

# 使用Python脚本(推荐)
python image_dedup.py
# 或使用命令行工具
antidupl --input ./images --output ./dedup --mode best-quality

注意事项:

  1. 备份原始文件:处理前先备份
  2. 调整阈值:根据图片相似度需求调整
  3. 预览结果:建议先小批量测试
  4. 清理残留:处理完后删除临时文件

这个工具可以帮你高效地清理重复图片,同时确保留下质量最好的版本,需要我详细解释某个部分吗?

标签: 最优保留

抱歉,评论功能暂时关闭!