Python使用CRC實現圖片去重
使用CRC32還可實現圖片去重功能,如下FindRepeatFile函數,運行后通過對所有文件做crc校驗并將校驗值存儲至CatalogueDict字典內,接著依次提取CRC特征值并將其存儲至CatalogueList列表內,接著通過統(tǒng)計特征值出現次數并將該次數放入到CountDict字典內,最后循環(huán)這個字典,并以此輸出文件特征與重復次數,將重復值放入到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():
# 循環(huán)查找字典中的數據,如果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格式文件,并輸出這些文件特征值,以及該特征的重復次數,如下圖所示;

有了上述方法我們就可以實現去重了,當然上述方法還可以優(yōu)化,通過使用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類型,掃描該目錄下所有重復文件,并將該文件移除,輸出效果如下圖所示;

當然上述方法是一次性清楚重復文件,在某些時候我們希望存入文件后自動清理,此時就需要動態(tài)監(jiān)控文件或目錄變化,函數MonitoringDirectory()可用于動態(tài)監(jiān)控用戶目錄,當有新文件創(chuàng)建時自動校驗是否存在該文件如果存在則刪除重復的,其實現原理是不間斷的遍歷目錄,當有新文件產生時自動將該文件計算特征對比,如果重復則刪除,該方式雖然可實現目錄監(jiān)控但效率卻很低,因為要不間斷的遍歷目錄。
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
# 開始監(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]
# 新增文件時觸發(fā)
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
# 循環(huán)池內的所有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
# 刪除文件時觸發(fā)
if removed:
print("移除文件: {}".format(removed))
before = after
if __name__ == "__main__":
MonitoringDirectory("d://lyshark")
運行上述程序,則會監(jiān)控d://lyshark目錄,當有心文件被創(chuàng)建時會自動對比特征值,如果相同則會被清理,如果無重復的則會被保留,如下圖所示;

到此這篇關于Python使用CRC實現圖片去重的文章就介紹到這了,更多相關Python圖片去重內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在Linux系統(tǒng)上安裝Python的Scrapy框架的教程
這篇文章主要介紹了在Linux系統(tǒng)上安裝Python的Scrapy框架的教程,Scrapy是著名的專門針對搜索引擎的爬蟲制作而研發(fā)的Python框架,需要的朋友可以參考下2015-06-06
Python Pillow 圖像處理庫詳解(常用Pillow函數及其參數)
Pillow,原名PIL(Python Imaging Library),是一個功能強大的Python圖像處理庫,支持多種格式,提供豐富的圖像操作功能,如旋轉、縮放、顏色轉換等,以及易于使用的API,Pillow支持廣泛的圖像文件格式,并提供圖像過濾、繪制等功能2024-09-09

