谷歌百度以图搜图 "感知哈希算法" 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 版权协议,转载请附上原 ...
随机推荐
- php面向对象(OOP)编程完整教程
http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/09/10/1823042.html
- ubuntu 执行make menuconfig ARCH=arm
1.ubuntu 执行make menuconfig ARCH=arm出错了!! *** Unable to find the ncurses libraries or the *** require ...
- Effective C++ Item 16 Use the same form in corresponding uses of new and delete
1. When you created an array and want to return the memory to system. You need to explicitly add [] ...
- unix:/tmp/php-cgi.sock
为什么要用unix:/tmp/php-cgi.sock,最主要的特征就是unix socket比tcp快,当网站流量大的时候,服务器的优化是分毫必争的. 当我们用php-fpm来管理我们的php启动时 ...
- jQuery中的$.each的用法
$.each(Array,function(i,value){ this; //this指向当前对象 i; //i表示当前下标 value; //value表示当前元素 })
- 硝烟中的Scrum和XP-我们如何实施Scrum 12)发布计划 13)组合XP
12 怎样制定发布计划, 处理固定价格的合同 一次只计划一个sprint的事情会显得提前量不足, 提前做计划是个好习惯; 尤其是签了固定价格的合同之后, 不得不预先计划好, 防止无法按期交付的危险情况 ...
- 点击button,button背景图片变化
1.设置背景渐变效果,在drawable目录下建buttonshape.xml文件, 内容为: <?xml version="1.0" encoding="utf- ...
- JS-cookie封装
智能社学习笔记 <script type="text/javascript"> /*****设置cookie*****/ function setCookie(name ...
- mysql in查询排序问题
SQL: select * from table where id IN (3,6,9,1,2,5,8,7); 这样的情况取出来后,其实,id还是按1,2,3,4,5,6,7,8,9,排序的,但如果我 ...
- hdu4976 A simple greedy problem.
A simple greedy problem. Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java ...