主类:

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;public class SimilarImageSearch {/*** @param args*/public static void main(String[] args) {List<String> hashCodes = new ArrayList<String>();String filename = ImageHelper.path + "\\images\\";String hashCode = null;for (int i = 0; i < 6; i++){hashCode = produceFingerPrint(filename + "example" + (i + 1) + ".jpg");hashCodes.add(hashCode);}        System.out.println("Resources: ");System.out.println(hashCodes);System.out.println();String sourceHashCode = produceFingerPrint(filename + "source.jpg");System.out.println("Source: ");System.out.println(sourceHashCode);System.out.println();for (int i = 0; i < hashCodes.size(); i++){int difference = hammingDistance(sourceHashCode, hashCodes.get(i));System.out.print("汉明距离:"+difference+"     ");if(difference==0){System.out.println("source.jpg图片跟example"+(i+1)+".jpg一样");}else if(difference<=5){System.out.println("source.jpg图片跟example"+(i+1)+".jpg非常相似");}else if(difference<=10){System.out.println("source.jpg图片跟example"+(i+1)+".jpg有点相似");}else if(difference>10){System.out.println("source.jpg图片跟example"+(i+1)+".jpg完全不一样");}}}/*** 计算"汉明距离"(Hamming distance)。* 如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。* @param sourceHashCode 源hashCode* @param hashCode 与之比较的hashCode*/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;}/*** 生成图片指纹* @param filename 文件名* @return 图片指纹*/public static String produceFingerPrint(String filename) {BufferedImage source = ImageHelper.readPNGImage(filename);// 读取文件int width = 8;int height = 8;// 第一步,缩小尺寸。// 将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。BufferedImage thumb = ImageHelper.thumb(source, width, height, false);// 第二步,简化色彩。// 将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。int[] pixels = new int[width * height];for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {pixels[i * height + j] = ImageHelper.rgbToGray(thumb.getRGB(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();}/*** 二进制转为十六进制* @param int binary* @return char hex*/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;}}

工具类:

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;import javax.imageio.ImageIO;import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;/*** 图片工具类,主要针对图片水印处理* * @author  025079* @version  [版本号, 2011-11-28]* @see  [相关类/方法]* @since  [产品/模块版本]*/
public class ImageHelper {// 项目根目录路径public static final String path = System.getProperty("user.dir");/*** 生成缩略图 <br/>* 保存:ImageIO.write(BufferedImage, imgType[jpg/png/...], File);* * @param source*            原图片* @param width*            缩略图宽* @param height*            缩略图高* @param b*            是否等比缩放* */public static BufferedImage thumb(BufferedImage source, int width,int height, boolean b) {// targetW,targetH分别表示目标长和宽int type = source.getType();BufferedImage target = null;double sx = (double) width / source.getWidth();double sy = (double) height / source.getHeight();if (b) {if (sx > sy) {sx = sy;width = (int) (sx * source.getWidth());} else {sy = sx;height = (int) (sy * source.getHeight());}}if (type == BufferedImage.TYPE_CUSTOM) { // handmadeColorModel cm = source.getColorModel();WritableRaster raster = cm.createCompatibleWritableRaster(width,height);boolean alphaPremultiplied = cm.isAlphaPremultiplied();target = new BufferedImage(cm, raster, alphaPremultiplied, null);} elsetarget = new BufferedImage(width, height, type);Graphics2D g = target.createGraphics();// smoother than exlax:g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));g.dispose();return target;}/*** 图片水印* * @param imgPath*            待处理图片* @param markPath*            水印图片* @param x*            水印位于图片左上角的 x 坐标值* @param y*            水印位于图片左上角的 y 坐标值* @param alpha*            水印透明度 0.1f ~ 1.0f* */public static void waterMark(String imgPath, String markPath, int x, int y,float alpha) {try {// 加载待处理图片文件Image img = ImageIO.read(new File(imgPath));BufferedImage image = new BufferedImage(img.getWidth(null),img.getHeight(null), BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.drawImage(img, 0, 0, null);// 加载水印图片文件Image src_biao = ImageIO.read(new File(markPath));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));g.drawImage(src_biao, x, y, null);g.dispose();// 保存处理后的文件FileOutputStream out = new FileOutputStream(imgPath);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(image);out.close();} catch (Exception e) {e.printStackTrace();}}/*** 文字水印* * @param imgPath*            待处理图片* @param text*            水印文字* @param font*            水印字体信息* @param color*            水印字体颜色* @param x*            水印位于图片左上角的 x 坐标值* @param y*            水印位于图片左上角的 y 坐标值* @param alpha*            水印透明度 0.1f ~ 1.0f*/public static void textMark(String imgPath, String text, Font font,Color color, int x, int y, float alpha) {try {Font Dfont = (font == null) ? new Font("宋体", 20, 13) : font;Image img = ImageIO.read(new File(imgPath));BufferedImage image = new BufferedImage(img.getWidth(null),img.getHeight(null), BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.drawImage(img, 0, 0, null);g.setColor(color);g.setFont(Dfont);g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));g.drawString(text, x, y);g.dispose();FileOutputStream out = new FileOutputStream(imgPath);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(image);out.close();} catch (Exception e) {System.out.println(e);}}/*** 读取JPEG图片* @param filename 文件名* @return BufferedImage 图片对象*/public static BufferedImage readJPEGImage(String filename){try {InputStream imageIn = new FileInputStream(new File(filename));// 得到输入的编码器,将文件流进行jpg格式编码JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(imageIn);// 得到编码后的图片对象BufferedImage sourceImage = decoder.decodeAsBufferedImage();return sourceImage;} catch (FileNotFoundException e) {e.printStackTrace();} catch (ImageFormatException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}/*** 读取JPEG图片* @param filename 文件名* @return BufferedImage 图片对象*/public static BufferedImage readPNGImage(String filename){try {File inputFile = new File(filename);  BufferedImage sourceImage = ImageIO.read(inputFile);return sourceImage;} catch (FileNotFoundException e) {e.printStackTrace();} catch (ImageFormatException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}/*** 灰度值计算* @param pixels 像素* @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);}/*** 计算数组的平均值* @param pixels 数组* @return int 平均值*/public static int average(int[] pixels) {float m = 0;for (int i = 0; i < pixels.length; ++i) {m += pixels[i];}m = m / pixels.length;return (int) m;}
}

原文地址:http://blog.csdn.net/yjflinchong/article/details/7469213#

java指纹识别+谷歌图片识别技术_源代码相关推荐

  1. java ocr 验证码_Ocrking图片识别之Java实现本地验证码的识别 | 学步园

    本实例代码为Java实现本地验证码的识别 依赖库为 httpclient-4.2 使用最新的库 需要修改部分代码 Author: niostars@gmail.com //构造一个httpclient ...

  2. 调用百度AI平台API进行文字识别和图片识别

    写在前面 这应该是本年度的最后一篇技术博客了,今年在CSDN上总共发表了20篇博客,除掉几篇LeetCode的博客,都是个人工作的总结,总体来说,收获不少,随手记录的习惯也养成了.希望来年持之以恒. ...

  3. 互联网图片文字识别 互联网图片识别 彩信识别 彩信图片文字识别

    "源于清华 服务全球"的国内顶尖OCR图文识别技术,针对视频文件里面的文字字符以及复杂背景图片的文字字符进行计算识别!   摘要:通过对视频文件里的字幕提取,达到视频文件的分类归档 ...

  4. 调用百度大脑智能里的文字识别实现图片识别

    由于有一本古籍需要识别,网上找了几个软件对于繁体字均感觉识别率不高.试了下发现百度的识别率还可以,于是想自己写一个调用百度图片识别api的程序. 用Delphi2010编码实现.在开发中遇到了几个问题 ...

  5. 基于Opencv快速实现人脸识别(图片识别)

    两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循"slabel"命名规则,但后面处理起来比较麻烦,因为目前opencv接 ...

  6. Java服务器上显示图片问题_java,_服务器读取图片到jsp显示问题,java - phpStudy

    服务器读取图片到jsp显示问题 我要从服务器读个图片显示到jsp jsp页面 后台 @RequestMapping(value = "getPic", method = Reque ...

  7. java自带的字节码技术_读懂字节码-还原JAVA源码

    已知有两个类: public class Father extends GrandFather { public String name = "father"; public vo ...

  8. java实现登录验证机制的技术_基于token的登陆验证机制

    session简介 做过Web开发的程序员应该对Session都比较熟悉,Session是一块保存在服务器端的内存空间,一般用于保存用户的会话信息. 用户通过用户名和密码登陆成功之后,服务器端程序会在 ...

  9. 前端图片合成技术_前端图片合并方案调研

    介绍 通过产品线数据分析,发现70%左右的图片为小于300K的图片,50%左右为小于100K的图片,因此调研前端图片合并方案是否有利于提高图片批量上传速度.之前做过的前端ZIP方案也是类似的思路. 工 ...

最新文章

  1. mysql 1243_MySQL#1243给予EXECUTE的未知预处理语句处理程序(stmt)
  2. sql server 2008学习3 表组织和索引组织
  3. dm368ipnc 重写架构中的swosd 实现中文osd
  4. hadoop二次排序
  5. java swing 一闪而过_Java代码,为什么图形会一闪而过,怎么修改?
  6. SQL2005结合ROW_NUMBER()高效分页存储过程
  7. JAVA两个视图层_MVC - 管理帐户 . 一个视图有两个局部视图和两个模型
  8. 舰r4月28服务器维护,崩坏3 11月28日版本更新维护通知
  9. asp去HTML标签
  10. Endnote在word中每次启动都要加载,或者无法加载的解决办法
  11. 【Atcoder agc020 C】Median Sum,序列子集和中位数,bitset,01背包
  12. Linux下Qt使用QAudio相关类进行音频采集,使用Windows下的Matlab软件播放
  13. Presto 安装与部署
  14. 苹果id解锁平台_黄蜂2单手手柄体验:苹果安卓平台双通用,解锁新潮玩法!
  15. Visual C++——定时器(计时器)SetTimer函数
  16. iMeta | 南京医科大学孔祥清团队创建前瞻性多组学纵向原发高血压队列eHypertension...
  17. MOOC 苏小红C语言 第四周编程题
  18. 什么是等级保护?等保二级和三级的区别?
  19. redis基础知识:数据结构SDS
  20. 安卓一键清理内存_安卓的手机内存清理来啦……

热门文章

  1. 51GIS学院分享室内导航定位技术研究进展与展望
  2. USB协议中的返回包含义
  3. 常用检索系统简单说明
  4. 用原生JS实现虚表控件
  5. 计算机的学生跨专业考研
  6. few-shot基本概念
  7. 游戏蓝牙耳机哪款比较好?游戏党推荐四款好用的低延迟蓝牙耳机
  8. 3、综合布线施工常用的线材及设备工具(图文)
  9. 絮絮叨叨的2020年小总结
  10. 理论——RNN(循环神经网络)与LSTM(长短期记忆神经网络)