packagecom.aliyun.picture.demo;/*** @BelongsProject: maven-demo

* @BelongsPackage: com.aliyun.picture.demo

* @Author: Guoyh

* @CreateTime: 2018-10-12 15:05

* @Description: 感知哈希算法(均值哈希算法)比较两图的相似性*/

importjavax.imageio.ImageIO;importjava.awt.Graphics;importjava.awt.Image;importjava.awt.color.ColorSpace;importjava.awt.image.BufferedImage;importjava.awt.image.ColorConvertOp;importjava.util.Arrays;importjava.io.File;public final classFingerPrint {/*** 图像指纹的尺寸,将图像resize到指定的尺寸,来计算哈希数组*/

private static final int HASH_SIZE = 16;/*** 保存图像指纹的二值化矩阵*/

private final byte[] binaryzationMatrix;public FingerPrint(byte[] hashValue) {if (hashValue.length != HASH_SIZE *HASH_SIZE) {throw new IllegalArgumentException(String.format("length of hashValue must be %d", HASH_SIZE *HASH_SIZE));

}this.binaryzationMatrix =hashValue;

}publicFingerPrint(String hashValue) {this(toBytes(hashValue));

}publicFingerPrint(BufferedImage src) {this(hashValue(src));

}private static byte[] hashValue(BufferedImage src) {

BufferedImage hashImage=resize(src, HASH_SIZE, HASH_SIZE);byte[] matrixGray = (byte[]) toGray(hashImage).getData().getDataElements(0, 0, HASH_SIZE, HASH_SIZE, null);returnbinaryzation(matrixGray);

}/*** 从压缩格式指纹创建{@linkFingerPrint}对象

*

*@paramcompactValue

*@return

*/

public static FingerPrint createFromCompact(byte[] compactValue) {return newFingerPrint(uncompact(compactValue));

}public static boolean validHashValue(byte[] hashValue) {if (hashValue.length !=HASH_SIZE) {return false;

}for (byteb : hashValue) {

{if (0 != b && 1 !=b) {return false;

}

}

}return true;

}public static booleanvalidHashValue(String hashValue) {if (hashValue.length() !=HASH_SIZE) {return false;

}for (int i = 0; i < hashValue.length(); ++i) {if ('0' != hashValue.charAt(i) && '1' !=hashValue.charAt(i)) {return false;

}

}return true;

}public byte[] compact() {returncompact(binaryzationMatrix);

}/*** 指纹数据按位压缩

*

*@paramhashValue

*@return

*/

private static byte[] compact(byte[] hashValue) {byte[] result = new byte[(hashValue.length + 7) >> 3];byte b = 0;for (int i = 0; i < hashValue.length; ++i) {if (0 == (i & 7)) {

b= 0;

}if (1 ==hashValue[i]) {

b|= 1 << (i & 7);

}else if (hashValue[i] != 0) {throw new IllegalArgumentException("invalid hashValue,every element must be 0 or 1");

}if (7 == (i & 7) || i == hashValue.length - 1) {

result[i>> 3] =b;

}

}returnresult;

}/*** 压缩格式的指纹解压缩

*

*@paramcompactValue

*@return

*/

private static byte[] uncompact(byte[] compactValue) {byte[] result = new byte[compactValue.length << 3];for (int i = 0; i < result.length; ++i) {if ((compactValue[i >> 3] & (1 << (i & 7))) == 0) {

result[i]= 0;

}else{

result[i]= 1;

}

}returnresult;

}/*** 字符串类型的指纹数据转为字节数组

*

*@paramhashValue

*@return

*/

private static byte[] toBytes(String hashValue) {

hashValue= hashValue.replaceAll("\\s", "");byte[] result = new byte[hashValue.length()];for (int i = 0; i < result.length; ++i) {char c =hashValue.charAt(i);if ('0' ==c) {

result[i]= 0;

}else if ('1' ==c) {

result[i]= 1;

}else{throw new IllegalArgumentException("invalid hashValue String");

}

}returnresult;

}/*** 缩放图像到指定尺寸

*

*@paramsrc

*@paramwidth

*@paramheight

*@return

*/

private static BufferedImage resize(Image src, int width, intheight) {

BufferedImage result= newBufferedImage(width, height,

BufferedImage.TYPE_3BYTE_BGR);

Graphics g=result.getGraphics();try{

g.drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);

}finally{

g.dispose();

}returnresult;

}/*** 计算均值

*

*@paramsrc

*@return

*/

private static int mean(byte[] src) {long sum = 0;//将数组元素转为无符号整数

for (byteb : src) {

sum+= (long) b & 0xff;

}return (int) (Math.round((float) sum /src.length));

}/*** 二值化处理

*

*@paramsrc

*@return

*/

private static byte[] binaryzation(byte[] src) {byte[] dst =src.clone();int mean =mean(src);for (int i = 0; i < dst.length; ++i) {//将数组元素转为无符号整数再比较

dst[i] = (byte) (((int) dst[i] & 0xff) >= mean ? 1 : 0);

}returndst;

}/*** 转灰度图像

*

*@paramsrc

*@return

*/

private staticBufferedImage toGray(BufferedImage src) {if (src.getType() ==BufferedImage.TYPE_BYTE_GRAY) {returnsrc;

}else{//图像转灰

BufferedImage grayImage = newBufferedImage(src.getWidth(), src.getHeight(),

BufferedImage.TYPE_BYTE_GRAY);new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, grayImage);returngrayImage;

}

}

@OverridepublicString toString() {return toString(true);

}/***@parammultiLine 是否分行

*@return

*/

public String toString(booleanmultiLine) {

StringBuffer buffer= newStringBuffer();int count = 0;for (byte b : this.binaryzationMatrix) {

buffer.append(0 == b ? '0' : '1');if (multiLine && ++count % HASH_SIZE == 0) {

buffer.append('\n');

}

}returnbuffer.toString();

}

@Overridepublic booleanequals(Object obj) {if (obj instanceofFingerPrint) {return Arrays.equals(this.binaryzationMatrix, ((FingerPrint) obj).binaryzationMatrix);

}else{return super.equals(obj);

}

}/*** 与指定的压缩格式指纹比较相似度

*

*@paramcompactValue

*@return*@see#compare(FingerPrint)*/

public float compareCompact(byte[] compactValue) {returncompare(createFromCompact(compactValue));

}/***@paramhashValue

*@return*@see#compare(FingerPrint)*/

public floatcompare(String hashValue) {return compare(newFingerPrint(hashValue));

}/*** 与指定的指纹比较相似度

*

*@paramhashValue

*@return*@see#compare(FingerPrint)*/

public float compare(byte[] hashValue) {return compare(newFingerPrint(hashValue));

}/*** 与指定图像比较相似度

*

*@paramimage2

*@return*@see#compare(FingerPrint)*/

public floatcompare(BufferedImage image2) {return compare(newFingerPrint(image2));

}/*** 比较指纹相似度

*

*@paramsrc

*@return*@see#compare(byte[], byte[])*/

public floatcompare(FingerPrint src) {if (src.binaryzationMatrix.length != this.binaryzationMatrix.length) {throw new IllegalArgumentException("length of hashValue is mismatch");

}returncompare(binaryzationMatrix, src.binaryzationMatrix);

}/*** 判断两个数组相似度,数组长度必须一致否则抛出异常

*

*@paramf1

*@paramf2

*@return返回相似度(0.0 ~ 1.0)*/

private static float compare(byte[] f1, byte[] f2) {if (f1.length !=f2.length) {throw new IllegalArgumentException("mismatch FingerPrint length");

}int sameCount = 0;for (int i = 0; i < f1.length; ++i) {

{if (f1[i] ==f2[i]) {++sameCount;

}

}

}return (float) sameCount /f1.length;

}public static float compareCompact(byte[] f1, byte[] f2) {returncompare(uncompact(f1), uncompact(f2));

}public static floatcompare(BufferedImage image1, BufferedImage image2) {return new FingerPrint(image1).compare(newFingerPrint(image2));

}/***@paramargs

*@returnvoid

*@authorGuoyh

* @date 2018/10/12 15:07*/

public static void main(String[] args) throwsException {for (int i = 18; i <= 21; i++) {

FingerPrint fp1= new FingerPrint(ImageIO.read(new File("G:/oss/pk/" + 18 + ".jpg")));

FingerPrint fp2= new FingerPrint(ImageIO.read(new File("G:/oss/pk/" + i + ".jpg")));

System.out.println("\t" + "\t"+"G:/oss/pk/" + 18 + ".jpg"+"\t"+"与"+"\t"+"G:/oss/pk/" + i + ".jpg"+"\t"+"两张图片的相似度为:" + fp1.compare(fp2) * 100 + "%");

}

}

}

halcon 相似度_列举一些算法对照片、图像进行相似度对比分析比较相关推荐

  1. 向量点积衡量相似度_余弦距离、欧氏距离和杰卡德相似性度量的对比分析

    1.余弦距离 余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量. 向量,是多维空间中有方向的线段,如果两个向量的方向一致,即夹角接近零,那么这两个向量就 ...

  2. 列举一些算法对照片、图像进行相似度对比分析比较

    转:列举一些算法对照片.图像进行相似度对比分析比较 首先: 图片如下                                                    18.jpg        ...

  3. 【机器学习】聚类算法DBSCAN、K-means、Mean Shift对比分析及具体代码实现

    [机器学习]聚类算法DBSCAN.K-means.Mean Shift对比分析及具体代码实现 一.DBSCAN算法(具有噪声的基于密度的聚类方法) 1.算法原理 基于数据分布密度不同对数据进行聚类,把 ...

  4. jaccard相似度_如何计算两个字符串之间的文本相似度?

    推荐阅读: 面试BAT 却被小小字符串秒杀?这13道题帮你一举击败字符串算法题 字节跳动秋招面经:后端开发工程师,已拿意向书 前言 平时的编码中,我们经常需要判断两个文本的相似性,不管是用来做文本纠错 ...

  5. sklearn tfidf求余弦相似度_【基础算法 】文本相似度计算

    在自然语言处理中,文本相似度是一种老生常谈而又应用广泛的基础算法模块,可用于地址标准化中计算与标准地址库中最相似的地址,也可用于问答系统中计算与用户输入问题最相近的问题及其答案,还可用于搜索中计算与输 ...

  6. 如何计算环形复杂度_数据结构与算法复杂度

    数据结构 数据存储于内存时,决定了数据顺序和位置关系的便是数据结构.根据使用数据的目的选择合适的数据结构,可以提高内存的利用率. 链表 链表是数据结构之一,其中的数据呈线性排列.链表在内存中无需存储在 ...

  7. python将矩阵顺时针旋转90度_在Python中将方形矩阵逆时针旋转90度的程序

    假设我们有一个正方形矩阵,我们必须将其逆时针旋转90度.147 258 369 那么输出将是789 456 1个23 为了解决这个问题,我们将遵循以下步骤-如果矩阵为空,则返回一个空白列表 n:=矩阵 ...

  8. python word2vector计算相似度_使用word2vec计算词向量之间的相似度

    2018-12-01 回答 希望对你有帮助 开始背单词了,要注意什么呢?一下这几点从现在起,请牢记在心,并彻底贯彻. 第一条:狂听!可以精听,也可以泛听.精听是指专门拿出一段时间,每个词都要听见,每个 ...

  9. android 三星手机拍照旋转90度,解决三星拍照上传照片被旋转90度,和三星相机崩溃...

    刚刚想起来前几天面试的时候遇到的一个问题, 问题大概是这样的做拍照上传图片功能的时候,在三星手机上拍出的照片是旋转了90度的,应该如何解决这个问题.因为之前没有遇到过这种问题,当时我回答的是给图片做一 ...

最新文章

  1. pandas批量为列名添加字符并重命名实战
  2. linux升级Python2.7.12
  3. OpenVINO安装之安装openCL
  4. mysql 修改多表数据库_mysql数据库:mysql增删改、单表、多表及子查询
  5. Linux O(1)调度器
  6. C语言实例第8期:模拟银行账户登陆
  7. 源代码加密程序:.NET Reactor使用教程
  8. web前端——qq登录界面
  9. 东方联盟郭盛华发家史:8年来实现跨越式发展
  10. Javascript - The same RegExp behave differently
  11. 艾默生首席执行官范大为退休;液化空气将新建生产装置为京东方供应气体 | 美通企业日报...
  12. 【金猿产品展】EasyTwin——国产自研数字孪生融合渲染引擎
  13. PostgreSQL的学习心得和知识总结(五十三)|语法级自上而下完美实现MySQL数据库的 insert set 的实现方案
  14. java定义一个日期类 包括年 月 日_【说明】 设计一个日期类Date包括年、月、日等私有数据成员。要求实现日期..._考试资料网...
  15. 均分纸牌(线性、环形、二维)
  16. 【coolshell酷壳】你可能不知道的Shell
  17. updating java index_myeclipse右下角的updating indexes 是什么意思?
  18. 使用“已知明文攻击”破解加密
  19. 【女人吃豆腐的好处】
  20. Linux下安装tuned以使用tuned-adm命令优化Linux系统性能

热门文章

  1. mysql驱动源码解析_mysql驱动源码分析
  2. route add添加路由
  3. 地址对齐和非对齐是指什么?
  4. 车辆销售系统用例_销售模块用例图
  5. 【喜报】华为OD统一考试(B卷)题库清单(已收录161题),更快,更全的 B 卷题库大纲
  6. java 改变窗口颜色_java swing 设置窗口背景颜色
  7. Hadoop中NameNode和SecondaryNameNode、NN和2NN工作机制、Fsimage和Edits解析、oiv查看Fsimage、oev查看Edits、CheckPoint时间设置
  8. python除法取整数部分_python3 除法去掉小数,保留整数的做法
  9. ProxmoxVE下安装AdGuard
  10. 小草客户端android2.2.4 g,小草app安卓版2.2.3