2012-06-19 187 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; 
}