• (转)感知哈希算法


    /// <summary>
    /// 感知哈希算法
    /// </summary>
    public class ImageComparer
    {
    /// <summary>
    /// 获取图片的Hashcode
    /// </summary>
    /// <param name="imageName"></param>
    /// <returns></returns>
    public static string GetImageHashCode(string imageName)
    {
    int width = 8;
    int height = 8;

    // 第一步
    // 将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,
    // 只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
    Bitmap bmp = new Bitmap(Thumb(imageName));
    int[] pixels = new int[width * height];

    // 第二步
    // 将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。
    for (int i = 0; i < width; i++)
    {
    for (int j = 0; j < height; j++)
    {
    Color color = bmp.GetPixel(i, j);
    pixels[i * height + j] = RGBToGray(color.ToArgb());
    }
    }

    // 第三步
    // 计算所有64个像素的灰度平均值。
    int avgPixel = Average(pixels);

    // 第四步
    // 将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
    int[] comps = new int[width * height];
    for (int i = 0; i < comps.Length; i++)
    {
    if (pixels[i] >= avgPixel)
    {
    comps[i] = 1;
    }
    else
    {
    comps[i] = 0;
    }
    }

    // 第五步
    // 将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。
    StringBuilder hashCode = new StringBuilder();
    for (int i = 0; i < comps.Length; i += 4)
    {
    int result = comps[i] * (int)Math.Pow(2, 3) + comps[i + 1] * (int)Math.Pow(2, 2) + comps[i + 2] * (int)Math.Pow(2, 1) + comps[i + 2];
    hashCode.Append(BinaryToHex(result));
    }
    bmp.Dispose();
    return hashCode.ToString();
    }

    /// <summary>
    /// 计算"汉明距离"(Hamming distance)。
    /// 如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。
    /// </summary>
    /// <param name="sourceHashCode"></param>
    /// <param name="hashCode"></param>
    /// <returns></returns>
    public static int HammingDistance(String sourceHashCode, String hashCode)
    {
    int difference = 0;
    int len = sourceHashCode.Length;

    for (int i = 0; i < len; i++)
    {
    if (sourceHashCode[i] != hashCode[i])
    {
    difference++;
    }
    }
    return difference;
    }

    /// <summary>
    /// 缩放图片 www.2cto.com
    /// </summary>
    /// <param name="imageName"></param>
    /// <returns></returns>
    private static Image Thumb(string imageName)
    {
    return Image.FromFile(imageName).GetThumbnailImage(8, 8, () => { return false; }, IntPtr.Zero);
    }

    /// <summary>
    /// 转为64级灰度
    /// </summary>
    /// <param name="pixels"></param>
    /// <returns></returns>
    private static int RGBToGray(int pixels)
    {
    int _red = (pixels >> 16) & 0xFF;
    int _green = (pixels >> 8) & 0xFF;
    int _blue = (pixels) & 0xFF;
    return (int)(0.3 * _red + 0.59 * _green + 0.11 * _blue);
    }

    /// <summary>
    /// 计算平均值
    /// </summary>
    /// <param name="pixels"></param>
    /// <returns></returns>
    private static int Average(int[] pixels)
    {
    float m = 0;
    for (int i = 0; i < pixels.Length; ++i)
    {
    m += pixels[i];
    }
    m = m / pixels.Length;
    return (int)m;
    }

    private static char BinaryToHex(int binary)
    {
    char ch = ' ';
    switch (binary)
    {
    case 0:
    ch = '0';
    break;
    case 1:
    ch = '1';
    break;
    case 2:
    ch = '2';
    break;
    case 3:
    ch = '3';
    break;
    case 4:
    ch = '4';
    break;
    case 5:
    ch = '5';
    break;
    case 6:
    ch = '6';
    break;
    case 7:
    ch = '7';
    break;
    case 8:
    ch = '8';
    break;
    case 9:
    ch = '9';
    break;
    case 10:
    ch = 'a';
    break;
    case 11:
    ch = 'b';
    break;
    case 12:
    ch = 'c';
    break;
    case 13:
    ch = 'd';
    break;
    case 14:
    ch = 'e';
    break;
    case 15:
    ch = 'f';
    break;
    default:
    ch = ' ';
    break;
    }
    return ch;
    }
    }

  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/xiaoni/p/3083295.html
Copyright © 2020-2023  润新知