一種基於顏色統計和特徵指紋的圖片相似度計算方法

一種基於顏色指紋和內容信息的圖像相似度計算方法

1.摘要

圖片相似度有很多實際應用,比如谷歌搜圖、淘寶識物購買,現在很多類似應用已經使用神經網絡訓練實現,但是本文僅僅從圖像處理角度出發,根據圖像內容特徵信息實現圖片相似度計算。如題描述,我們將從顏色和內容信息兩方面進行。

2.實現

本節內容將從原理、代碼實現並結合應用效果介紹感知哈希算法和顏色分量統計算法

from math import sqrt
import numpy as np
import pandas as pd
import itertools

2.1.感知哈希算法

  1. 原理描述:結合離散餘弦變換,將灰度圖片所包含的特徵生成一組指紋(哈希值),計算圖片相似度即計算圖片指紋的相似度。
  2. 關於離散餘弦變換:灰度圖是二維矩陣,由不同頻率的成分組成。一般來說亮度變化小的區域是低頻成分,它描述大範圍的信息。而亮度變化劇烈的區域(比如物體的邊緣)就是高頻的成分,它描述具體的細節。由於大多數自然信號的能量都集中在餘弦變換後的低頻部分,可以捨棄信息含量更少的高頻部分而提高計算效率,具體使用方法是離散餘弦變換(DCT)。
  3. 具體步驟:

    • 簡化色彩:BGR2GRAY;
    • 計算DCT:計算圖片的DCT變換,得到32*32的DCT係數矩陣;
    • 縮小DCT:保留左上角的8*8的矩陣(最低頻率);
    • 計算平均值:計算DCT的均值;
    • 計算hash值:根據8*8的DCT矩陣,設置0或1的64位的hash值,大於等於DCT均值的設爲”1”,小於DCT均值的設爲“0”。將得到的二維數組拉伸成一維,構成了一個長度爲64位的向量,這就是這張圖片的指紋;
    • 計算兩張圖片指紋,使用漢明距離計算相似度。

    結果並不能告訴我們真實性的低頻率,只能粗略地告訴我們較於平均值頻率的相對比例。只要圖片的整體結構保持不變,hash結果值就不變。能夠避免伽馬校正或顏色直方圖被調整帶來的影響。

#均值哈希算法
def aHash(img):
    img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    s=0
    hash_str=''
    for i in range(8):
        for j in range(8):
            s=s+gray[i,j]
    avg=s/64
    for i in range(8):
        for j in range(8):
            if  gray[i,j]>avg:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'            
    return hash_str

#差值感知算法
def dHash(img):
    img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    hash_str=''
    for i in range(8):
        for j in range(8):
            if   gray[i,j]>gray[i,j+1]:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'
    return hash_str

# 感知哈希算法
def pHash(img):
    img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    img=cv2.resize(img,(32,32),interpolation=cv2.INTER_CUBIC)

    _ = np.array(img,np.float32)
    __ = cv2.dct(_)
    #取低頻區域
    img_dct = __[:8,:8]

    #把二維list變成一維list
    img_list = []
    for i in img_dct.tolist():
        for j in i:
            img_list.append(j)

    #計算均值並哈希轉換
    avg = sum(img_list)*1./len(img_list)
    hash_str = ''
    for i in img_list:
        if i > avg:
            hash_str=hash_str+'1'
        else:
            hash_str=hash_str+'0' 
    return hash_str

#Hash值對比
def compCode(code1,code2,length):
    num = 0
    for index in range(0,len(code1)):
        if code1[index] != code2[index]:
            num+=1
    return (1-(num / length))
# 感知哈希算法使用:
compCode(pHash(img_a),pHash(img_b),64)

2.2.顏色分量統計算法

  1. 原理描述:每張圖片都有自己特定的顏色分佈。將1600多萬種顏色分爲N個顏色區間,對每張圖片,統計其每個顏色區間的像素個數,獲得一組長度爲N的向量。計算圖片相似度即計算向量之間的相似度。
  2. 具體步驟:
    • 規整尺寸:resize(1024*1024*3);
    • 顏色分區:將RGB每個顏色通道均分爲m個數值區間,共得到m的三次方(記爲N)個顏色區間;
    • 統計每個顏色區間內的像素個數,獲得向量;
    • 計算向量之間的相似度;
# 代碼不貼了 有興趣私聊

3.驗證效果

感知哈希算法中,經過了餘弦離散變化,圖像內部信息的大都集中在低頻區域,將計算重點縮小至該區域,但是僅僅對灰度圖研究,丟失了顏色信息,而顏色分量統計算法從顏色角度出發,統計了整張圖片的顏色分佈情況,兩種方法結合保證了相似度的準確性。

以下風景圖(450*800*3)爲例,記爲img
Original

將原圖上下平均拆分
img_up:225*800
img_dn:225*800
將原圖左右比例拆分
img_left:450*600
img_right:450*600

感知哈希算法效果如下:
這裏寫圖片描述

綜合兩種算法一起的效果如下:
這裏寫圖片描述

參考:https://blog.csdn.net/haofan_/article/details/77097473?locationNum=7&fps=1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章