Python计算图片之间的相似度

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.还有通过感知哈希算法(或者也称为图片指纹的形式的,嗯,我是这样子理解的)

具体的代码看之前的文章:https://blog.csdn.net/weixin_39121325/article/details/84174876

。。。。占时就这些了,还有的遇到了在更新吧

猜你喜欢

转载自blog.csdn.net/weixin_39121325/article/details/84187453