All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.image.Fingerprint Maven / Gradle / Ivy

There is a newer version: 2.10.3
Show newest version
package net.gdface.image;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.util.Arrays;

import net.gdface.utils.Assert;
import net.gdface.utils.FaceUtilits;
import net.gdface.utils.Judge;

/**
 * 均值哈希实现图像指纹比较,用于比较两个图像的内容的相似度
 * @author guyadong
 *
 */
public final class Fingerprint {
	/**
	 * 图像指纹的尺寸,将图像resize到指定的尺寸,来计算哈希数组 
	 */
	private static final int HASH_SIZE=16;
	/**
	 * 保存图像指纹的二值化矩阵
	 */
	private final byte[] binaryzationMatrix;
	public Fingerprint(byte[] hashValue) {
		Assert.notEmpty(hashValue, "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;
	}
	public Fingerprint(String hashValue) {
		this(toBytes(hashValue));
	}
	public Fingerprint (Image src){
		this(hashValue(src));
	}
	private static byte[] hashValue(Image src){
		Assert.notNull(src, "src");
		BufferedImage hashImage = resize(src,HASH_SIZE,HASH_SIZE);
		byte[] matrixGray = (byte[]) toGray(hashImage).getData().getDataElements(0, 0, HASH_SIZE, HASH_SIZE, null);	
		return  binaryzation(matrixGray);
	}
	public static  Fingerprint createFromImage(T src) throws UnsupportedFormatException, NotImageException{
		return  null==src?null:new Fingerprint(LazyImage.create(src).read(null, null));	
	}
	public static  Fingerprint createFromImageNoThrow(T src) {
		try {
			return  createFromImage(src);
		} catch (UnsupportedFormatException e) {
			throw new RuntimeException(e);
		} catch (NotImageException e) {
			throw new RuntimeException(e);
		}	
	}
	/**
	 * 从压缩格式指纹创建{@link Fingerprint}对象
	 * @param compactValue
	 * @return
	 */
	public static Fingerprint createFromCompact(byte[] compactValue){
		return Judge.isEmpty(compactValue)?null:new Fingerprint(uncompact(compactValue));
	}
	/**
	 * @param compactValueHex
	 * @return
	 * @see #createFromCompact(byte[])
	 */
	public static Fingerprint createFromCompact(String compactValueHex){
		return Judge.isEmpty(compactValueHex)?null:new Fingerprint(uncompact(FaceUtilits.hex2Bytes(compactValueHex)));
	}
	/**
	 * 验证是否为有效的指纹数据
	 * @param hashValue
	 * @return
	 */
	public static boolean validHashValue(byte[] hashValue){
		Assert.notEmpty(hashValue, "hashValue");
		if(hashValue.length!=HASH_SIZE)
			return false;
		for(byte b:hashValue){
			if(0!=b&&1!=b)return false;			
		}
		return true;
	}
	/**
	 * @param hashValue
	 * @return
	 * @see #validHashValue(byte[])
	 */
	public static boolean validHashValue(String hashValue){
		Assert.notEmpty(hashValue, "hashValue");
		if(hashValue.length()!=HASH_SIZE)
			return false;
		for(int i=0;i>3];
		byte b=0;
		for(int i=0;i>3]=b;
			}
		}
		return result;
	}

	/**
	 * 压缩格式的指纹解压缩
	 * @param compactValue
	 * @return
	 */
	private static byte[] uncompact(byte[] compactValue){
		Assert.notEmpty(compactValue, "compactValue");
		byte[] result=new byte[compactValue.length<<3];
		for(int i=0;i>3]&(1<<(i&7)))==0)
				result[i]=0;
			else
				result[i]=1;
		}
		return result;		
	}
	/**
	 * 字符串类型的指纹数据转为字节数组
	 * @param hashValue
	 * @return
	 */
	private static byte[] toBytes(String hashValue){
		Assert.notEmpty(hashValue, "hashValue");
		hashValue=hashValue.replaceAll("\\s", "");
		byte[] result=new byte[hashValue.length()];
		for(int i=0;i=mean?1:0);
		}
		return dst;
		
	}
	/**
	 * 转灰度图像
	 * @param src
	 * @return
	 */
	private static BufferedImage toGray(BufferedImage src){
		Assert.notNull(src, "src");
		if(src.getType()==BufferedImage.TYPE_BYTE_GRAY){
			return src;
		}else{
			// 图像转灰
			BufferedImage grayImage = new BufferedImage(src.getWidth(), src.getHeight(),  
	                BufferedImage.TYPE_BYTE_GRAY);
			new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, grayImage);
		    return grayImage;		
		}
	}

	@Override
	public String toString() {
		return toString(true);
	}
	/**
	 * @param multiLine 是否分行
	 * @return
	 */
	public String toString(boolean multiLine) {
		StringBuffer buffer=new StringBuffer();
		int count=0;
		for(byte b:this.binaryzationMatrix){
			buffer.append(0==b?'0':'1');
			if(multiLine&&++count%HASH_SIZE==0)
				buffer.append('\n');
		}
		return buffer.toString();
	}
	@Override
	public boolean equals(Object obj) {
		if(super.equals(obj))
			return true;
		if(obj instanceof Fingerprint)
			return Arrays.equals(this.binaryzationMatrix,((Fingerprint)obj).binaryzationMatrix);
		else
			return false;
	}

	/**
	 * 与指定的压缩格式指纹比较相似度
	 * @param compactValue
	 * @return
	 * @see #compare(Fingerprint)
	 */
	public float compareCompact(byte[] compactValue){
		return compare(createFromCompact(compactValue));
	}
	/**
	 * @param hashValue
	 * @return
	 * @see #compare(Fingerprint)
	 */
	public float compare(String hashValue){
		return compare(new Fingerprint(hashValue));
	}
	/**
	 * 与指定的指纹比较相似度
	 * @param hashValue
	 * @return
	 * @see #compare(Fingerprint)
	 */
	public float compare(byte[] hashValue){
		return compare(new Fingerprint(hashValue));
	}
	/**
	 * 与指定图像比较相似度
	 * @param image2
	 * @return
	 * @see #compare(Fingerprint)
	 */
	public float compare(Image image2){
		return compare(new Fingerprint(image2));
	}
	/**
	 * 比较指纹相似度
	 * @param src
	 * @return 
	 * @see #compare(byte[], byte[])
	 */
	public float compare(Fingerprint src){
		Assert.notNull(src, "src");
		if(src.binaryzationMatrix.length!=this.binaryzationMatrix.length)
			throw new IllegalArgumentException("length of hashValue is mismatch");
		return compare(binaryzationMatrix,src.binaryzationMatrix);
	}
	/**
	 * 判断两个数组相似度,数组长度必须一致否则抛出异常
	 * @param f1
	 * @param f2
	 * @return 返回相似度(0.0~1.0)
	 */
	private static float compare(byte[] f1,byte[] f2){
		Assert.notEmpty(f1, "f1");
		Assert.notEmpty(f2, "f2");
		if(f1.length!=f2.length)
			throw new IllegalArgumentException("mismatch FingerPrint length");
		int sameCount=0;
		for(int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy