2012-05-28 31 views
1

我從圖像中獲得25個樣本,獲取它們的平均rgb值並將它們保存爲5x5顏色陣列。這些是我的「簽名」。簽名中的值如下所示:比較數據庫中的圖像

Color signature[5][5]; 

-21233 -1 -323211 ... ... 
-123 -12323 ... 
... 

我可以從簽名的索引中獲取紅色,藍色和綠色值。我使用這些值來比較兩個圖像的簽名並獲得「差異」值。

signature[1][1].getBlue() = 123, Color[1][1].getRed() = 200 .. 

for (int x = 0; x < 5; x++) { 
     for (int y = 0;y < 5; y++) { 
      int r1 = signature[x][y].getRed(); 
      int g1 = signature[x][y].getGreen(); 
      int b1 = signature[x][y].getBlue(); 
      int r2 = signature2[x][y].getRed(); 
      int g2 = signature2[x][y].getGreen(); 
      int b2 = signature2[x][y].getBlue(); 
      double tempDiff = Math.sqrt((r1 - r2) * (r1 - r2) 
             + (g1 - g2) * (g1 - g2) 
             + (b1 - b2) * (b1 - b2)); 
      difference += tempDiff; 
     } 
} 

我還得到了圖像的第二個簽名,顯示了他們的邊緣找到版本的簽名。比較兩幅圖像,我將正常特徵差異與邊緣特徵差異相乘,得到最終差異值。

在比較兩幅圖像時,一切都很好。但是,我得到了大量的圖片,所以我救了我的簽名數據庫中像下面:

Table images: 
-COLUMN name-  -COLUMN signature-    -COLUMN edge signature- 
myimg.jpg |-12312 -132 -2 ... (25 of them) |-123 -1 -1234 -6921 .. (25 of them)| 

我只是在連接它們之間的空間簽名指標,並保存爲字符串。

這是我的問題:我需要找到一個圖像的相似之處。如果我從數據庫中選擇所有圖像,事情會變得非常緩慢,而且我內存不足。我可以從數據庫中選擇1000張圖像,比較並獲得下一張1000張圖像,但速度更慢。

我需要一種方法來比較查詢中的圖像簽名,我準備好更改我的表格的列,甚至準備好嘗試瘋狂的表格,其中有100列保存簽名的所有RGB值。我需要減少或散列簽名。它有什麼方法/方法,鏈接或庫你可以建議嗎?任何幫助,將不勝感激。

如果需要,我在NetBeans上使用Java,並使用MySQL。

+0

*「這是我的問題」*該段落或以下內容中沒有任何內容,這是一個問題。 –

+0

根據您的任務添加帶問號的句子。 –

回答

0

看到,我們需要150列後,有兩種方法走進心靈:

  1. 根據邏輯減少列數。
  2. 使用感知散列(散列,其中靠近散列值表示接近前散列值)

然而,難看和雜亂實施後,將碼工作得很好。我正在做的只是用SQL查詢在問題中進行計算,並從數據庫中獲取最相似的50張圖片。在得到結果之後,我整理了一些代碼,並且它工作的很好,很快。

所以我們沒有看到真正需要實施上述方法,因爲它們減少了發現相似性的成功,而且我們不需要更快。我們獲得最佳的50個結果,因此內存複雜性也不是問題。

對於那些在項目中的「Java部分」(或任何其他「代碼」部分)中遇到速度或內存問題的人,我強烈建議儘可能多地轉移到「數據庫部分」並獲得用查詢完成的事情。

0

哈希最有可能不會工作,因爲您正在尋找類似的,不相同的圖像。即使將相似的圖像映射到同一個鍵上,它也不起作用,因爲根據您對比函數的定義「類似」關係不是傳遞性的(A類似於B,B類似於C,但C可能不類似於A )。

我能想到的唯一的事情就是如你所說的那樣存儲在25 * 3列中。您可以編寫SQL語句以僅選擇可通過距離測試的可能的圖像(如果差值已經大於閾值,則將其過濾掉)。如果數據庫中的圖像不太相似,則此方法應該可以正常工作。但是,如果DB中的圖像彼此非常相似,則此方法很糟糕。

+0

謝謝你的回答。我需要單獨的紅色,綠色和藍色值進行比較,所以我需要25色x 3(r,g,b)x 2(顏色,邊緣)= 150列。這就是我現在正在執行的。順便說一下,這些圖像並不接近。是否有任何建議沒有給出太多的相似性成功並減少我的列數? –

+0

對不起。我沒有圖形處理的經驗,所以我無法幫你解決這個問題。 – nhahtdh

+0

該方法的工作速度足夠快150列,查詢和代碼變得非常難看,但它是成功的。所以沒有必要減少列數。再次感謝! –

0

您可以使用SQL來做到這一點。

如果你想找到所有重複,你可以使用這樣的(替代正確的字段名)

SELECT i.[name] FROM images i 
    INNER JOIN 
    (SELECT signature, edge_signature 
      FROM images 
      GROUP BY signature, edge_signature 
      HAVING COUNT(*) > 1) dups 
    on i.signature = dups.signature and i.edge_signature = dups.edge_signature; 

如果你想找到一個特定圖像的副本,創建簽名,並把他們在這個SQL

SELECT i.[name] 
    FROM images 
    WHERE signature = '$yourCalculatedSignaturehere' 
    and edge_signature = '$yourCalculatedEdgeSignaturehere'; 

這兩個查詢都可能返回多行(如果沒有重複,則返回0行)。

您可以使用signature, edge_signature, [name] (該索引可能使您的表使用的磁盤空間增加一倍,但應該顯着提高查詢性能)上的索引加速查詢。

+0

我想找到相似之處,而不是重複。 –