Python使用CRC實(shí)現(xiàn)圖片去重
使用CRC32
還可實(shí)現(xiàn)圖片去重功能,如下FindRepeatFile
函數(shù),運(yùn)行后通過對所有文件做crc
校驗(yàn)并將校驗(yàn)值存儲(chǔ)至CatalogueDict
字典內(nèi),接著依次提取CRC
特征值并將其存儲(chǔ)至CatalogueList
列表內(nèi),接著通過統(tǒng)計(jì)特征值出現(xiàn)次數(shù)并將該次數(shù)放入到CountDict
字典內(nèi),最后循環(huán)這個(gè)字典,并以此輸出文件特征與重復(fù)次數(shù),將重復(fù)值放入到RepeatFileFeatures
列表內(nèi)。
如下代碼所示;
import zlib,os def Find_Repeat_File(file_path,file_type): Catalogue = os.listdir(file_path) CatalogueDict = {} # 查詢字典,方便后期查詢鍵值對對應(yīng)參數(shù) 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校驗(yàn): {}".format(path,str(crc32))) CatalogueDict[each] = str(crc32) CatalogueList = [] for value in CatalogueDict.values(): # 該過程實(shí)現(xiàn)提取字典中的crc32特征組合成列表 CatalogueList CatalogueList.append(value) CountDict = {} for each in CatalogueList: # 該過程用于存儲(chǔ)文件特征與特征重復(fù)次數(shù),放入 CountDict CountDict[each] = CatalogueList.count(each) RepeatFileFeatures = [] for key,value in CountDict.items(): # 循環(huán)查找字典中的數(shù)據(jù),如果value大于1就存入 RepeatFileFeatures if value > 1: print("[-] 文件特征: {} 重復(fù)次數(shù): {}".format(key,value)) RepeatFileFeatures.append(key) if __name__ == "__main__": Find_Repeat_File("D://lyshark/",".png")
運(yùn)行上述代碼,則會(huì)掃描d://lyshark/
目錄下所有的png
格式文件,并輸出這些文件特征值,以及該特征的重復(fù)次數(shù),如下圖所示;
有了上述方法我們就可以實(shí)現(xiàn)去重了,當(dāng)然上述方法還可以優(yōu)化,通過使用groupby
功能可以自動(dòng)實(shí)現(xiàn)分組,f恩組后我們只需要對分組進(jìn)行排序,并尋找對應(yīng)符合條件的特征,找到后直接調(diào)用os.remove
將其移除即可,實(shí)現(xiàn)代碼如下所示;
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校驗(yàn): {}".format(path,str(crc32))) CatalogueList.append({ "CRC32": str(crc32) , "FILE": path }) # 首先排序,然后根據(jù)字典中的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("---> 重復(fù)圖片: {} 已移除".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/
并設(shè)置.png
類型,掃描該目錄下所有重復(fù)文件,并將該文件移除,輸出效果如下圖所示;
當(dāng)然上述方法是一次性清楚重復(fù)文件,在某些時(shí)候我們希望存入文件后自動(dòng)清理,此時(shí)就需要?jiǎng)討B(tài)監(jiān)控文件或目錄變化,函數(shù)MonitoringDirectory()
可用于動(dòng)態(tài)監(jiān)控用戶目錄,當(dāng)有新文件創(chuàng)建時(shí)自動(dòng)校驗(yàn)是否存在該文件如果存在則刪除重復(fù)的,其實(shí)現(xiàn)原理是不間斷的遍歷目錄,當(dāng)有新文件產(chǎn)生時(shí)自動(dòng)將該文件計(jì)算特征對比,如果重復(fù)則刪除,該方式雖然可實(shí)現(xiàn)目錄監(jiān)控但效率卻很低,因?yàn)橐婚g斷的遍歷目錄。
import os, time from zlib import crc32 # 計(jì)算目標(biāo)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 # 開始監(jiān)控目錄 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] # 新增文件時(shí)觸發(fā) if added: # print("新建文件: {}".format(added)) for index in range(0,len(added)): # 計(jì)算文件CRC32 AbsolutePath = path_to_watch + "/" + added[index] crc = Calculation_crc32(AbsolutePath) print(f"計(jì)算文件路徑: {AbsolutePath} 文件CRC32: {crc}") # 只要有新文件則加入到crc_pool if crc != 0: crc_poll.append(crc) print("池內(nèi)數(shù)據(jù): {}".format(crc_poll)) crc_count = 0 # 循環(huán)池內(nèi)的所有CRC數(shù)據(jù) for index in range(0,len(crc_poll)): # 如果當(dāng)前文件CRC與池內(nèi)某個(gè)一致則遞增 if crc_poll[index] == crc: crc_count = crc_count + 1 # 只要大于2則說明有重復(fù)的 if crc_count >= 2: try: print("存在校驗(yàn)值,刪除文件: {}".format(AbsolutePath)) os.remove(AbsolutePath) crc_poll.remove(crc) except Exception: pass # 刪除文件時(shí)觸發(fā) if removed: print("移除文件: {}".format(removed)) before = after if __name__ == "__main__": MonitoringDirectory("d://lyshark")
運(yùn)行上述程序,則會(huì)監(jiān)控d://lyshark
目錄,當(dāng)有心文件被創(chuàng)建時(shí)會(huì)自動(dòng)對比特征值,如果相同則會(huì)被清理,如果無重復(fù)的則會(huì)被保留,如下圖所示;
到此這篇關(guān)于Python使用CRC實(shí)現(xiàn)圖片去重的文章就介紹到這了,更多相關(guān)Python圖片去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python深度學(xué)習(xí)tensorflow入門基礎(chǔ)教程示例
這篇文章主要為大家介紹了python深度學(xué)習(xí)tensorflow入門基礎(chǔ)教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06在Linux系統(tǒng)上安裝Python的Scrapy框架的教程
這篇文章主要介紹了在Linux系統(tǒng)上安裝Python的Scrapy框架的教程,Scrapy是著名的專門針對搜索引擎的爬蟲制作而研發(fā)的Python框架,需要的朋友可以參考下2015-06-06Python&Matlab實(shí)現(xiàn)櫻花的繪制
正值櫻花飄落的季節(jié),本文將利用Python和Matlab分別繪制一顆櫻花樹,文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起動(dòng)手嘗試一下2022-04-04Python Pillow 圖像處理庫詳解(常用Pillow函數(shù)及其參數(shù))
Pillow,原名PIL(Python Imaging Library),是一個(gè)功能強(qiáng)大的Python圖像處理庫,支持多種格式,提供豐富的圖像操作功能,如旋轉(zhuǎn)、縮放、顏色轉(zhuǎn)換等,以及易于使用的API,Pillow支持廣泛的圖像文件格式,并提供圖像過濾、繪制等功能2024-09-09Python使用Qt5實(shí)現(xiàn)水平導(dǎo)航欄的示例代碼
本文主要介紹了Python使用Qt5實(shí)現(xiàn)水平導(dǎo)航欄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Python實(shí)現(xiàn)輕松讀取大文件的技巧揭秘
Python提供了多種方法來讀取文件內(nèi)容,其中包括read()、readline()和readlines()三個(gè)常用的函數(shù),本文將深入探討這三個(gè)函數(shù)的使用方法,需要的可以參考一下2023-08-08