Google 图片搜索功能

在谷歌图片搜索中, 用户可以上传一张图片, 谷歌显示因特网中与此图片相同或者相似的图片.

比如我上传一张照片试试效果:

原理讲解

参考Neal Krawetz博士的这篇文章, 实现这种功能的关键技术叫做"感知哈希算法"(Perceptual Hash Algorithm), 意思是为图片生成一个指纹(字符串格式), 两张图片的指纹越相似, 说明两张图片就越相似. 但关键是如何根据图片计算出"指纹"呢? 下面用最简单的步骤来说明一下原理:

第一步 缩小图片尺寸

将图片缩小到8x8的尺寸, 总共64个像素. 这一步的作用是去除各种图片尺寸和图片比例的差异, 只保留结构、明暗等基本信息.

第二步 转为灰度图片

将缩小后的图片, 转为64级灰度图片.

第三步 计算灰度平均值

计算图片中所有像素的灰度平均值

第四步 比较像素的灰度

将每个像素的灰度与平均值进行比较, 如果大于或等于平均值记为1, 小于平均值记为0.

第五步 计算哈希值

将上一步的比较结果, 组合在一起, 就构成了一个64位的二进制整数, 这就是这张图片的指纹.

第六步 对比图片指纹

得到图片的指纹后, 就可以对比不同的图片的指纹, 计算出64位中有多少位是不一样的. 如果不相同的数据位数不超过5, 就说明两张图片很相似, 如果大于10, 说明它们是两张不同的图片.

代码实现 (C#版本)

下面我用C#代码根据上一节所阐述的步骤实现一下.

using System;
using System.IO;
using System.Drawing;namespace SimilarPhoto
{class SimilarPhoto{Image SourceImg;public SimilarPhoto(string filePath){SourceImg = Image.FromFile(filePath);}public SimilarPhoto(Stream stream){SourceImg = Image.FromStream(stream);}public String GetHash(){Image image = ReduceSize();Byte[] grayValues = ReduceColor(image);Byte average = CalcAverage(grayValues);String reslut = ComputeBits(grayValues, average);return reslut;}// Step 1 : Reduce size to 8*8private Image ReduceSize(int width = 8, int height = 8){Image image = SourceImg.GetThumbnailImage(width, height, () => { return false; }, IntPtr.Zero);return image;}// Step 2 : Reduce Colorprivate Byte[] ReduceColor(Image image){Bitmap bitMap = new Bitmap(image);Byte[] grayValues = new Byte[image.Width * image.Height];for(int x = 0; x<image.Width; x++)for (int y = 0; y < image.Height; y++){Color color = bitMap.GetPixel(x, y);byte grayValue = (byte)((color.R * 30 + color.G * 59 + color.B * 11) / 100);grayValues[x * image.Width + y] = grayValue;}return grayValues;}// Step 3 : Average the colorsprivate Byte CalcAverage(byte[] values){int sum = 0;for (int i = 0; i < values.Length; i++)sum += (int)values[i];return Convert.ToByte(sum / values.Length);}// Step 4 : Compute the bitsprivate String ComputeBits(byte[] values, byte averageValue){char[] result = new char[values.Length];for (int i = 0; i < values.Length; i++){if (values[i] < averageValue)result[i] = '0';elseresult[i] = '1';}return new String(result);}// Compare hashpublic static Int32 CalcSimilarDegree(string a, string b){if (a.Length != b.Length)throw new ArgumentException();int count = 0;for (int i = 0; i < a.Length; i++){if (a[i] != b[i])count++;}return count;}}
}

谷歌服务器里的图片数量是百亿级别的, 我电脑里的图片数量当然没法比, 但以前做过爬虫程序, 电脑里有40,000多人的头像照片, 就拿它们作为对比结果吧! 我计算出这些图片的"指纹", 放在一个txt文本中, 格式如下.

用ASP.NET写一个简单的页面, 允许用户上传一张图片, 后台计算出该图片的指纹, 并与txt文本中各图片的指纹对比, 整理出结果显示在页面中, 效果如下:

原文地址: http://www.cnblogs.com/technology/archive/2012/07/12/Perceptual-Hash-Algorithm.html

【转】感知哈希算法——找出相似的图片相关推荐

  1. 感知哈希算法——找出相似的图片

    参考Neal Krawetz博士的这篇文章, 实现这种功能的关键技术叫做"感知哈希算法"(Perceptual Hash Algorithm), 意思是为图片生成一个指纹(字符串格 ...

  2. 知哈希算法——找出相似的图片

    知哈希算法--找出相似的图片 感知哈希算法--找出相似的图片 - Create Chen - 博客园 知哈希算法--找出相似的图片 Google 图片搜索功能 在谷歌图片搜索中, 用户可以上传一张图片 ...

  3. 基于感知哈希算法的中药标本相似图片的搜索

    一 前言 笔者最近在开发中药标本相似图片的搜索,就是根据用户上传的图片,然后到中药标本库里找到相似的图片,从而帮助用户识别标本,获取标本信息.查阅了大量资料,看到了阮一峰的一篇文章,经过一个月的开发终 ...

  4. 感知哈希算法原理与实现

    今天忽然想做一个图像识别的APP,但是在两张图片相似度的问题上产生了问题,感知哈希算法并不能解决这个问题,只是我在试着解决问题的过程中学到的一点知识. 这里的关键技术叫做"感知哈希算法&qu ...

  5. 感知哈希算法(Perceptual hash algorithm)的OpenCV实现

    1.前言 目前"以图搜图"的引擎越来越多,可参考博文: http://blog.csdn.net/forthcriminson/article/details/8698175 此篇 ...

  6. 感知哈希算法(Perceptual hash algorithm) 以图搜图

    1.序 目前"以图搜图"的引擎越来越多,可参考博文: http://blog.csdn.net/forthcriminson/article/details/8698175 此篇博 ...

  7. 感知哈希算法(perceptual hash algorithm),

    感知哈希算法(perceptual hash algorithm),它的作用是对每张图像生成一个"指纹"(fingerprint)字符串,然后比较不同图像的指纹.结果越接近,就说明 ...

  8. 相似图片检测:感知哈希算法之aHash,dHash,pHash的Python实现

    相似图片检测:感知哈希算法之aHash,dHash,pHash的Python实现 原文:http://blog.sina.com.cn/s/blog_56fd58ab0102xpqf.html 感知哈 ...

  9. 相似图片检测:感知哈希算法之dHash的Python实现

    原文:https://blog.csdn.net/haluoluo211/article/details/52769325 相似图片检测:感知哈希算法之dHash的Python实现 某些情况下,我们需 ...

最新文章

  1. go标准库的学习-sync互斥
  2. shell脚本将本地docker镜像push到阿里云镜像仓库
  3. php 接口curl,php中接口强大之处php_curl
  4. MSDE 1433端口
  5. jq 按钮能触发submit吗
  6. c++ (QT)笔记
  7. Asp.Net Core 通过中间件防止图片盗链
  8. 热门专业学习之关于java的一些知识
  9. 用位运算实现求绝对值-有效避开if-else判断
  10. SpringSecurity Filter顺序
  11. 2020级C语言大作业 - 王国保卫战
  12. 从3D Studio Max导入物体 Importing Objects From 3D Studio Max
  13. 实战Swiper:利用Swiper制作手机新闻界面
  14. v-loading.fullscreen.lock初始化后第一次点击无效
  15. 计算机视觉(三)线性分类器
  16. 2023-2028年中国压铸机行业发展前景与投资趋势分析报告
  17. 《软技能-代码之外的生存指南》————第二篇 自我营销
  18. MSDN系列 14 -- NDIS Protocol Driver 入门
  19. csp-202203
  20. zzuli oj 1016:银行利率(java)

热门文章

  1. 关于GDPR的六大理解
  2. 【软件工程】第0次个人作业
  3. pip install whl
  4. 微信小程序一些知识点
  5. c3p0 数据库连接池
  6. SQL中变量的赋值-select
  7. 科普:WiFi是谁申请的专利?高通吗?错!
  8. poj1220:高精度进制转换模板题
  9. (转)Linux系统调用和库函数调用的区别
  10. Erlang里实现MapReduce