程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 谷歌百度以圖搜圖 "感知哈希算法" C#簡單實現

谷歌百度以圖搜圖 "感知哈希算法" C#簡單實現

編輯:C#入門知識

/// <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; 
        } 
    } 

 


摘自 Query!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved