Android 以图找图功能
来源:互联网 发布:kali linux安装到u盘 编辑:程序博客网 时间:2024/06/05 00:17
到2016年的最后一个月了,总得写点什么或者记录点什么。恩,就记录一下,我当时做以图找图,这个功能的过程和结果吧。以图找图简而言之就是确认小图是否属于大图的一部分。
1.序
刚开始做这个功能的时候,我一直在往误区上找,认为这是Android的项目,然后一直在找android方面的东西,也确实找到了,但这方面根本没有相关的DEMO(其实也是因为个人有点懒,有现成的,总是想直接用。)
然后想到了其实可以从java方面图片,这样就发现很多都是通过像素点进行查找的,但原理上是没错的就是查找的过程就有点慢了。在电脑上运行当然很快,但放在android上就很慢了,毕竟你需要对比每个像素点。
最后是通过计算哈希值的方法,来进行图片的查找。虽然也需要一块一块的查(就是根据原图片的大小,然后在目标图片上查找),然后得出结论是否是属于目标图片的。
2.代码
/** 小图是否属于大图 * @param mubiao 目标图片(大图)地址 * @param yuantu 源图片(小图)地址 * @return * @throws IOException */private static boolean FindImg(String mubiao, String yuantu) throws IOException{boolean isFind = false; Bitmap yuantusource = BitmapFactory.decodeFile(yuantu, null); Bitmap mubiaosource = BitmapFactory.decodeFile(mubiao, null); // huidu("yuantu" , yuantu);// huidu("mubiao" , mubiao); String mubiaoHashCode; String yuantuHashCode; Bitmap jiequsource; int width = yuantusource.getWidth(); int height = yuantusource.getHeight(); int Mwidth = mubiaosource.getWidth(); int Mheight = mubiaosource.getHeight(); mubiaoHashCode = BufproduceFingerPrint(mubiaosource); //通过循环来查找图片(就是从左上到右下)
for(int i=0;i<width-Mwidth;i++){ for(int j= 0;j<height-Mheight;j++){ jiequsource = Bitmap.createBitmap(yuantusource, i, j, width, height, null, false); yuantuHashCode = BufproduceFingerPrint(jiequsource); int difference = hammingDistance(mubiaoHashCode, yuantuHashCode); if(difference == 0 ){ ImageUtils.savePhotoToSDCard(context, "找到", jiequsource); SharedUtil.saveData(context, "Find", "x", String.valueOf(backX)); SharedUtil.saveData(context, "Find", "y", String.valueOf(j));// LogInfo.ceshi("找到2:x="+ backX + "y=" + j); isFind = true; break; } else{// LogInfo.ceshi("没找到2:x="+ backX + "y=" + j);// ToastUtil.showToast(context, "正在查找中···"); } } } if(isFind){ return true; }else{ return false; } }
/** * 处理图片 * @param source * @return */public static String BufproduceFingerPrint(Bitmap source) {// BufferedImage source = ImageHelper.readPNGImage(filename);// 读取文件 int width = 8; int height = 8; int pixelColor; // 第一步,缩小尺寸。 // 将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。 Bitmap thumb = ImageHelper.zoomImage(source, width,height); // 第二步,简化色彩。 // 将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。 int[] pixels = new int[width * height]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) {// System.out.println("i=" + i +";y=" + j);// pixelColor = thumb.getPixel(i, j);// R = Color.red(pixelColor);// G = Color.green(pixelColor);// B = Color.blue(pixelColor); pixels[i * height + j] = ImageHelper.rgbToGray(thumb.getPixel(i, j)); } } // 第三步,计算平均值。 // 计算所有64个像素的灰度平均值。 int avgPixel = ImageHelper.average(pixels); // 第四步,比较像素的灰度。 // 将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。 int[] comps = new int[width * height]; for (int i = 0; i < comps.length; i++) { if (pixels[i] >= avgPixel) { comps[i] = 1; } else { comps[i] = 0; } } // 第五步,计算哈希值。 // 将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。 StringBuffer hashCode = new StringBuffer(); for (int i = 0; i < comps.length; i += 4) { int result = 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)); } // 得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。 return hashCode.toString(); } private static char binaryToHex(int binary) { char ch = ' '; switch (binary) { case 0: ch = '0'; break; case 1: ch = '1'; break; case 2: ch = '2'; break; case 3: ch = '3'; break; case 4: ch = '4'; break; case 5: ch = '5'; break; case 6: ch = '6'; break; case 7: ch = '7'; break; case 8: ch = '8'; break; case 9: ch = '9'; break; case 10: ch = 'a'; break; case 11: ch = 'b'; break; case 12: ch = 'c'; break; case 13: ch = 'd'; break; case 14: ch = 'e'; break; case 15: ch = 'f'; break; default: ch = ' '; } return ch; }
/** * 2个是否相同,0为相同 * @param sourceHashCode * @param hashCode * @return */ public static int hammingDistance(String sourceHashCode, String hashCode) { int difference = 0; int len = sourceHashCode.length(); for (int i = 0; i < len; i++) { if (sourceHashCode.charAt(i) != hashCode.charAt(i)) { difference++; } } return difference; }
3.结束
恩,这就是以图找图的所有代码=-=恩,是通过网上方法总结出来了的=-=就这样了。
0 0
- Android 以图找图功能
- Android开发学习之以CameraAPI方式实现相机功能(二)——相机功能配置
- 以图搜图功能实现
- 如何使用谷歌“以图找图”图片搜索功能
- Android开发学习之以CameraAPI方式实现相机功能(一)——快速实现相机
- 使用栈结构简易实现浏览器的后退与前进功能(以Android为例)
- 申请百度提供的API Key,以在自己的Android应用程序中使用百度的LBS功能
- 以图找图
- Android开发以备后用
- 以继承基类的功能!
- lua以xpcall实现try/catch功能
- Android底層系統服務開發:以MediaRecorder模組為例
- COM+:创建补偿资源管理器以扩展应用程序的事务性功能
- ASP.NET Forums N层架构实现,以功能举例
- MATLAB命令大全——以功能进行分类
- 用Delphi开发ISAPI过滤器以增强IIS功能
- 百度关闭竞价排名部分功能,以提升用户体验
- 百度关闭竞价排名部分功能,以提升用户体验
- 3Sum
- UEditor转义字符入库再显示带标签的解决方法
- 自己记录,筛选我喜欢的宝宝
- elasticsearch 时间查询语法
- weblogic部署更新会多出来一个工程
- Android 以图找图功能
- One-vs-Rest算法介绍及Spark MLlib调用实例(Scala/Java/Python)
- 初始化(C++primer5th学习笔记)
- 学jQuery笔记
- 深入浅出JMS(一)--JMS基本概念
- 【Dijkstra模板】codeforces715B Complete The Graph(最短路径)
- 学习TCP/IP协议
- LibEvent中文帮助文档--第12章【Evbuffer IO实用功能】
- 学生信息管理系统优化(一)