图片对比 dHash

■环境                         
    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))

图片对比 dHash

转载于:https://blog.51cto.com/13685327/2097262

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值