■环境
Python 3.6.0
Pycharm 2017.1.3
■库、库的版本
PIL 1.1.7
Pillow 3.4.2
■参考
https://segmentfault.com/a/1190000004467183
■逻辑
1. 打开图片。
2. 修改图片大小,12*12(图片越大,精度越高)。
3. 转成灰度图,使用Image的对象的方法convert(‘L‘)。
4. 获取图片指纹:遍历灰度图的所有像素,左边比右边大则+1,否则+0。
5. 对比两张图片的指纹,得到汉明距离。
6. 汉明距离等于0说明两张图片完全一样。
7. 当两张图片的字节数大小一样时才对比。
from PIL import Image
import os
import datetime
def get_img_fingerprints(image_gray):
"""
获取图片指纹:遍历灰度图的所有像素,左边比右边大则+1,否则+0。
:param image_gray: 灰度图
:return: 获取图片指纹
"""
fingerprints = ‘‘
for h in range(0, image_gray.size[1]):
for w in range(0, image_gray.size[0] - 1):
left = image_gray.getpixel((w, h))
right = image_gray.getpixel((w + 1, h))
if left > right:
fingerprints += ‘1‘
else:
fingerprints += ‘0‘
return fingerprints
def get_img_gray_bit(image, resize=(9, 8)):
"""
获取图片指纹
:param image: 图片
:param resize: Resize的图片大小
:return: 图片指纹
"""
# 修改图片大小
image_resize = image.resize(resize)
# 修改图片成灰度图
image_gray = image_resize.convert("L")
# 获取图片指纹
img_fingerprints = get_img_fingerprints(image_gray)
return img_fingerprints
def get_mh(img_fingerprints1, img_fingerprints2):
"""
获取汉明距离
:param img_fingerprints1: 比较对象1的指纹
:param img_fingerprints2: 比较对象2的指纹
:return: 汉明距离
"""
hm = 0
for i in range(0, len(img_fingerprints1)):
if img_fingerprints1[i] != img_fingerprints2[i]:
hm += 1
return hm
def is_image_file(file_name):
"""
判断文件是否是图片
:param file_name: 文件名称(包含后缀信息)
:return: 1:图片,0:非图片
"""
ext = (os.path.splitext(file_name)[1]).lower()
if ext == ".jpg" or ext == ".jpeg" or ext == ".bmp" or ext == ".png":
return 1
return 0
def get_all_img_list(root_path):
"""
获取目标文件夹下所有图片路径集合
:param root_path: 目标文件夹
:return: 图片集合
"""
img_list = []
# 获取目标文件夹下所有元组
root = os.walk(root_path)
# 循环元组,获取目标文件夹下所有图片路径集合
for objects in root:
for obj in objects:
if "/" in str(obj):
# 记录文件夹路径
path = str(obj)
elif len(obj) > 0:
# 如果是文件,判断是否是图片。如果是图片则保存进
for file in obj:
if "." in str(file) and is_image_file(file) == 1:
full_path = path + "/" + str(file)
img_list.append(full_path.replace("\\", "/"))
return img_list
def compare_img(root_path):
"""
比较图片 (Main)
:param root_path: 目标文件夹
"""
compared_list = []
# 获取目标文件夹下所有图片路径集合
img_list = get_all_img_list(root_path)
# 遍历目标文件夹下所有图片进行两两比较
for file1 in img_list:
# 已经发现是相同的图片不再比较
if file1 in compared_list:
continue
im1 = Image.open(file1)
im1_size = os.path.getsize(file1)
img_fingerprints1 = get_img_gray_bit(im1)
for file2 in img_list:
# 当不是自己时再比较
if file1 != file2:
im2 = Image.open(file2)
im2_size = os.path.getsize(file2)
# 如果两张图片字节数大小一样再判断汉明距离
if im1_size == im2_size:
img_fingerprints2 = get_img_gray_bit(im2)
compare_result = get_mh(img_fingerprints1, img_fingerprints2)
# 汉明距离等于0,说明两张图片完全一样
if compare_result == 0:
print("图片相同:" + file1 + "::::::" + file2)
compared_list.append(file1)
compared_list.append(file2)
start_time = datetime.datetime.now()
start_time = start_time.strftime(‘%Y-%m-%d %H:%M:%S‘)
print("start time: " + start_time)
compare_img("C:/Users/x230/Desktop/test")
end_time = datetime.datetime.now()
end_time = end_time.strftime(‘%Y-%m-%d %H:%M:%S‘)
print("end time: " + end_time)
d1 = datetime.datetime.strptime(start_time, ‘%Y-%m-%d %H:%M:%S‘)
d2 = datetime.datetime.strptime(end_time, ‘%Y-%m-%d %H:%M:%S‘)
print("耗时: " + str((d2 - d1).seconds))
原文地址:http://blog.51cto.com/13685327/2097262