平均哈希法matlab,图片对比 平均哈希法(aHash)

■环境

Python 3.6.0

Pycharm 2017.1.3

■库、库的版本

PIL 1.1.7

Pillow 3.4.2

■参考

https://segmentfault.com/a/1190000004467183

https://www.cnblogs.com/tomato0906/articles/5616692.html

■逻辑

1. 打开图片。

2. 修改图片大小,12*12(图片越大,精度越高)。

3. 转成灰度图,使用Image的对象的方法convert('L')。

4. 计算灰度图的所有像素平均值。

5. 获取图片指纹:遍历灰度图的所有像素,比平均值大则记录为1,否则记录为0。

6. 对比两张图片的指纹,得到汉明距离。

7. 汉明距离等于0说明两张图片完全一样。

8. 当两张图片的字节数大小一样时才对比。

from PIL import Image

import os

import datetime

def get_img_gray_list(image_gray):

"""

获取灰度图像素集合

:param image_gray: 灰度图

:return: 灰度图像素集合

"""

gray_list = []

for h in range(0, image_gray.size[1]):

for w in range(0, image_gray.size[0]):

gray_list.append(image_gray.getpixel((w, h)))

return gray_list

def get_img_gray_avg(gray_list):

"""

获取灰度图像素平均值

:param gray_list: 灰度图像素集合

:return: 灰度图像素平均值

"""

return sum(gray_list) / len(gray_list)

def get_img_fingerprints(image_gray, image_gray_avg):

"""

获取图片指纹:遍历灰度图的所有像素,比平均值大则记录为1,否则记录为0。

:param image_gray: 灰度图

:param image_gray_avg: 灰度图像素平均值

:return: 图片指纹集合

"""

img_fingerprints = ''

for h in range(1, image_gray.size[1]):

for w in range(1, image_gray.size[0]):

if image_gray.getpixel((w, h)) > image_gray_avg:

img_fingerprints += '1'

else:

img_fingerprints += '0'

return img_fingerprints

def get_img_gray_bit(image, resize=(12, 12)):

"""

获取图片指纹

:param image: 图片

:param resize: Resize的图片大小

:return: 图片指纹

"""

# 修改图片大小

image_resize = image.resize(resize)

# 修改图片成灰度图

image_gray = image_resize.convert("L")

# 获取灰度图像素集合

gray_list = get_img_gray_list(image_gray)

# 获取灰度图像素平均值

image_gray_avg = get_img_gray_avg(gray_list)

# 获取图片指纹

img_fingerprints = get_img_fingerprints(image_gray, image_gray_avg)

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))

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值