谷歌百度以图搜图 "感知哈希算法" C#简单实现
2014-05-14 15:41 狼人:-) 阅读(1669) 评论(1) 编辑 收藏 举报
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | /// <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> /// 缩放图片 /// </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; } } |
声明:此博有部分内容为转载,版权归原作者所有~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南