訂閱
糾錯
加入自媒體

建立重復(fù)圖像查找系統(tǒng)

是否要識別重復(fù)或接近重復(fù)的圖像?或者計算數(shù)據(jù)集中每個圖像的副本數(shù)?

如果是,那么這篇文章是給你的。

本文的目標有五個方面:

1. 理解重復(fù)圖像查找器和基于內(nèi)容的圖像檢索系統(tǒng)之間的區(qū)別

2. 演練比較相似圖像的5種不同方法的概念

3. 學習python中的每個方法實現(xiàn)

4. 確定圖像變換對所述算法整體性能的靈敏度

5. 為在速度和準確性方面選擇適合你應(yīng)用的最佳方法的選擇過程鋪路(包括實驗)

基本架構(gòu)

首先,需要定義一個重要的術(shù)語。查詢圖像是用戶輸入以獲取信息的圖像。系統(tǒng)在數(shù)據(jù)集中搜索相似圖像,計算圖像之間的距離。圖1說明了這些步驟。

圖1-重復(fù)圖像查找系統(tǒng)的基本結(jié)構(gòu)

在第3節(jié)中,我們將研究這個相似性塊,并探索實現(xiàn)此功能的最常見方法。

重復(fù)圖像查找器與基于內(nèi)容的圖像檢索系統(tǒng)

兩種系統(tǒng)之間的主要區(qū)別在于,重復(fù)圖像查找器僅檢測相同和近似相同的圖像(圖2)。另一方面,基于內(nèi)容的圖像檢索(CBIR)系統(tǒng)搜索相似的感興趣區(qū)域,并顯示與這些區(qū)域最相似的圖像(圖像3)。

圖2:重復(fù)圖像查找系統(tǒng)的輸入和輸出示例:

圖3-基于內(nèi)容的圖像檢索系統(tǒng)的詳細信息示例

請注意,基于內(nèi)容的圖像檢索系統(tǒng)如何識別蘋果并輸出不同場景的圖像。

比較相似圖像的五種常用方法

本文將考察五種主要方法:

· 歐幾里得距離

· 結(jié)構(gòu)相似性度量(SSIM)

· 圖像哈希

· 相似度

· 特征的相似性(使用CNN)

1、歐幾里得距離

轉(zhuǎn)到第一種方法,如圖4所示,歐幾里得距離是平面中2個數(shù)據(jù)點之間的直線距離[8]。它也稱為L2范數(shù)距離度量。

圖4-歐幾里得距離

我們可以將圖像表示為向量。向量是具有起點和終點的量[4]。這兩個點構(gòu)成向量的兩個特征:大小和方向。

在向量空間中,假設(shè)我們有兩張圖片來比較x=[x1,x2,x3]和y=[y1,y2,y3]。雖然圖5顯示了一般公式[8],但圖6顯示了使用示例。

圖5-歐幾里得距離的一般公式

圖6-應(yīng)用歐幾里得距離公式的示例

該方法公式簡單明了。

在python中,實現(xiàn)非常簡單:

· 實現(xiàn)1:使用Scipy庫

import numpy as np

from scipy.spatial import distance

from PIL import Image

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images have to be of equal size

# we need to flatten the image to a 1D vector

value = distance.euclidean(np.a(chǎn)rray(image1).flatten(), np.a(chǎn)rray(image2).flatten())

實現(xiàn)2:使用NumPy的linalg

import numpy as np

from PIL import Image


image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images have to be of equal size


# linalg.norm

value = np.linalg.norm(np.a(chǎn)rray(image1) - np.a(chǎn)rray(image2))

2、結(jié)構(gòu)相似性度量(SSIM)

論文《Image Quality Assessment: From Error Visibility to Structural Similarity》[1]于2004年介紹了SSIM。它計算兩個給定圖像之間的相似性,得出一個介于0和1之間的值。

除了尋找重復(fù),它的許多應(yīng)用之一是測量壓縮圖像如何影響其質(zhì)量[2]。此外,它還估計了數(shù)據(jù)傳輸損耗如何嚴重降低質(zhì)量[2]。

作者認為,影響該指數(shù)的主要三個因素是亮度、對比度和結(jié)構(gòu)[3]。因此,如果其中一個因素發(fā)生變化,度量也會發(fā)生變化。

實現(xiàn)如下:

from SSIM_PIL import compare_ssim

from PIL import Image

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images have to be of equal size

value = compare_ssim(image1, image2, GPU=False) # a value of 1 indicates strong similarity

3、圖像哈希

計算兩幅圖像之間相似性的另一種方法是圖像哈希(也稱為數(shù)字指紋)。它是為每個圖像分配唯一哈希值的過程。然而,該方法對相同的值產(chǎn)生相同的結(jié)果。平均哈希是眾多哈希類型之一。其工作方式如下[6]。此外,請參閱圖7以了解說明。

1. 減小圖像大小(例如:8x8)

2. 將其轉(zhuǎn)換為灰度

3. 取均值

4. 將每個像素與平均值進行比較。如果像素高于平均值,則為其指定值1,否則為0

5. 構(gòu)造哈希

圖7-平均哈希步驟

生成的64位整數(shù)可能如下所示:

1011111101100001110001110000111101101111100001110000001100001001

我們可以用不同的方式表示圖像。從左上角開始列出0位和1(如上例所示)、左右角等等[6]。

最重要的是,如果我們改變縱橫比,增加或減少亮度或?qū)Ρ榷,甚至改變圖像的顏色,其哈希值將是相同的[7],這使其成為比較同一圖像的最佳方法之一。

比較兩幅圖像的步驟如下[7]:

1. 構(gòu)造每個圖像的哈希(通過遵循上述5個步驟)

2. 計算漢明距離。零距離表示相同的圖像。(下面的代碼塊更好地解釋了這一點)

import imagehash

from PIL import Image

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images DO NOT have to be of equal size

# Construct the hash

hash1 = imagehash.a(chǎn)verage_hash(image1)

hash2 = imagehash.a(chǎn)verage_hash(image2)

# Calculate the hamming distance

value = hash1-h(huán)ash2

4、余弦相似性

余弦相似性是一種計算兩個向量(可以是圖像)相似性的方法,方法是取點積并將其除以每個向量的幅值[9],如下圖8所示。

圖8-余弦相似方程

隨著兩個向量之間的角度變小,相似性變大[9]。如圖9所示,向量C和B與A和B具有高度相似性,因為它們的角度明顯較小。

圖9-余弦相似性說明

以下是使用torch計算兩個PIL圖像的度量的代碼。

from torch import nn

from PIL import Image

from torchvision import transforms

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image)

# Note: images have to be of equal size

# Transform the images to tensors then flatten them to 1D tensors

image1_tensor = transforms.ToTensor()(image1).reshape(1, -1).squeeze()

image2_tensor = transforms.ToTensor()(image2).reshape(1, -1).squeeze()

cos = nn.CosineSimilarity(dim=0) # dim=0 -> dimension where cosine similarity is computed

value = float(cos(image1_tensor, image2_tensor)) # a value of 1 indicates strong similarity

5.特征的相似性(使用CNN)

最后一種比較圖像的方法是計算特征的相似性。眾所周知,卷積神經(jīng)網(wǎng)絡(luò)CNN可以選擇圖像的模式并對其進行感知。卷積層是具有檢測模式的濾波器。圖像中的不同圖案可以是邊緣、形狀或紋理。這些模式稱為特征。

我們可以從CNN的卷積層中提取這些特征。

圖10清楚地說明了一個示例架構(gòu)。通常,我們指定網(wǎng)絡(luò)的最后一個卷積層用于特征提取。

圖10-一個簡單的CNN架構(gòu)

最先進的CNN架構(gòu)之一是高效網(wǎng)(EfficientNet)。這是一種縮放方法,使用復(fù)合系數(shù)均勻縮放所有維度:深度/寬度/分辨率。我不會深入探討它,因為它超出了本文的范圍。然而,我將在以下幾節(jié)中使用它。

通常,數(shù)據(jù)科學界在基于內(nèi)容的圖像檢索系統(tǒng)中廣泛使用特征的相似性。實驗部分將解釋原因。

5.1. EfficientNet-b0和歐幾里得距離

在從EfficientNet中提取特征后,我應(yīng)用歐幾里得距離測量查詢和數(shù)據(jù)集圖像的特征之間的相似性,以找到最相似的特征。

from efficientnet_pytorch import EfficientNet

import numpy as np

from PIL import Image

from torchvision import transforms

# Load the model

model = EfficientNet.from_pretrained('efficientnet-b0')

model.eval()

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images have to be of equal size
         

# Convert the images to tensors

image1_tensor = transforms.ToTensor()(image1)

image2_tensor = transforms.ToTensor()(image2)
     

# Add a fourth dimension for the batch and extract the features

features1 = model.extract_features(image1_tensor.unsqueeze(0))

features2 = model.extract_features(image2_tensor.unsqueeze(0))

# Calculate the Euclidean distance of the features

value = round(np.linalg.norm(np.a(chǎn)rray(features1.detach()) -
                            np.a(chǎn)rray(features2.detach())), 4)

5.2. EfficientNet-b0和余弦相似性

計算特征的余弦相似性與前一個非常相似。然而,應(yīng)用余弦相似性代替歐幾里得距離。

from efficientnet_pytorch import EfficientNet

from PIL import Image

from torchvision import transforms

from torch import nn

# Load the model

model = EfficientNet.from_pretrained('efficientnet-b0')

model.eval()

image1 = Image.open("path/to/image")

image2 = Image.open("path/to/image")

# Note: images have to be of equal size

# Transform the images to tensors

image1_tensor = transforms.ToTensor()(image1)

image2_tensor = transforms.ToTensor()(image2)

# Add a fourth dimension representing the batch number and compute the features

features1 = model.extract_features(image1_tensor.unsqueeze(0))

features2 = model.extract_features(image2_tensor.unsqueeze(0))

# flatten the features and apply cosine similarity

cos = nn.CosineSimilarity(dim=0)

value = round(float(cos(features1.reshape(1, -1).squeeze(),
                       features2.reshape(1, -1).squeeze())),4)

在本節(jié)結(jié)束之前,如果得到的相似性為250、0.04或10809,該怎么辦?使一對圖像相似的數(shù)字是多少?答案如下:你必須根據(jù)對所選數(shù)據(jù)集的研究或特殊測試來定義此閾值。

數(shù)據(jù)集集合

在整個實驗過程中,使用了兩個不同的數(shù)據(jù)集進行評估:

· Fruits360數(shù)據(jù)集的一部分(96幅多尺寸圖像)

· 收集并稱之為SFBench的數(shù)據(jù)集由40張圖片組成(3024x4032像素)

指定了第一個數(shù)據(jù)集來評估重復(fù)/近似重復(fù)圖像查找器,因為它由每個類別360度拍攝的不同水果的圖像組成。這些框架略有不同;圖12顯示了棕色劃痕是如何順時針移動的。

圖11:Fruits360數(shù)據(jù)集的樣本

圖12:Fruits360數(shù)據(jù)集三幀之間的差異

由于所有圖像都是相鄰幀,因此在此數(shù)據(jù)集上的測試將為我們提供關(guān)于重復(fù)圖像查找器性能的良好反饋。這意味著,對于每個獨特的類別,這些圖片主要是相似的。

其次,SFBench是一個收集了40幅圖像的數(shù)據(jù)集,用于評估基于內(nèi)容的圖像檢索(CBIR)系統(tǒng)。

請注意,本文的目標不是構(gòu)建或評估CBIR系統(tǒng)。我們使用該數(shù)據(jù)集僅測試圖像變換(如3D投影和旋轉(zhuǎn))如何影響方法的性能。

數(shù)據(jù)集的一些示例圖像如下圖13所示。與第一個數(shù)據(jù)集一樣,它由每個場景4個圖像組成。

圖13:SFBench數(shù)據(jù)集示例

實驗

以以下方式使用兩個數(shù)據(jù)集測試了每種方法:

實驗1:速度和準確性

實驗2:圖像轉(zhuǎn)換的彈性

實驗3:  Scipy distance.euclidean vs. Numpy linalg.norm 速度

注意:在所有測試中都使用了2019年的MacBook Pro CPU。此外,你可以在Github存儲庫中找到所有測試。

實驗1:速度和準確性

該測試為重復(fù)圖像查找系統(tǒng)提出了速度和精度方面的最佳方法。以下步驟如下:

· 讀取Fruits360數(shù)據(jù)集的圖像。

· 將其轉(zhuǎn)換為RGB

· 將圖像大小調(diào)整為固定大小

· 使用5種方法

· 獲取參考圖像的3個最相似圖像。

· 計算該方法用于比較一對圖像的平均時間(秒)

· 計算準確率(對于每個參考圖像,如果檢測到3個重復(fù)/近重復(fù),準確率為100%)

結(jié)果(如表1所示)清楚地表明,余弦相似性占主導地位,CNN的運行時間比余弦相似性慢約250倍,但是準確率卻比較接近。此外,如果速度是一個很大的因素,那么圖像哈希是一個很好的選擇。

表1-實驗1結(jié)果

實驗2:圖像轉(zhuǎn)換的彈性

該測試遵循與實驗1相同的步驟。唯一的區(qū)別是使用的數(shù)據(jù)集和大小調(diào)整因子;我使用了SFBench,注意到圖像重復(fù)查找器的目的不是檢測和識別相似的變換圖像。我只是評估這些方法在CBIR系統(tǒng)中的潛在使用的彈性。

從邏輯上講,當CNN在其層內(nèi)保存空間信息時,特征相似性方法表現(xiàn)最好。表2總結(jié)了以下結(jié)果:

表2-實驗2結(jié)果

實驗3:Scipy distance.euclidean vs. Numpy linalg.norm 速度

最后一個實驗通過重復(fù)相同的操作約2300次來考察Scipy和Numpy實現(xiàn)的比較。此測試是本文的額外步驟,不會影響重復(fù)圖像/近復(fù)制查找系統(tǒng)的功能。

結(jié)果表明,它們的性能相似(表3)。

表3-實驗3結(jié)果

結(jié)論

總之,我們學習了歐幾里得距離、SSIM、圖像哈希、余弦相似性和特征相似性的概念和Python代碼。此外,我們還確定了圖像變換對這些算法性能的敏感性。最后,通過實驗,我們根據(jù)速度和準確性的要求,得出了最佳的方法。

你可以在Github存儲庫中找到所有數(shù)據(jù)集、實驗和結(jié)果。此外,只要對每個數(shù)據(jù)集遵循相同的命名約定,就可以測試你選擇的數(shù)據(jù)集。

參考引用

[1] Wang, et al, Image Quality Assessment: From Error Visibility to Structural Similarity, 2004

[2] Imatest LLC, SSIM: Structural Similarity Index, v.22.1

[3] Datta, All about Structural Similarity Index (SSIM): Theory + Code in PyTorch, 2020

[4] Mathematics LibreTexts, A Further Applications of Trigonometry: Vectors. 2021

[5] Nagella, Cosine Similarity Vs Euclidean Distance, 2019

[6] The Content Blockchain Project, Testing Different Image Hash Functions, 2019

[7] Krawetz, The Hacker Factor Blog, Looks Like It, 2011

[8] Gohrani, Different Types of Distance Metrics used in Machine Learning, 2019

[9] Clay, How to calculate Cosine Similarity (With code), 2020

       原文標題 : 建立重復(fù)圖像查找系統(tǒng)

聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號