找出相似的图片--C#
请先参考我写到java这章
原理讲解
参考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*8
private Image ReduceSize(int width = , int height = )
{
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 = ; x<image.Width; x++)
for (int y = ; y < image.Height; y++)
{
Color color = bitMap.GetPixel(x, y);
byte grayValue = (byte)((color.R * + color.G * + color.B * ) / );
grayValues[x * image.Width + y] = grayValue;
}
return grayValues;
} // Step 3 : Average the colors
private Byte CalcAverage(byte[] values)
{
int sum = ;
for (int i = ; 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 = ; i < values.Length; i++)
{
if (values[i] < averageValue)
result[i] = '';
else
result[i] = '';
}
return new String(result);
} // Compare hash
public static Int32 CalcSimilarDegree(string a, string b)
{
if (a.Length != b.Length)
throw new ArgumentException();
int count = ;
for (int i = ; i < a.Length; i++)
{
if (a[i] != b[i])
count++;
}
return count;
}
}
}
转:http://www.cnblogs.com/technology/archive/2012/07/12/2588022.html
找出相似的图片--C#的更多相关文章
- 【CTF MISC】隐写术wireshark找出图片-“强网杯”网络安全挑战赛writeup
这场CTF中有一道题是分析pcap包的.. 13.大黑阔: 从给的pcap包里把图片提取出来,是一张中国地图. 题目提示是黑阔在聊天,从数据里可以找出几段话. 思路:主要考察wireshark的过滤规 ...
- 机器学习进阶-项目实战-信用卡数字识别 1.cv2.findContour(找出轮廓) 2.cv2.boudingRect(轮廓外接矩阵位置) 3.cv2.threshold(图片二值化操作) 4.cv2.MORPH_TOPHAT(礼帽运算突出线条) 5.cv2.MORPH_CLOSE(闭运算图片内部膨胀) 6. cv2.resize(改变图像大小) 7.cv2.putText(在图片上放上文本)
7. cv2.putText(img, text, loc, text_font, font_scale, color, linestick) # 参数说明:img表示输入图片,text表示需要填写的 ...
- Linux运维之批量下载指定网站的100个图片文件,并找出大于200KB的文件
题目为: 有一百个图片文件,它们的地址都是http://down.fengge.com/img/1.pnghttp://down.fengge.com/img/2.png…一直到http://dow ...
- c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)
c#封装DBHelper类 public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...
- Facebook存储技术方案:找出“暖性BLOB”数据
Facebook公司已经在其近线存储体系当中彻底弃用RAID与复制机制,转而采用分布式擦除编码以隔离其所谓的“暖性BLOB”. 暖性?BLOB?这都是些什么东西?大家别急,马上为您讲解: BLOB—— ...
- 使用 Visual Studio 分析器找出应用程序瓶颈(转)
使用 Visual Studio 分析器找出应用程序瓶颈 Hari Pulapaka and Boris Vidolov 本文讨论: 以性能瓶颈为目标 应用程序代码分析 比较分析数据 性能报告 本文使 ...
- 使用 Visual Studio 分析器找出应用程序瓶颈
VS的性能分析工具 性能分析工具的选择 打开一个“性能分析”的会话:Debug->Start Diagnotic Tools Without Debugging(或按Alt+F2),VS2013 ...
- 机器学习进阶-图像特征sift-SIFT特征点 1.cv2.xfeatures2d.SIFT_create(实例化sift) 2. sift.detect(找出关键点) 3.cv2.drawKeypoints(画出关键点) 4.sift.compute(根据关键点计算sift向量)
1. sift = cv2.xfeatures2d.SIFT_create() 实例化 参数说明:sift为实例化的sift函数 2. kp = sift.detect(gray, None) 找出 ...
- 机器学习进阶-图像金字塔与轮廓检测-模板匹配(单目标匹配和多目标匹配)1.cv2.matchTemplate(进行模板匹配) 2.cv2.minMaxLoc(找出矩阵最大值和最小值的位置(x,y)) 3.cv2.rectangle(在图像上画矩形)
1. cv2.matchTemplate(src, template, method) # 用于进行模板匹配 参数说明: src目标图像, template模板,method使用什么指标做模板的匹配 ...
随机推荐
- fastJson解析复杂的json字符串,经测试已经成功解析
要解析的json数据格式为: HTTP/1.1 200 OK Content-Type: text/jsv Content-Length: length { ResponseStatus: { }, ...
- Cocos Creator的小点
声明的时候,变量如此:但用的时候就变成了border,找了很久的问题,一直没找到啊,后来就发现命名的时候和内置的一定不要太相似否则后悔的只能是自己: cc.Class({ extends: cc.Co ...
- Python基础语法-基本数据类型
此文档解决以下问题: 一.Python中数值数据类型——整型(int).浮点型(float).布尔型(bool).复数(complex) 1.float()函数的运用 2.int()函数的运用 3.t ...
- android常用工具收集
1.脱壳工具 https://github.com/DrizzleRisk/drizzleDumper
- makefile中的shell编程注意点
参考:http://blog.csdn.net/wanglang3081/article/details/49423105 (1)Makefile本质上来讲也是shell脚本,即每条command都是 ...
- springmvc 动态加载配置文件
<import resource="classpath:config/spring-profile-properties.xml" /> <context:pro ...
- java 集合框架 Java集合&List的实现
原文: https://blog.csdn.net/u012658346/article/details/50917068 一.java集合类图如下所示: 上述类图中,实线边框的是实现类,比如Arra ...
- Android Studio下加入百度地图的使用(二)——定位服务
上一章(http://www.cnblogs.com/jerehedu/p/4891216.html)中我们已经完成了环境的搭建,这一章我们来研究一下如何使用. 第一步:在xml文件中加入以下权限 & ...
- shell编程中的控制判断语句
if 单格式与嵌套 if 条件表达式;then #当条件为真时执行以下语句 命令列表 else #为假时执行以下语句 命令列表 fi if 语句也可以嵌套使用 if 条件表达式1;then if 条件 ...
- 从源码编译InfluxDB
操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 go语言安装参考: http://www.cnblogs.com ...