#region 生成图片及图片比较
public String GetHash(Image SourceImg)
{
Image image = ReduceSize(SourceImg);
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(Image SourceImg)
{
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 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;
}
#endregion

  

原理讲解

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

第一步 缩小图片尺寸

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

第二步 转为灰度图片

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

第三步 计算灰度平均值

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

第四步 比较像素的灰度

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

第五步 计算哈希值

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

第六步 对比图片指纹

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

参考文:https://blog.csdn.net/weixin_34066347/article/details/86363431

淘宝图片指纹匹配功能c#实现的更多相关文章

  1. 【Demo】jQuery 图片放大镜效果——模仿淘宝图片放大效果

    实现功能: 模仿淘宝图片放大效果,鼠标移动到小图片的某一处,放大镜对应显示大图片的相应位置. 实现效果: 实现代码: <!DOCTYPE html> <html> <he ...

  2. 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能

    前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...

  3. 关于opencv模板匹配功能的项目测试记录

    模板匹配功能介绍的很好的一篇博客:https://www.cnblogs.com/XJT2018/p/9934139.html 就如上述博客所言:“若原图像中的匹配目标发生旋转或大小变化,该算法无效. ...

  4. 原生js实现淘宝图片切换

    这个淘宝图片切换具体效果就是:鼠标移上底部一行中的小图片,上面大图片区域就会显示对应的图片. gif图片看起来还挺酷的,其实实现很简单,用原生js绑定事件改变大图片区域的src. 上代码,html部分 ...

  5. chrome 显示图片遇到的问题,与 淘宝图片服务器 缓存 有关系

    最近发现使用淘宝的jae环境,一个 abc.jsp 地址,随机跳转到淘宝图片空间里任意的一张图片. 但在chrome浏览器发现一个奇怪的问题: 用户第一次访问 abc.jsp  -> 302 f ...

  6. Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能

    Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能. 下面是个例子: import org.junit.Test; import java. ...

  7. 基于Vuejs的搜索匹配功能

    最近一直在看vue,查了很多资料,看了很多文档和博客,大概半知半解了,然后利用所理解的知识写了一个简单的搜索匹配功能. 大概长这个样子:   <!DOCTYPE html> <htm ...

  8. iOS- Swift:指触即开,如何集成Touch ID指纹识别功能

    1.前言 随着移动支付时代的到来,Touch ID 指纹验证迅速被支付宝,微信钱包普及,相信各位朋友使用后也大呼方便.之前写了篇关于iOS9的3D Touch的集成使用,有朋友在我博客下提到,让我写一 ...

  9. 实现一个带有指纹加密功能的笔记本(Android)第二部分

    上文基本完成了整个笔记本的笔记功能的实现,接下来记录实现指纹识别加密以及一些小注意事项. 首先判断该手机是否具备指纹识别的硬件功能和用户是否开启指纹识别. public boolean isFinge ...

随机推荐

  1. Comparison and difference for Default geodatabase,Current workspace,Scratch workspace,Home Folder

    Comparison and difference for Default geodatabase,Current workspace,Scratch workspace,Home Folder 商务 ...

  2. CopyOnWrite 思想及在 Java 并发包中的具体体现

    读多写少的场景下引发的问题? 假设现在我们的内存里有一个 ArrayList,这个 ArrayList 默认情况下肯定是线程不安全的,要是多个线程并发读和写这个 ArrayList 可能会有问题. 那 ...

  3. Linux 下不得不说的那些快捷键

    一 .终端里使用的那些快捷键(SERVER ADMIN必备) !! 执行上一条命令 !abc 执行以abc开头的最新的命令 !n 执行历史中第n个命令 Alt-> 历史最后一项 Alt-< ...

  4. postgresql 臭氧8小时聚合函数

    1.定义数据拼接函数 CREATE OR REPLACE FUNCTION "public"."sfun"("results" _numer ...

  5. 003-结构型-03-代理模式(Proxy)

    一.概述 Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问. 可以详细控制访问某个类或对象的方法,在调用这个方法(流程代码放到代理 ...

  6. netty5客户端监测服务端断连后重连

    服务端挂了或者主动拒绝客户端的连接后,客户端不死心,每15秒重连试试,3次都不行就算了.修改下之前的客户端引导类(NettyClient,参见netty5心跳与业务消息分发实例),新增两个成员变量,在 ...

  7. 聚类K-Means和大数据集的Mini Batch K-Means算法

    import numpy as np from sklearn.datasets import make_blobs from sklearn.cluster import KMeans from s ...

  8. Glide图片加载过程(简)

    iceIC 关注 2018.10.25 20:53* 字数 906 阅读 529评论 0喜欢 1 调研版本为4.7.1为了更加简单的理解,会将函数代码简化,详细代码请自行照源码对比 Glide用法 G ...

  9. Sq常用操作

    sql创建表实例: CREATE TABLE mytable( id varchar(40) NOT NULL default '', userId varchar(40) NOT NULL defa ...

  10. iOS 控制输入框的字数?(textFliedView,textFlied等)

    //控制输入框的字数 - (void)textViewDidChange:(UITextView *)textView { NSInteger number = [textView.text leng ...