1.cosin相似度(余弦相似度)
把图片表示成一个向量,通过计算向量之间的余弦距离来表征两张图片的相似度
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time : 2018/11/17 14:52
# @Author : xhh
# @Desc : 余弦相似度计算
# @File : difference_image_consin.py
# @Software: PyCharm
from PIL import Image
from numpy import average, dot, linalg
# 对图片进行统一化处理
def get_thum(image, size=(64,64), greyscale=False):
# 利用image对图像大小重新设置, Image.ANTIALIAS为高质量的
image = image.resize(size, Image.ANTIALIAS)
if greyscale:
# 将图片转换为L模式,其为灰度图,其每个像素用8个bit表示
image = image.convert('L')
return image
# 计算图片的余弦距离
def image_similarity_vectors_via_numpy(image1, image2):
image1 = get_thum(image1)
image2 = get_thum(image2)
images = [image1, image2]
vectors = []
norms = []
for image in images:
vector = []
for pixel_tuple in image.getdata():
vector.append(average(pixel_tuple))
vectors.append(vector)
# linalg=linear(线性)+algebra(代数),norm则表示范数
# 求图片的范数??
norms.append(linalg.norm(vector, 2))
a, b = vectors
a_norm, b_norm = norms
# dot返回的是点积,对二维数组(矩阵)进行计算
res = dot(a / a_norm, b / b_norm)
return res
image1 = Image.open('../dataset/100002.png')
image2 = Image.open('../dataset/100001.png')
cosin = image_similarity_vectors_via_numpy(image1, image2)
print('图片余弦相似度',cosin)
运行结果:
该方法运算量较大,速度明显比ssim方法慢,但如果不计较快慢的话感受结果比ssim靠谱
2.利用SSIM(结构相似度度量)计算图片的相似度
是一种全参考的图像质量评价指标,分别从亮度、对比度、结构三个方面度量图像相似性。
SSIM取值范围[0, 1],值越大,表示图像失真越小。
在实际应用中,可以利用滑动窗将图像分块,令分块总数为N,考虑到窗口形状对分块的影响,采用高斯加权计算每一窗口的均值、方差以及协方差,然后计算对应块的结构相似度SSIM,最后将平均值作为两图像的结构相似性度量,即平均结构相似性SSIM
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time : 2018/11/17 14:26
# @Author : xhh
# @Desc : 结构相似度量,计算图片之间的相似度
# @File : difference_image_ssim.py
# @Software: PyCharm
from skimage.measure import compare_ssim
from scipy.misc import imread
import numpy as np
# 读取图片
img1 = imread('../dataset/100002.png')
img2 = imread('../dataset/100001.png')
img2 = np.resize(img2, (img1.shape[0], img1.shape[1], img1.shape[2]))
print(img1.shape)
print(img2.shape)
ssim = compare_ssim(img1, img2, multichannel = True)
print(ssim)
本来是打算使用opencv的imread来读取图片的,但是没想到报错了,但是随后改为
scipy.misc import imread成功了,最后又改成了opencv又好了,有点懵逼了
结果:
该方法通常用来衡量一张图片压缩后的失真度,很少用来计算两图的相似度。
3.通过直方图计算
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time : 2018/11/17 16:04
# @Author : xhh
# @Desc : 通过直方图计算图片的相似度
# @File : difference_image_hist.py
# @Software: PyCharm
from PIL import Image
# 将图片转化为RGB
def make_regalur_image(img, size=(64, 64)):
gray_image = img.resize(size).convert('RGB')
return gray_image
# 计算直方图
def hist_similar(lh, rh):
assert len(lh) == len(rh)
hist = sum(1 - (0 if l == r else float(abs(l-r))/max(l,r))for l, r in zip(lh, rh))/len(lh)
return hist
# 计算相似度
def calc_similar(li, ri):
calc_sim = hist_similar(li.histogram(), ri.histogram())
return calc_sim
if __name__ == '__main__':
image1 = Image.open('../dataset/100002.png')
image1 = make_regalur_image(image1)
image2 = Image.open('../dataset/100001.png')
image2 = make_regalur_image(image2)
print("图片间的相似度为",calc_similar(image1, image2))
运行结果:
直方图过于简单,只能捕捉颜色信息的相似性,捕捉不到更多的信息。只要颜色分布相似,就会判定二者相似度较高。
所以本菜鸟利用之前做验证码时的用灰度图和彩色图进行了对比:
运行的结果为:
结果为0.54,有点差强人意了。。
4.还有通过感知哈希算法(或者也称为图片指纹的形式的,嗯,我是这样子理解的)
具体的代码看之前的文章:
。。。。占时就这些了,还有的遇到了在更新吧