2012-06-19 251 views
1

我需要計算圖像的感知散列,並且應該在不使用任何外部庫的情況下執行散列。感知(或平均)圖像散列

我嘗試使用pHash(http://phash.org/),但我無法編譯它的iOS(5),我還沒有找到一個真正的教程如何做到這一點。

+0

請注意pHash是根據GPLv3許可的,這意味着衍生作品只能在相同許可條款下發布! – Anne

+0

這不會是一個問題(代碼將在相同的許可證下發布。問題是我無法爲iOS(arm)編譯pHash。 – tagyro

回答

0

其中一個(依賴庫的)解決方案是使用添加到版本爲6.8.8.3的ImageMagick的pHashing功能,該版本具有iOS binaries available。使用示例記錄在here

這裏還有一個簡單的參考函數(在C#中)用於生成您自己的可比較圖像平均散列,可在this blog上找到。

public static ulong AverageHash(System.Drawing.Image theImage) 
// Calculate a hash of an image based on visual characteristics. 
// Described at http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html 
{ 
    // Squeeze the image down to an 8x8 image. 
    // Chant the ancient incantations to create the correct data structures. 
    Bitmap squeezedImage = new Bitmap(8, 8, PixelFormat.Format32bppRgb); 
    Graphics drawingArea = Graphics.FromImage(squeezedImage); 
     drawingArea.CompositingQuality = CompositingQuality.HighQuality; 
     drawingArea.InterpolationMode = InterpolationMode.HighQualityBilinear; 
     drawingArea.SmoothingMode = SmoothingMode.HighQuality; 
     drawingArea.DrawImage(theImage, 0, 0, 8, 8); 

    byte[] grayScaleImage = new byte[64]; 

    uint averageValue = 0; 
    ulong finalHash = 0; 

    // Reduce to 8-bit grayscale and calculate the average pixel value. 
    for(int y = 0; y < 8; y++) 
    { 
     for(int x = 0; x < 8; x++) 
     { 
      Color pixelColour = squeezedImage.GetPixel(x,y); 
      uint grayTone = ((uint)((pixelColour.R * 0.3) + (pixelColour.G * 0.59) + (pixelColour.B * 0.11))); 

      grayScaleImage[x + y*8] = (byte)grayTone; 
      averageValue += grayTone; 
     } 
    } 
    averageValue /= 64; 

    // Return 1-bits when the tone is equal to or above the average, 
    // and 0-bits when it's below the average. 
    for(int k = 0; k < 64; k++) 
    { 
     if(grayScaleImage[k] >= averageValue) 
     { 
      finalHash |= (1UL << (63-k)); 
     } 
    } 

    return finalHash; 
}