谷歌百度以图搜图 "感知哈希算法" C#简单实现

本文涉及的产品
图像搜索,任选一个服务类型 1个月
简介: /// /// 感知哈希算法 /// public class ImageComparer { /// /// 获取图片的Hashcode /// /// /// public static string GetImageHashCode(string imageName) { int width = 8; int height = 8; // 第一步 // 将图片缩小到8x8的尺寸,总共64个像素。

 

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

  

 

目录
相关文章
|
2月前
|
存储 监控 算法
电脑监控管理中的 C# 哈希表进程资源索引算法
哈希表凭借O(1)查询效率、动态增删性能及低内存开销,适配电脑监控系统对进程资源数据的实时索引需求。通过定制哈希函数与链地址法冲突解决,实现高效进程状态追踪与异常预警。
174 10
|
7月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
214 8
|
8月前
|
机器学习/深度学习 监控 算法
员工上网行为监控软件中基于滑动窗口的C#流量统计算法解析​
在数字化办公环境中,员工上网行为监控软件需要高效处理海量网络请求数据,同时实时识别异常行为(如高频访问非工作网站)。传统的时间序列统计方法因计算复杂度过高,难以满足低延迟需求。本文将介绍一种基于滑动窗口的C#统计算法,通过动态时间窗口管理,实现高效的行为模式分析与流量计数。
229 2
|
5月前
|
机器学习/深度学习 搜索推荐 API
京东拍立淘API-以图搜图中的图像搜索算法
京东拍立淘API基于深度学习,利用CNN提取图像特征,结合余弦相似度实现商品精准匹配。支持图片搜索、类目限定与相似度筛选,日均处理千万级请求,广泛应用于移动购物与社交带货场景。
|
6月前
|
监控 算法 数据处理
内网实时监控中的 C# 算法探索:环形缓冲区在实时数据处理中的关键作用
本文探讨了环形缓冲区在内网实时监控中的应用,结合C#实现方案,分析其原理与优势。作为固定长度的循环队列,环形缓冲区通过FIFO机制高效处理高速数据流,具备O(1)时间复杂度的读写操作,降低延迟与内存开销。文章从设计逻辑、代码示例到实际适配效果展开讨论,并展望其与AI结合的潜力,为开发者提供参考。
283 2
|
6月前
|
监控 算法 安全
公司电脑监控软件关键技术探析:C# 环形缓冲区算法的理论与实践
环形缓冲区(Ring Buffer)是企业信息安全管理中电脑监控系统设计的核心数据结构,适用于高并发、高速率与短时有效的多源异构数据处理场景。其通过固定大小的连续内存空间实现闭环存储,具备内存优化、操作高效、数据时效管理和并发支持等优势。文章以C#语言为例,展示了线程安全的环形缓冲区实现,并结合URL访问记录监控应用场景,分析了其在流量削峰、关键数据保护和高性能处理中的适配性。该结构在日志捕获和事件缓冲中表现出色,对提升监控系统效能具有重要价值。
177 1
|
7月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
217 2
|
7月前
|
存储 监控 算法
局域网上网记录监控的 C# 基数树算法高效检索方案研究
在企业网络管理与信息安全领域,局域网上网记录监控是维护网络安全、规范网络行为的关键举措。随着企业网络数据量呈指数级增长,如何高效存储和检索上网记录数据成为亟待解决的核心问题。基数树(Trie 树)作为一种独特的数据结构,凭借其在字符串处理方面的卓越性能,为局域网上网记录监控提供了创新的解决方案。本文将深入剖析基数树算法的原理,并通过 C# 语言实现的代码示例,阐述其在局域网上网记录监控场景中的具体应用。
177 7
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
241 3
|
10月前
|
机器学习/深度学习 人工智能 运维
[ICDE2024]多正常模式感知的频域异常检测算法MACE
[ICDE2024]多正常模式感知的频域异常检测算法MACE
163 0

热门文章

最新文章