Python使用CRC实现图片去重

 更新时间:2023年10月31日 14:03:40   作者:lyshark  
这篇文章主要为大家详细介绍了Python如何使用CRC实现图片去重功能,文中的示例代码讲解详细,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

使用CRC32还可实现图片去重功能,如下FindRepeatFile函数,运行后通过对所有文件做crc校验并将校验值存储至CatalogueDict字典内,接着依次提取CRC特征值并将其存储至CatalogueList列表内,接着通过统计特征值出现次数并将该次数放入到CountDict字典内,最后循环这个字典,并以此输出文件特征与重复次数,将重复值放入到RepeatFileFeatures列表内。

如下代码所示;

import zlib,os

def Find_Repeat_File(file_path,file_type):
    Catalogue = os.listdir(file_path)
    CatalogueDict = {}  # 查询字典,方便后期查询键值对对应参数
    for each in Catalogue:
        path = (file_path + each)
        if os.path.splitext(path)[1] == file_type:
            with open(path,"rb") as fp:
                crc32 = zlib.crc32(fp.read())
                # print("[*] 文件名: {} CRC32校验: {}".format(path,str(crc32)))
                CatalogueDict[each] = str(crc32)
    CatalogueList = []
    for value in CatalogueDict.values():
    # 该过程实现提取字典中的crc32特征组合成列表 CatalogueList
        CatalogueList.append(value)

    CountDict = {}
    for each in CatalogueList:
    # 该过程用于存储文件特征与特征重复次数,放入 CountDict
        CountDict[each] = CatalogueList.count(each)
        
    RepeatFileFeatures = []
    for key,value in CountDict.items():
    # 循环查找字典中的数据,如果value大于1就存入 RepeatFileFeatures
        if value > 1:
            print("[-] 文件特征: {} 重复次数: {}".format(key,value))
            RepeatFileFeatures.append(key)

if __name__ == "__main__":
    Find_Repeat_File("D://lyshark/",".png")

运行上述代码,则会扫描d://lyshark/目录下所有的png格式文件,并输出这些文件特征值,以及该特征的重复次数,如下图所示;

有了上述方法我们就可以实现去重了,当然上述方法还可以优化,通过使用groupby功能可以自动实现分组,f恩组后我们只需要对分组进行排序,并寻找对应符合条件的特征,找到后直接调用os.remove将其移除即可,实现代码如下所示;

import zlib,os,argparse
from operator import itemgetter
from itertools import groupby

def Find_Repeat_File(file_path,file_type):
    Catalogue = os.listdir(file_path)
    CatalogueList = []
    for each in Catalogue:
        path = (file_path + each)
        if os.path.splitext(path)[1] == file_type:
            with open(path,"rb") as fp:
                crc32 = zlib.crc32(fp.read())
                # print("[*] 文件名: {} CRC32校验: {}".format(path,str(crc32)))
                CatalogueList.append({ "CRC32": str(crc32) , "FILE": path })
    
    # 首先排序,然后根据字典中的CRC32排序
    CatalogueList.sort(key=itemgetter("CRC32"))
    for key,value in groupby(CatalogueList,key=itemgetter("CRC32")):
        # print("[*] CRC32特征码: {}\t".format(key))
        for each in value:
            RepeatNumber = len(list(value))
            if (RepeatNumber+1) > 1:
                try:
                    print("---> 重复图片: {} 已移除".format(each.values()))
                    os.remove(str(list(each.values())[1]))
                except FileNotFoundError:
                    pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-d","--dirs",dest="dirs",help="指定目录路径")
    parser.add_argument("-t","--types",dest="types",help="指定文件类型")
    args = parser.parse_args()
    # 使用方式: main.py -d "d://lyshark/" -t ".png"
    if args.dirs and args.types:
        os.chdir(args.dirs)
        try:
            for each in range(0,len(os.listdir())):
                Find_Repeat_File("./",args.types)
        except:
            pass
    else:
        parser.print_help()

如下图所示,我们通过传入d://lyshark/并设置.png类型,扫描该目录下所有重复文件,并将该文件移除,输出效果如下图所示;

当然上述方法是一次性清楚重复文件,在某些时候我们希望存入文件后自动清理,此时就需要动态监控文件或目录变化,函数MonitoringDirectory()可用于动态监控用户目录,当有新文件创建时自动校验是否存在该文件如果存在则删除重复的,其实现原理是不间断的遍历目录,当有新文件产生时自动将该文件计算特征对比,如果重复则删除,该方式虽然可实现目录监控但效率却很低,因为要不间断的遍历目录。

import os, time
from zlib import crc32

# 计算目标CRC32
def Calculation_crc32(filename):
    try:
        with open(filename,"rb") as fp:
            crc = crc32(fp.read())
            while True:
                temp = fp.read(8196)
                if not temp:
                    break
            fp.close()
            return crc
    except Exception:
        fp.close()
        return 0
    return 0

# 开始监控目录
def MonitoringDirectory(path_to_watch):
    crc_poll = []

    before = dict([(f, None) for f in os.listdir(path_to_watch)])
    while True:
        time.sleep (0.3)

        after = dict ([(f, None) for f in os.listdir (path_to_watch)])
        added = [f for f in after if not f in before]
        removed = [f for f in before if not f in after]

        # 新增文件时触发
        if added:
            # print("新建文件: {}".format(added))
            for index in range(0,len(added)):
                # 计算文件CRC32
                AbsolutePath = path_to_watch + "/" + added[index]
                crc = Calculation_crc32(AbsolutePath)
                print(f"计算文件路径: {AbsolutePath} 文件CRC32: {crc}")

                # 只要有新文件则加入到crc_pool
                if crc != 0:
                    crc_poll.append(crc)

                print("池内数据: {}".format(crc_poll))
                crc_count = 0

                # 循环池内的所有CRC数据
                for index in range(0,len(crc_poll)):

                    # 如果当前文件CRC与池内某个一致则递增
                    if crc_poll[index] == crc:
                        crc_count = crc_count + 1

                    # 只要大于2则说明有重复的
                    if crc_count >= 2:
                        try:
                            print("存在校验值,删除文件: {}".format(AbsolutePath))
                            os.remove(AbsolutePath)
                            crc_poll.remove(crc)
                        except Exception:
                            pass
        # 删除文件时触发
        if removed:
            print("移除文件: {}".format(removed))
        before = after

if __name__ == "__main__":
    MonitoringDirectory("d://lyshark")

运行上述程序,则会监控d://lyshark目录,当有心文件被创建时会自动对比特征值,如果相同则会被清理,如果无重复的则会被保留,如下图所示;

到此这篇关于Python使用CRC实现图片去重的文章就介绍到这了,更多相关Python图片去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 我对PyTorch dataloader里的shuffle=True的理解

    我对PyTorch dataloader里的shuffle=True的理解

    这篇文章主要介绍了我对PyTorch dataloader里的shuffle=True的理解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • Python 函数装饰器详解

    Python 函数装饰器详解

    这篇文章主要介绍了Python函数装饰器,结合实例形式详细分析了Python装饰器的原理、功能、分类、常见操作技巧与使用注意事项,需要的朋友可以参考下
    2021-10-10
  • pytorch中的weight-initilzation用法

    pytorch中的weight-initilzation用法

    这篇文章主要介绍了pytorch中的weight-initilzation用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • Pandas读存JSON数据操作示例详解

    Pandas读存JSON数据操作示例详解

    这篇文章主要为大家介绍了Pandas读存JSON数据操作示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 浅谈keras的深度模型训练过程及结果记录方式

    浅谈keras的深度模型训练过程及结果记录方式

    今天小编就为大家分享一篇浅谈keras的深度模型训练过程及结果记录方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • Python logging日志模块的概念与实践讲解

    Python logging日志模块的概念与实践讲解

    本文通过具体的代码示例为大家解释了如何高效地使用logging模块进行日志记录,以及如何避免常见的陷阱,希望可以帮助大家更好地掌握这个强大的工具
    2023-07-07
  • python利用while求100内的整数和方式

    python利用while求100内的整数和方式

    这篇文章主要介绍了 python利用while求100内的整数和方式,下面文章要描述的内容有1到100的和、1到100内的偶数和、1到100内的奇数和,具体详细内容,需要的朋友可以参考一下
    2021-11-11
  • python利用opencv实现SIFT特征提取与匹配

    python利用opencv实现SIFT特征提取与匹配

    这篇文章主要为大家详细介绍了python利用opencv实现SIFT特征提取与匹配,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • python分批定量读取文件内容,输出到不同文件中的方法

    python分批定量读取文件内容,输出到不同文件中的方法

    今天小编就为大家分享一篇python分批定量读取文件内容,输出到不同文件中的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • pytorch中tensor.expand()和tensor.expand_as()函数详解

    pytorch中tensor.expand()和tensor.expand_as()函数详解

    今天小编就为大家分享一篇pytorch中tensor.expand()和tensor.expand_as()函数详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12

最新评论