Python計算圖片之間的相似度
阿新 • • 發佈:2018-12-06
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
。。。。佔時就這些了,還有的遇到了在更新吧