Python实现文件夹内相似图片批量删除的两种算法
本文介绍使用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文件处理技巧,可查阅本站过往文章或继续浏览后续内容。感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









