Python实现文件夹内相似图片批量删除的两种算法

落日邮差
落日邮差
发布时间:2026-10-14 | 4人浏览过
原创

本文介绍使用Python批量删除同一文件夹下相似图片的两种方法。第一种方法通过相邻文件比较,适合视频截图等连续图像,效率较高;第二种方法采用逐个比对策略,准确率更高但耗时较长。文章提供了基于OpenCV和scikit-image的完整代码示例,涵盖SSIM相似度计算及文件删除逻辑。

Python删除相似图片的两种实现方案

前言

在整理图片资源时,常遇到大量内容高度相似的图片。为解决这一问题,编写了相应的Python脚本进行清理。本文提供两种不同的处理方案供选择。

需要注意的是,第一种方法主要适用于连续生成的图片(例如从视频中截取的一系列帧),其处理效率较高,但准确率相对有限;第二种方法虽然处理速度较慢,但在识别相似性方面更为准确。

方法一:相邻文件比较法

方法一的核心逻辑是:依次比较相邻的两个文件相似度,若判定为相似,则将后一个文件加入待删除列表,最后对该列表进行去重处理并统一执行删除操作。

具体流程示例:假设有文件1至10。首先比较文件1和文件2,若两者相似,则将文件2加入新列表;接着比较文件2和文件3,若不相似,则继续比较文件3和文件4,依此类推直至文件10。处理结束后,删除新列表中包含的所有图片。

相关实现代码如下:

方法一代码实现


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import cv2
from skimage.measure import compare_ssim
# import shutil
# def yidong(filename1,filename2):
#     shutil.move(filename1,filename2)
def delete(filename1):
    os.remove(filename1)
if __name__ == '__main__':
    path = r'D:\camera_pic\test\rec_pic'
    # save_path_img = r'E:\0115_test\rec_pic'
    # os.makedirs(save_path_img, exist_ok=True)
    img_path = path
    imgs_n = []
    num = []
    img_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(path) for file in files if
                 (file.endswith('.jpg'))]
    for currIndex, filename in enumerate(img_files):
        if not os.path.exists(img_files[currIndex]):
            print('not exist', img_files[currIndex])
            break
        img = cv2.imread(img_files[currIndex])
        img1 = cv2.imread(img_files[currIndex + 1])
        ssim = compare_ssim(img, img1, multichannel=True)
        if ssim > 0.9:
            imgs_n.append(img_files[currIndex + 1])
            print(img_files[currIndex], img_files[currIndex + 1], ssim)
        else:
            print('small_ssim',img_files[currIndex], img_files[currIndex + 1], ssim)
        currIndex += 1
        if currIndex >= len(img_files)-1:
            break
    for image in imgs_n:
        # yidong(image, save_path_img)
        delete(image)

方法二:逐个比对去重法

方法二采用逐个比较策略:遍历文件列表,若发现相似图片,则将其从原列表中移除并加入待删除列表;若不相似,则继续后续比较。

具体流程示例:假设有文件1至10。首先比较文件1和文件2,若相似,则将文件2从原列表删除并加入待删除列表;接着继续用文件1与文件3比较,若不相似,则用文件1与文件4比较,直至文件1与最后一个文件比较完毕。随后,理论上应从原列表的下一个文件(即原文件2)开始,但因其已被删除,故从剩余文件的下一个(即原文件3)开始,重复上述操作,最后删除待删除列表中的所有图片。

相关实现代码如下:

方法二代码实现


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import cv2
from skimage.measure import compare_ssim
import shutil
import datetime
def yidong(filename1,filename2):
    shutil.move(filename1,filename2)
def delete(filename1):
    os.remove(filename1)
    print('real_time:',now_now-now)
if __name__ == '__main__':
    path = r'F:\temp\demo'
    # save_path_img = r'F:\temp\demo_save'
    # os.makedirs(save_path_img, exist_ok=True)
    for (root, dirs, files) in os.walk(path):
        for dirc in dirs:
            if dirc == 'rec_pic':
                pic_path = os.path.join(root, dirc)
                img_path = pic_path
                imgs_n = []
                num = []
                del_list = []
                img_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(img_path) for file in files if
                             (file.endswith('.jpg'))]
                for currIndex, filename in enumerate(img_files):
                    if not os.path.exists(img_files[currIndex]):
                        print('not exist', img_files[currIndex])
                        break
                    new_cur = 0
                    for i in range(10000000):
                        currIndex1 =new_cur
                        if currIndex1 >= len(img_files) - currIndex - 1:
                            break
                        else:
                            size = os.path.getsize(img_files[currIndex1 + currIndex + 1])
                            if size < 512:
                                # delete(img_files[currIndex + 1])
                                del_list.append(img_files.pop(currIndex1 + currIndex + 1))
                            else:
                                img = cv2.imread(img_files[currIndex])
                                img = cv2.resize(img, (46, 46), interpolation=cv2.INTER_CUBIC)
                                img1 = cv2.imread(img_files[currIndex1 + currIndex + 1])
                                img1 = cv2.resize(img1, (46, 46), interpolation=cv2.INTER_CUBIC)
                                ssim = compare_ssim(img, img1, multichannel=True)
                                if ssim > 0.9:
                                    # imgs_n.append(img_files[currIndex + 1])
                                    print(img_files[currIndex], img_files[currIndex1 + currIndex + 1], ssim)
                                    del_list.append(img_files.pop(currIndex1 + currIndex + 1))
                                    new_cur = currIndex1
                                else:
                                    new_cur = currIndex1 + 1
                                    print('small_ssim',img_files[currIndex], img_files[currIndex1 + currIndex + 1], ssim)
                for image in del_list:
                    # yidong(image, save_path_img)
                    delete(image)
                    print('delete',image)

总结

至此,关于使用Python删除同一文件夹下相似图片的介绍已完成。如需了解更多相关Python文件处理技巧,可查阅本站过往文章或继续浏览后续内容。感谢大家的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表