#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. vue-router 利用url传递参数

    vue-router 利用url传递参数 :冒号的形式传递参数  在路由配置文件里以:冒号的形式传递参数,这就是对参数的绑定. 1. 在配置文件里以冒号的形式设置参数.我们在/src/router/i ...

  2. 官方Android Camera2 录像示例--停止录像时崩溃修正

    官方Android 使用Camera2示例项目地址:https://github.com/android/camera-samples 视频录像示例:https://github.com/androi ...

  3. 【转】分享一款颜色神器ColorSchemer Studio

    原文:https://www.cnblogs.com/xyfll7/p/7569078.html ColorSchemer Studio是一款专业配色软件,网页设计或平面设计师必备工具,和ColorP ...

  4. MAC下快速打开指定目录(转)

    使用了这么长时间MAC,打开文件查找目录总是感觉还是不如windows来的爽快 1.通过快捷键搜索   command + 空格,输入关键词 2.通过控制台打开    1) 跳转到指定路径  cd  ...

  5. shell编程系列17--文本处理三剑客之awk动作中的表达式用法

    shell编程系列17--文本处理三剑客之awk动作中的表达式用法 awk动作表达式中的算数运算符 awk动作中的表达式用法总结: 运算符 含义 + 加 - 减 * 乘 / 除 % 模 ^或** 乘方 ...

  6. 【转载】 tf.split函数的用法

    原文地址: https://blog.csdn.net/uestc_c2_403/article/details/73350457 由于tensorflow 版本更新问题   用法略有修改 ----- ...

  7. JSOUP 爬虫

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.mavne 依赖: <!--html 解析 : jsoup HTML parser library @ ...

  8. 5-1 嵌套while循环应用

    package com.imooc; public class forDemo { public static void main(String[] args) { ;//外重循环的循环变量: ;// ...

  9. linux非root用户安装jdk1.8

    如题,先到 Oracle 官方网站 下载1.8版本的 JDK 压缩包(jdk-8u221-linux-x64.tar.gz)到本地(如D盘的soft目录),然后开始进入linux的非root用户(如w ...

  10. 【Java】分布式自增ID算法---雪花算法 (snowflake,Java版)

    一般情况,实现全局唯一ID,有三种方案,分别是通过中间件方式.UUID.雪花算法. 方案一,通过中间件方式,可以是把数据库或者redis缓存作为媒介,从中间件获取ID.这种呢,优点是可以体现全局的递增 ...