首先声明一下,代码是从网上找到的,只是本人作以简单的修改。

请大家尊重原创。

我本地用到的是

Python 3.4   以及 Pillow (4.0.0)  第三方包。

方法一、

#!/usr/bin/python
# coding : utf-8
import glob
import os
import sys
from functools import reduce from PIL import Image # EXTS = 'jpg', 'jpeg', 'JPG', 'JPEG', 'gif', 'GIF', 'png', 'PNG'
EXTS = 'jpg', 'jpeg', 'gif', 'png' # 通过计算哈希值来得到该张图片的“指纹”
def avhash(im):
# 判断参数im,是不是Image类的一个参数
try:
if not isinstance(im, Image.Image):
im = Image.open(im)
except OSError as ose:
print("打不开图片:{}".format(im))
return "ng"
# resize,格式转换,把图片压缩成8*8大小,ANTIALIAS是抗锯齿效果开启,“L”是将其转化为
# 64级灰度,即一共有64种颜色
im = im.resize((8, 8), Image.ANTIALIAS).convert('L')
# 递归取值,这里是计算所有
# 64个像素的灰度平均值
avg = reduce(lambda x, y: x + y, im.getdata()) / 64.
print(reduce(func_reduce_param, enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())), 0))
# 比较像素的灰度,将每个像素的灰度与平均值进行比较,>=avg:1;<avg:0
return reduce(func_reduce_param,
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())), 0) def func_reduce_param(x, a):
if type(a) == tuple:
y = a[0]
z = a[1]
return x | (z << y) # 比较指纹,等同于计算“汉明距离”(两个字符串对应位置的字符不同的个数)
def hamming(h1, h2):
if h1 == "ng" or h2 == "ng":
return "获取指纹失败。"
h, d = 0, h1 ^ h2
while d:
h += 1
d &= d - 1
return h def compare(img1, img2):
if os.path.isfile(img1):
print("源图为:{}".format(img1))
else:
print("给定的源图片:{} 不存在".format(img1))
return "img1" if os.path.isfile(img2):
print("对比图为:{}".format(img2))
else:
print("给定的对比图片:{} 不存在".format(img2))
return "img2" ham = hamming(avhash(img2), avhash(img1))
if type(ham) == int:
if ham == 0:
print("源图:{} 与对比图:{} 一样。{}".format(img1, img2, ham))
elif ham <= 3:
print("源图:{} 与对比图:{} 存在差异。{}".format(img1, img2, ham))
elif ham <= 5:
print("源图:{} 与对比图:{} 对比明显存在差异。{}".format(img1, img2, ham))
elif ham <= 8:
print("源图:{} 与对比图:{} 还能看到一点儿相似的希望。{}".format(img1, img2, ham))
elif ham <= 10:
print("源图:{} 与对比图:{} 这两张图片有相同点,但少的可怜啊。{}".format(img1, img2, ham))
elif ham > 10:
print("源图:{} 与对比图:{} 不一样。{}".format(img1, img2, ham))
else:
print("未知的结果,无法完成对比。")
return "" def compare_many_pic(img, abs_dir):
if os.path.isfile(img):
print("源图为:{}".format(img))
else:
print("给定的源图片:{} 不存在".format(img))
print("Usage: image.jpg [dir]")
return "img"
if os.path.isdir(abs_dir):
print("给定目录为:{}".format(abs_dir))
else:
print("给定的目录:{} 不存在".format(abs_dir))
print("Usage: image.jpg [dir]")
return "dir" h = avhash(img) os.chdir(abs_dir)
images = []
for ext in EXTS:
images.extend(glob.glob('*.%s' % ext))
print(images) seq = []
prog = int(len(images) > 50 and sys.stdout.isatty())
for f in images:
seq.append((f, hamming(avhash(f), h)))
if prog:
perc = 100. * prog / len(images)
x = int(2 * perc / 5)
print('\rCalculating... [' + '#' * x + ' ' * (40 - x) + ']')
print('%.2f%%' % perc, '(%d/%d)' % (prog, len(images)))
sys.stdout.flush()
prog += 1 if prog: print("")
for f, ham in sorted(seq, key=lambda i: i[1]):
print("{}\t{}".format(ham, f))
return "" if __name__ == '__main__': compare(img1="./images/1.png", img2="./images/4.png") 此方法的详细描述,已经在代码中给出,不做赘述。 方法二、
# 原作者发布在GitHub上的一些列图片对比的方法。有兴趣研究的可以访问链接如下:
# https://github.com/MashiMaroLjc/Learn-to-identify-similar-images
# coding : utf-8
from PIL import Image def calculate(image1, image2):
g = image1.histogram()
s = image2.histogram()
assert len(g) == len(s), "error" data = [] for index in range(0, len(g)):
if g[index] != s[index]:
data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))
else:
data.append(1) return sum(data) / len(g) def split_image(image, part_size):
pw, ph = part_size
w, h = image.size sub_image_list = [] assert w % pw == h % ph == 0, "error" for i in range(0, w, pw):
for j in range(0, h, ph):
sub_image = image.crop((i, j, i + pw, j + ph)).copy()
sub_image_list.append(sub_image) return sub_image_list def classfiy_histogram_with_split(image1, image2, size=(256, 256), part_size=(64, 64)):
'''
'image1' 和 'image2' 都是Image 对象.
可以通过'Image.open(path)'进行创建。
'size' 重新将 image 对象的尺寸进行重置,默认大小为256 * 256 .
'part_size' 定义了分割图片的大小.默认大小为64*64 .
返回值是 'image1' 和 'image2'对比后的相似度,相似度越高,图片越接近,达到100.0说明图片完全相同。
'''
img1 = image1.resize(size).convert("RGB")
sub_image1 = split_image(img1, part_size) img2 = image2.resize(size).convert("RGB")
sub_image2 = split_image(img2, part_size) sub_data = 0
for im1, im2 in zip(sub_image1, sub_image2):
sub_data += calculate(im1, im2) x = size[0] / part_size[0]
y = size[1] / part_size[1] pre = round((sub_data / (x * y)), 6)
print(pre * 100)
return pre * 100 if __name__ == '__main__':
image1 = Image.open("./images/1.png")
image2 = Image.open("./images/brain.jpg")
classfiy_histogram_with_split(image1, image2) 对比方法一和方法二,在执行的效率上基本一致,但是在对比的准确度上,方法二要优于方法一。

Python3.0以上版本在对比图片相似中的应用的更多相关文章

  1. VMware vSphere 5.x 与 vSphere 6.0各版本功能特性对比

    各版本中的新特性及功能对比:   VMware vSphere 5.0 VMware vSphere 5.1 VMware vSphere 5.5 VMware vSphere 6.0 ESXi 5. ...

  2. 记录一次MongoDB3.0.6版本wiredtiger与MMAPv1引擎的写入耗时对比

    一.MongoDB3.0.x的版本特性(相对于MongoDB2.6及以下): 增加了wiredtiger引擎: 开源的存储引擎: 支持多核CPU.充分利用内存/芯片级别缓存(注:10月14日刚刚发布的 ...

  3. 【和我一起学Python吧】Python3.0与2.X版本的区别

    做为一个前端开发的码农,却正在阅读最新版的<A byte of Python>.发现Python3.0在某些地方还是有些改变的.准备慢慢的体会,与老版本的<A byte of Pyt ...

  4. centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'

    centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'的解决办法 3.7版本需要一个新的包libffi-de ...

  5. Python3 与 C# 面向对象之~继承与多态 Python3 与 C# 面向对象之~封装 Python3 与 NetCore 基础语法对比(Function专栏) [C#]C#时间日期操作 [C#]C#中字符串的操作 [ASP.NET]NTKO插件使用常见问题 我对C#的认知。

    Python3 与 C# 面向对象之-继承与多态   文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html 目录: 2.继承 ¶ 2.1.单继 ...

  6. oracle数据库升级记(记一次10.2.0.3版本升级到11.2.0.1版本的过程)

    操作系统:windows xp 已有数据库版本:10.2.0.3 升级目标版本:11.2.0.1 步骤大纲: 在源操作系统(安装有10.2.0.3数据库的操作系统)上安装11.2.0.1数据库软件,然 ...

  7. Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1Python 3_x 新特性1python3.4新特性1python3.5新特性1值得关注的新特性1Pyth

    Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1 Python 3_x 新特性1 python3.4新特性1 python3.5新特性1 值得关注的新特性1 ...

  8. 【转载】python3.0与2.x之间的区别

    python3.0与2.x之间的区别: 1.性能 Py3.0运行pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好 ...

  9. Windows8 各种版本区别对比详解

    微软的 Windows8 操作系统提供了4个不同的版本,分别是 Windows RT.Windows 8 标准版.Windows 8 Pro 专业版 以及 Windows 8 Enterprise 企 ...

随机推荐

  1. docker进程分析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/80970541 序言      闷热. ...

  2. CentOS安装和配置Apache(httpd)

    1. 安装httpd yum install httpd #安装apache 2. 启动httpd systemctl start httpd.service #启动apache 3. 随服务器自启动 ...

  3. 源码分析八( hashmap工作原理)

    首先从一条简单的语句开始,创建了一个hashmap对象: Map<String,String> hashmap = new HashMap<String,String>(); ...

  4. 【2019年03月29日】股票的滚动市盈率PE最低排名

    仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 深康佳A(SZ000016) - 滚动市盈率PE:2.51 - 滚动市净率PB:1.68 - 滚动年化股息收益率:2.9% - - - ...

  5. [LeetCode] Majority Element 求大多数

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  6. 更改ORACLE归档路径及归档模式

    更改ORACLE归档路径及归档模式   在ORACLE10g和11g版本,ORACLE默认的日志归档路径为闪回恢复区($ORACLE_BASE/flash_recovery_area).对于这个路径, ...

  7. 用TreeSet生成不重复自动排序随机数组

    随机数组就是在指定长度的数组中用随机数字为每个元素赋值,常用于不确定数值的环境,如拼图游戏需要随机数组来打乱图片顺序.可是同时也存在问题,就是随机数的重复问题,这个问题常常被忽略. TreeSet类的 ...

  8. ArcGIS AddIN异常:无法注册程序集 未能加载文件或程序集"ESRI.ArcGIS.Desktop.Addins"

    异常: 无法注册程序集“D:\CodeXX\bin\Debug\XX.dll”.未能加载文件或程序集“ESRI.ArcGIS.Desktop.AddIns, Version=10.1.0.0, Cul ...

  9. Intellij IDEA快捷键与使用技巧一览表

    Intellij IDEA快捷键 Ctrl+Shift + Enter,语句完成 "!",否定完成,输入表达式时按 "!"键 Ctrl+E,最近的文件 Ctrl ...

  10. gui小计算器的程序写法

    import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.sw ...