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

感知哈希算法——找出相似的图片 - Create Chen - 博客园

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

Google 图片搜索功能

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

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

原理讲解

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

第一步 缩小图片尺寸

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

第二步 转为灰度图片

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

第三步 计算灰度平均值

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

第四步 比较像素的灰度

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

第五步 计算哈希值

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

第六步 对比图片指纹

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

代码实现 (C#版本)

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

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
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*8
         private Image ReduceSize( int width = 8, int height = 8)
         {
             Image image = SourceImg.GetThumbnailImage(width, height, () => { return false ; }, IntPtr.Zero);
             return image;
         }
         // Step 2 : Reduce Color
         private 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 colors
         private 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 bits
         private 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' ;
                 else
                     result[i] = '1' ;
             }
             return new String(result);
         }
         // Compare hash
         public 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

posted on 2012-07-15 07:58  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/archive/2012/07/15/2592038.html

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

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

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

  2. 【转】感知哈希算法——找出相似的图片

    Google 图片搜索功能 在谷歌图片搜索中, 用户可以上传一张图片, 谷歌显示因特网中与此图片相同或者相似的图片. 比如我上传一张照片试试效果: 原理讲解 参考Neal Krawetz博士的这篇文章 ...

  3. 现在有一个整数数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数...

    现在有一个整数数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数. 方法1:Hash链表 方法2:使用两个变量A和B,其中A存储某个数组中的数,B用来计数.开始时将B初始化为0 ...

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

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

  5. c语言 判断互质,[经典算法] 找出某数以内与其互质的数

    起因:前几天做了一个这样的题目,感觉自己变成了一个智障,来写写算法: 相关定义: ①质数定义:没有除 '1' 以外的因子的数就是质数.如:1.3.5.7.11等等. ②互质定义:两个数之间除 '1'  ...

  6. Apriori算法找出频繁项集(python)

    目标 数据库有5个事务.设min_sup=60%,min_conf=80%. TID 购买的商品 T100 {M,O,N,K,E,Y} T200 {D,O,N,K,E,Y} T300 {M,A,K,E ...

  7. python 频繁项集_用FP-Growth算法找出销售数据中的频繁项集

    运行环境 python3.7.PyCharm 2018.2.4 (Community Edition) 数据来源 思路 从所给数据及其说明文档可以看出此数据集是从购物数据中收集而来的,每行数据都是一条 ...

  8. python出现的次数最多的元素_Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算...

    本文实例讲述了Python找出序列中出现次数最多的元素.分享给大家供大家参考,具体如下: 问题:找出一个元素序列中出现次数最多的元素是什么 解决方案:collections模块中的Counter类正是 ...

  9. 找出相似的图片--C#

    请先参考我写到java这章 原理讲解 参考Neal Krawetz博士的这篇文章, 实现这种功能的关键技术叫做"感知哈希算法"(Perceptual Hash Algorithm) ...

最新文章

  1. 1000行python代码_GitHub - kill1000/LearnPython: 以撸代码的形式学习Python
  2. oracle存储过程模板
  3. SAP- MM 委外加工(Subconctracting)流程
  4. Swift-Tips之重复字符串
  5. 斯坦福大学机器学习第一课“引言(Introduction)”
  6. 早起21天,奖你 1000元!
  7. 【UI/UX】GUI设计指南
  8. 机器学习速成课程 | 练习 | Google Development——编程练习:(TensorFlow) Hello World
  9. java搜索引擎创建索引_搜索引擎系列 ---lucene简介 创建索引和搜索初步
  10. python scapy sniffer停止抓包_如果没有收到数据包,如何告诉scapy sniff()停止?
  11. python如何释放对象_如何正确清理Python对象?
  12. 彻底理解connection timeout
  13. redis主从,哨兵模式配置
  14. 人工智能方向毕业设计_本科生的毕业论文如果选择人工智能相关方向,需要注意哪些问题...
  15. 如何使用一台电脑远程控制多台电脑
  16. 论文大致思路(不断更新)
  17. 加密的压缩包文件如何解压
  18. hdu——4379 ——The More The Better
  19. 华为Atlas200DK的环境部署与运行demo(人脸识别)
  20. fx5u以太网通讯设置_图文简述三菱FX 5U以太网通讯的8大功能,你会用几种?

热门文章

  1. 搜狗、chrome、猎豹三个浏览器所耗内存对比
  2. 数字证书常见格式整理
  3. 【Python抽奖系统】好消息:史上最强商场抽奖活动来啦,超优惠,攻略快拿好啦~(超牛)
  4. 《算法笔记》-两个子集合个数差最小,子集和的差最大
  5. php生成艺术签名 下
  6. 【劝退贴】学人工智能?你想好了吗?
  7. 串口工作在DMA模式下有时接收异常
  8. 关于CORS跨域问题的理解
  9. Linux学习笔记(二)——文件与磁盘系统
  10. store彩虹代shua商城模板分享