Google 以图搜图 - 相似图片搜索原理 - Java实现

前阵子在阮一峰的博客上看到了这篇《相似图片搜索原理》博客,就有一种冲动要将这些原理实现出来了。

 

Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相似的图片。

打开Google图片搜索页面:


点击使用上传一张angelababy原图:


点击搜索后,Google将会找出与之相似的图片,图片相似度越高就越排在前面。如:


这种技术的原理是什么?计算机怎么知道两张图片相似呢?

根据Neal Krawetz博士的解释,实现相似图片搜素的关键技术叫做"感知哈希算法"(Perceptualhash algorithm),它的作用是对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

 

以下是一个最简单的Java实现:

 

预处理:读取图片

File inputFile = newFile(filename); 
BufferedImage sourceImage = ImageIO.read(inputFile);//读取图片文件

第一步,缩小尺寸。

将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

int width= 8;
intheight = 8;
// targetW,targetH分别表示目标长和宽
int type= sourceImage.getType();// 图片类型
BufferedImagethumbImage = null;
double sx= (double) width / sourceImage.getWidth();
double sy= (double) height / sourceImage.getHeight();
// 将图片宽度和高度都设置成一样,以长度短的为准
if (b) {if(sx > sy) {sx= sy;width= (int) (sx * sourceImage.getWidth());}else {sy= sx;height= (int) (sy * sourceImage.getHeight());}
}
// 自定义图片
if (type== BufferedImage.TYPE_CUSTOM) { // handmadeColorModelcm = sourceImage.getColorModel();WritableRasterraster = cm.createCompatibleWritableRaster(width,height);booleanalphaPremultiplied = cm.isAlphaPremultiplied();thumbImage= new BufferedImage(cm, raster, alphaPremultiplied, null);} else {// 已知图片,如jpg,png,gifthumbImage= new BufferedImage(width, height, type);
}
// 调用画图类画缩小尺寸后的图
Graphics2Dg = target.createGraphics();
//smoother than exlax:
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawRenderedImage(sourceImage,AffineTransform.getScaleInstance(sx, sy));
g.dispose();

 

第二步,简化色彩。

将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

int[]pixels = new int[width * height];
for (inti = 0; i < width; i++) {for(int j = 0; j < height; j++) {pixels[i* height + j] = rgbToGray(thumbImage.getRGB(i, j));}
}
/*** 灰度值计算* @param pixels 彩色RGB值(Red-Green-Blue 红绿蓝)* @return int 灰度值*/
public static int rgbToGray(int pixels) {// int _alpha =(pixels >> 24) & 0xFF;int _red = (pixels >> 16) & 0xFF;int _green = (pixels >> 8) & 0xFF;int _blue = (pixels) & 0xFF;return (int) (0.3 * _red + 0.59 * _green + 0.11 * _blue);
}


第三步,计算平均值。

计算所有64个像素的灰度平均值。

int avgPixel= 0;
int m = 0;
for (int i =0; i < pixels.length; ++i) {m +=pixels[i];
}
m = m /pixels.length;
avgPixel = m;


第四步,比较像素的灰度。

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

int[] comps= new int[width * height];
for (inti = 0; i < comps.length; i++) {if(pixels[i] >= avgPixel) {comps[i]= 1;}else {comps[i]= 0;}
}

第五步,计算哈希值。

将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

 =  = 8f373714acfcf4d0

StringBufferhashCode = new StringBuffer();
for (inti = 0; i < comps.length; i+= 4) {intresult = comps[i] * (int) Math.pow(2, 3) + comps[i + 1] * (int) Math.pow(2, 2)+ comps[i + 2] * (int) Math.pow(2, 1) + comps[i + 2];hashCode.append(binaryToHex(result));//二进制转为16进制
}
StringsourceHashCode = hashCode.toString();


得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算"汉明距离"(Hammingdistance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

int difference = 0;
int len =sourceHashCode.length();for (inti = 0; i < len; i++) {if(sourceHashCode.charAt(i) != hashCode.charAt(i)) {difference++;}
}

你可以将几张图片放在一起,也计算出他们的汉明距离对比,就可以看看两张图片是否相似。

 

这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。

 

实际应用中,往往采用更强大的pHash算法和SIFT算法,它们能够识别图片的变形。只要变形程度不超过25%,它们就能匹配原图。这些算法虽然更复杂,但是原理与上面的简便算法是一样的,就是先将图片转化成Hash字符串,然后再进行比较。


以上内容大部分直接从阮一峰的网站上复制过来,想看原著的童鞋可以去在最上面的链接点击进去看。


提供源码下载,源码下载链接:http://download.csdn.net/detail/luohong722/3965112 

参考链接:神奇的图像处理算法, 11款相似图片搜索引擎推荐,以图搜图将不再是难事,http://insidesearch.blogspot.com/2011/07/teaching-computers-to-see-image.html

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27784.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT-5紧急叫停?千名专家联名呼吁,AI技术的未来又该何去何从?

在半个月前强势上线的GPT-4 &#xff0c;以其强大的性能再次掀起了一波关于人工智能技术的全民热潮。但GPT-4太强了&#xff0c;强到发指&#xff0c;不止群众恐慌&#xff0c;北京时间3月29日&#xff0c;全世界的 AI 大佬们纷纷出手&#xff0c;千名专家发表公开信&#xff0…

这次彻底搞懂 Redis,超详细总结!

作者&#xff1a;wugongzi 来源&#xff1a;https://www.cnblogs.com/wugongzi/p/16827473.html Redis 基础 如果对 Redis 还不了解的同学可以先看一下这篇 https://www.cnblogs.com/wugongzi/p/12841273.html 这里面介绍了 Redis 是什么&#xff0c;以及怎么用。 Redis 管道 我…

《花雕学AI》35:如何一次性和17个AI聊天机器人交流?ChatALL让你轻松实现

聊天机器人&#xff0c;也称为对话机器人&#xff0c;是一种能够通过自然语言与人类进行交流的人工智能系统。聊天机器人的应用领域非常广泛&#xff0c;从客服、娱乐、教育、医疗、社交等&#xff0c;到科研、商业、政治、军事等&#xff0c;几乎无所不包。随着深度学习和自然…

一个程序员的成长之路

学习笔记 java基础类型与String相关基本类型范围基本类型的转换byte计算自动转换int基本类型与包装类equals与的区别 集合比较与常用集合原理反射机制与真实使用场景动态代理与使用范例异常类加载机制与热加载实现与反编译内存模型与threadLocal与syncronizejvm的GC与调优处理J…

【Idea】人工智能编程他来了,Idea集成一款和ChatGPT一样智能的编码辅助神器

文章目录 简介官方介绍功能介绍 注册使用使用方法功能说明 结尾 简介 Bito是一款建立在OpenAI和ChatGPT之上的开发辅助神器&#xff01;他可以帮我们生成代码、语法提示、生成测试用例、解释代码含义、生成注释、优化代码、检测代码安全性以及学习理论知识等&#xff01;我们可…

澎湃新闻对话腾讯丁珂:从“治已病”到“治未病”,企业需快速构建“安全免疫力”

作者&#xff1a;澎湃新闻记者 周頔 随着数字化进程加快&#xff0c;企业数字化体系的边界在不断拓展&#xff0c;安全风险和挑战不断增加&#xff0c;传统被动防御的安全应对常显疲态&#xff0c;数字安全时代亟待建立全新的安全范式。 6月13日&#xff0c;腾讯安全联合IDC等…

2023年大学生就业怎么样?双一流高校就业率仅15%,到底是咋了?

2023年&#xff0c;大学毕业生就业状况如何&#xff0c;一直是社会关注的焦点。尤其是中国的双一流高校&#xff0c;以其优越的教学与研究背景和实力&#xff0c;被众多年轻人视为就业的理想选择。 然而&#xff0c;在最新的统计数据中&#xff0c;这些一流高校的就业率却惊人…

Chat GPT 的上线,网络安全问题已经显现

前言 Chat GPT已经发布了&#xff0c;一位不知名的作者将它的孪生兄弟“DAN”就在世界上最黑暗的暗网上线了。 这个黑化的GPT刚刚上线的一周后&#xff0c;就已经有组织利用“DAN”犯罪了。 他们利用虚拟电话号码注册各种交友平台的账号&#xff0c;然后再模仿有魅力的男女人…

媒体专访|知道创宇黑哥:视野和格局将决定网络空间测绘的未来!

日前&#xff0c;网安专业媒体安全牛【牛人访谈】栏目专访了知道创宇CSO黑哥&#xff08;周景平&#xff09;。 围绕知道创宇出版的新书《网络空间测绘技术与实践》&#xff0c;安全牛分析师与黑哥就网络空间测绘技术当下的应用与挑战、未来的发展与创新进行了对话与交流。 以…

《花雕学AI》比尔・盖茨:AI 和 ChatGPT 可以改善人类生活,但也要防止滥用和危害

3月21号&#xff0c;微软创始人比尔盖茨&#xff0c;发表最新AI文章《人工智能时代已经开始——人工智能与手机、互联网一样具有革命性》&#xff0c;文章中表示&#xff1a;「自1980年首次看到图形用户界面&#xff08;graphical user interface&#xff09;以来&#xff0c;O…

速下载|2023上半年网络与数据安全法规政策、国标、报告合集

随着国家数字经济建设进程加快&#xff0c;数据安全立法实现由点到面、由面到体加速构建&#xff0c;目前我国数据安全立法已基本形成以《网络安全法》《数据安全法》《个人信息保护法》《密码法》等法律为核心&#xff0c;行政法规、部门规章为依托&#xff0c;地方性法规、地…

ChatGPT进军网络安全,安全从业者将会被取代?

在ChatGPT爆火之后&#xff0c;微软宣布推出基于ChatGPT的“安全副驾驶”产品&#xff0c;宣称将“帮助防御者以机器的速度和规模进行端到端防御。” 网络安全是人工智能最大的细分市场&#xff0c;而ChatGPT又是引领当下人工智能技术革命的“核弹级产品”&#xff0c;在网络安…

C#与西门子PLC通信通过S7.NET

前言&#xff1a; S7.NET支持连接S7-200SMART,S7-1200,S7-1500,S7-300,S7-400PLC,只支持西门子系列PLC&#xff0c;而且连接方式要是profinet通信 一&#xff0c;引用S7.NET的dll文件 二&#xff0c;using S7.Net; 三,实例化PLC 如果是连接PLC SMART200&#xff0c;CPU.Type直…

利用NetToPLCsim将西门子PLCSIM变成一个真实PLC,实现与录波软件、HMI软件等的通讯

学习西门子PLC的朋友们对于西门子的S7-PLCSIM软件都不陌生&#xff0c;当我们安装了该软件后&#xff0c;在STEP7或者博图的面板中就多出了一个仿真的按钮&#xff0c;点击该按钮&#xff0c;就会调出仿真软件S7-PLCSIM软件&#xff0c;将当前的PLC项目下载进去。启动该仿真PLC…

博途仿真PLC与第三方客户端通信

NetToSimPLC使用 在缺少PLC硬件的情况下&#xff0c;我们可以借助PLC模拟器&#xff08;西门子&#xff09;PLCSim做一些简单程序测试。但是除了PLC程序本身需要测试以外&#xff0c;PLC之间的通讯和PLC与HMI、SCADA的连接也是需要调试的。在缺少硬件的情况下&#xff0c; 往往…

PLC程序实例二:ModBusTCP客户端编程实例与测试方法

一、需求描述 1、设备作为服务端时&#xff0c;需要给出对应的测试方法&#xff0c;即要求 PLC 作为客户端&#xff0c;设备作为服务端&#xff0c;因此要求编写 PLC 的ModBusTCP客户端 2、先了解一下设备作为服务端的ModBusTCP网络触发业务逻辑 &#xff08;1&#xff09;设…

C#界面通过nettoplcsim与西门子PLC仿真连接

我&#xff01;&#xff01;终于&#xff01;&#xff01;成功了&#xff01;&#xff01;&#xff01;本踩坑大王终于跳出来了&#xff01;&#xff01;&#xff01;&#xff01;先放个图纪念一下 下面详细记录一下如何用C#上位机与西门子S7-1200在PLCSIM中进行仿真连接。过程…

C#与西门子PLC通讯

C#与西门子PLC通讯 S7NetPLC设置C#程序 S7Net PLC在工业自动化领域是常用的控制器&#xff0c;一般在和上位机界面通讯时&#xff0c;经常使用组态软件。以西门子PLC为例&#xff0c;上位机可以使用西门子的WINCC。但是&#xff0c;当面对需求比较多样化的需求时&#xff0c;W…

C#使用S7NetPlus以及PLCSIM Advanced V3.0实现西门子PLC仿真通讯

PLCSIM Advanced 简介 PLCSIM Advanced是西门子推出的一款功能强大的仿真软件&#xff0c;目前最新发布的版本为4.0&#xff0c;但鉴于新版本可能存在未知的bug&#xff0c;故本文使用V3.0。 V3.0支持仿真1500PLC及ET 200SP&#xff0c;可实现Socket网络通讯功能&#xff0c;…

西门子PLC与C#程序的S7.net通信

1、导入S7.net通信文件&#xff1a;打开工具->NuGet包管理器->管理解决方案得NuGet程序包&#xff0c;入下图搜索S7&#xff0c;安装S7netplus。 在程序中引用S7.Net文件 建立西门子PLC类 using System; using System.Collections.Generic; using System.Linq; using…