【python + PIL】圖像相似度檢測


這個仿佛差不多是為了趕作業然后一開始寫了個直方圖匹配后來找了兩種最簡單的能夠加進去的方法……

Fundimental

在這里簡單的實現了直方圖匹配和圖像感知的哈希算法。
采用的python庫為PIL。

直方圖匹配

基本公式為

Sim(G,S)=1Ni=1N(1|gisi|Max(gi,si))

對RGB分別取出來然后進行匹配

其他

此外可以通過把圖像分塊進行匹配來減少由於位置信息不足帶來的誤差。這里在實現的時候把圖像分為了4*4,取每塊的匹配值,取平均。

(這里后面的reference里有一篇寫的更好orz但是我是寫不出這種風格的

感知哈希算法

這種算法據說是谷歌識圖等使用的方法,但是最后做出來仿佛在小規模的樣本中表現並不好。

Better ways

• Position and structure
• Better color spaces, Lab/HSV/Yuv …
• Texture features, Gabor filter bank
• Better similarity computing
• advanced machine learning methods

灰度匹配

灰度匹配的基本思想:以統計的觀點將圖像看成是二維信號,采用統計相關的方法尋找信號間的相關匹配。利用兩個信號的相關函數,評價它們的相似性以確定同名點。
常用方法比如直方圖匹配、ssim、圖像感知哈希算法

矩陣分解

圖像本身就是一個矩陣,可以依靠數學上矩陣分解的一些知識來獲取矩陣中一些代表這個矩陣元素值和分布的一些魯棒性特征來對圖像的相似度進行計算。
最常用的一般是SVD分解和NMF分解。

特征匹配

特征匹配是指通過分別提取兩個或多個圖像的特征(點、線、面等特征),對特征進行參數描述,然后運用所描述的參數來進行匹配的一種算法。
常用的特征提取與匹配方法有:統計方法、幾何法、模型法、信號處理法、邊界特征法、傅氏形狀描述法、幾何參數法、形狀不變矩法等。

Code

# -*- coding: utf-8 -*- 

# Birdy 17/11/27
import os
import PIL.Image as Image



def difference(hist1,hist2):
    sum1 = 0
    for i in range(len(hist1)):
       if (hist1[i] == hist2[i]):
          sum1 += 1
       else:
           sum1 += 1 - float(abs(hist1[i] - hist2[i]))/ max(hist1[i], hist2[i])
    return sum1/len(hist1)

def similary_calculate(path1 , path2 , mode):
    if(mode == 3):
        img1 = Image.open(path1).resize((8,8)).convert('1')  
        img2 = Image.open(path2).resize((8,8)).convert('1')
        hist1 = list(img1.getdata())
        hist2 = list(img2.getdata())
        return difference(hist1, hist2)

    # 預處理
    img1 = Image.open(path1).resize((256,256)).convert('RGB')  
    img2 = Image.open(path2).resize((256,256)).convert('RGB')
    if(mode == 1):
        return difference(img1.histogram(), img2.histogram())
    if(mode == 2):
        sum = 0;
        for i in range(4):
            for j in range(4):
                hist1 = img1.crop((i*64, j*64, i*64+63, j*64+63)).copy().histogram()
                hist2 = img2.crop((i*64, j*64, i*64+63, j*64+63)).copy().histogram()
                sum += difference(hist1, hist2)
                #print difference(hist1, hist2)
        return sum/16
    return 0


def readfolder(folder,pic, mode):
# 不同的mode對應不同的類型
    file_list = []
    t = 0
    file_temp = ''
    for root,directors,files in os.walk(folder):
        for filename in files:
            filepath = os.path.join(root,filename)
            if (filepath.endswith(".png") or filepath.endswith(".jpg")):
               remember = similary_calculate(pic,filename,mode)
               print filename
               print remember
               if (remember > t) and remember!= 1:
                   file_temp = filename
                   t = remember

    return file_temp

if __name__ == '__main__': 
    print "###########直方圖的距離計算#############"
    print "相似度最高的圖是" + readfolder('E:\Code\similarity','t2.png',1)
    print "###########分塊直方圖的距離計算#############"
    print "相似度最高的圖是" + readfolder('E:\Code\similarity','t2.png',2)
    print "##############感知哈希算法###############"
    print "相似度最高的圖是" + readfolder('E:\Code\similarity','t2.png',3)

Reference

http://www.cnblogs.com/technology/archive/2012/07/12/2588022.html http://blog.csdn.net/gzlaiyonghao/article/details/2325027


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM