谷歌百度以图搜图 "感知哈希算法" 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>
/// 缩放图片
/// </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;
}
}
谷歌百度以图搜图 "感知哈希算法" C#简单实现的更多相关文章
- 使用 selenium 实现谷歌以图搜图爬虫
使用selenium实现谷歌以图搜图 实现思路 原理非常简单,就是利用selenium去操作浏览器,获取到想要的链接,然后进行图片的下载,和一般的爬虫无异. 用到的技术:multiprocessing ...
- 以图搜图(一):Python实现dHash算法(转)
近期研究了一下以图搜图这个炫酷的东西.百度和谷歌都有提供以图搜图的功能,有兴趣可以找一下.当然,不是很深入.深入的话,得运用到深度学习这货.Python深度学习当然不在话下. 这个功能最核心的东西就是 ...
- Google 以图搜图 - 相似图片搜索原理 - Java实现
前阵子在阮一峰的博客上看到了这篇<相似图片搜索原理>博客,就有一种冲动要将这些原理实现出来了. Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相 ...
- Google 以图搜图 - 相似图片搜索原理 - Java实现 (转)
前阵子在阮一峰的博客上看到了这篇<相似图片搜索原理>博客,就有一种冲动要将这些原理实现出来了. Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相 ...
- 以图搜图之模型篇: 基于 InceptionV3 的模型 finetune
在以图搜图的过程中,需要以来模型提取特征,通过特征之间的欧式距离来找到相似的图形. 本次我们主要讲诉以图搜图模型创建的方法. 图片预处理方法,看这里:https://keras.io/zh/prepr ...
- [No000007]搜索引擎以图搜图的原理
之前,Google把"相似图片搜索"正式放上了首页. 你可以用一张图片,搜索互联网上所有与它相似的图片.点击搜索框中照相机的图标. 一个对话框会出现. 你输入网片的网址,或者直接上 ...
- php 以图搜图
感知哈希算法count < =5 匹配最相似count > 10 两张不同的图片var_dump(ImageHash::run('1.jpg’, '2.jpg’)); <?php c ...
- 感知哈希算法的java实现
一.原理讲解 实现这种功能的关键技术叫做"感知哈希算法"(Perceptual Hash Algorithm), 意思是为图片生成一个指纹(字符串格式), 两张图片的指纹 ...
- 感知哈希算法——Python实现【转】
转自:https://blog.csdn.net/m_buddy/article/details/78887248 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
随机推荐
- haffman哈夫曼编码的实现
<span style="font-size:18px;">/* 1.在一棵二叉树中,我们定义从A节点到B节点所经过的分支序列为从A节点到B节点的路径: 定义从A节点到 ...
- 高级类特性----抽象类(abstract class)
抽象类(abstract class) 随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用.类的设计应该保证父类和子类能够共享特征.有时将一个父类设计得非常抽象,以至于它没有具 ...
- Effective C++ Item 13 Use object to manage resources
1. Always use object to manage resource! If you delete a pointer or release a handler manually by yo ...
- Python Scrapy 自动爬虫注意细节(2)
一.自动爬虫的创建,需要指定模版 如: scrapy genspider -t crawl stockinfo quote.eastmoney.com crawl : 爬虫模版 stockinfo : ...
- 【RF库Collections测试】Get From Dictionary
Name:Get From DictionarySource:Collections <test library>Arguments:[ dictionary | key ]Returns ...
- 新唐ARM9之NUC972学习历程之系统的搭建和BSP包的使用
说到嵌入式,我们首先想到的,就是它的复杂程度,LINUX,BSP,UBOOT,交叉编译,寄存器配置,等等一系列的问题,甚至有的时候我们对此一头雾水,很是头疼,不过我们今天要说的就是关于NUC972的一 ...
- Google's C++ coding style
v0.2 - Last updated November 8, 2013 源自 Google's C++ coding style rev. 3.274 目录 由 DocToc生成 头文件 ...
- Axis2开发实例
1.下载①axis2-1.7.4-bin.zip.②axis2-1.7.4-war.zip.③axis2-eclipse-service-plugin-1.7.4.zip.④axis2-eclipse ...
- OracleClient安装系统环境变量配置
1.变量名:TNS_ADMIN 值:E:\instantclient_11_2\NETWORK\ADMIN 2.变量名:NLS_LANG 值:SIMPLIFIED CHINESE_CHINA. ...
- 【linux】Crontab 定时任务 使用实例
1 使用putty 登录linux 服务器 2 输入以下命令.查看已有的定时任务 crontab -l 3 输入 以下命令,进入定时任务文件 crontab -e 4 键盘 选择 i 键 进行输 ...