//package cc.mrbird.febs.mall.test; // //import javax.imageio.ImageIO; //import java.awt.*; //import java.awt.color.ColorSpace; //import java.awt.image.BufferedImage; //import java.awt.image.ColorConvertOp; //import java.io.File; //import java.io.IOException; //import java.util.Arrays; // ///** // * 图片是采用phash算法,一共分为四步吧. // * // * 1.将图片缩放到16*16大小,这是我们选择的合适的大小,假如宽高不一样,直接将其压到16*16,去掉细节,只保留宏观; // * // * 2.图片一共是16*16的,共256个像素,我们将图片进行灰度化,灰度化就是只有黑白灰三种,从白到黑,一共分了255层; // * // * 3.灰度化之后将图片进行DCT转换(离散余弦变化),因为为了识别有的图片旋转,这个DCT转换是将图片进行了一种压缩算法; // * // * 4.我们对这个算法进行了优化,因为之前是计算像素的均值,我们为了更准确,我们取RGB,rgb一共分为255个像素,我们将255个像素分为16段,如果像素大于0-16记为0,17到32记为1,直到255,这样就得到255位的二进制,这就是这张图片的指纹码. // * // * 得到唯一标识的指纹码之后怎么去计算像素度呢? // * // * 通过汉明距离比较两个二进制距离,如果距离小于<10的话,我们就判定两张图片相似.如果两个指纹码(二进制)一模一样,我们就判定两个是一张图片,或者类似; // */ ///** // * 视频相似度算法: // * 视频的话我们是通过ffmpeg(ff am pig),它是一个专门处理视频的框架,可以从视频中按针提取图片.然后就按照图片的相似度取对比了... // */ // ///** // * https://blog.csdn.net/weixin_34095889/article/details/91923072?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171652008316800182787012%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171652008316800182787012&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-91923072-null-null.142^v100^pc_search_result_base8&utm_term=java%20%E6%8A%8A%E5%9B%BE%E7%89%87%E8%BD%AC%E6%8D%A2%E6%88%90%E9%BB%91%E7%99%BD%E7%81%B0%E5%83%8F%E7%B4%A0%E9%A3%8E%E6%A0%BC&spm=1018.2226.3001.4187 // * 均值哈希实现图像指纹比较 // */ //public class FingerPrint { // // public static void main(String[] args) { // FingerPrint fp1 = null; // FingerPrint fp2 = null; // try { // fp1 = new FingerPrint(ImageIO.read(new File("D:\\image\\F1.png"))); // fp2 = new FingerPrint(ImageIO.read(new File("D:\\image\\Z1.jpg"))); // } catch (IOException e) { // e.printStackTrace(); // } // System.out.println(fp1.toString(false)); // System.out.println(fp2.toString(false)); // System.out.printf("sim=%f",fp1.compare(fp2)); // } // // /** // * 图像指纹的尺寸,将图像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; // } // public FingerPrint(String hashValue) { // this(toBytes(hashValue)); // } // public FingerPrint (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); // return binaryzation(matrixGray); // } // /** // * 从压缩格式指纹创建{@link FingerPrint}对象 // * @param compactValue // * @return // */ // public static FingerPrint createFromCompact(byte[] compactValue){ // return new FingerPrint(uncompact(compactValue)); // } // // public static boolean validHashValue(byte[] hashValue){ // if(hashValue.length!=HASH_SIZE) // return false; // for(byte b:hashValue){ // if(0!=b&&1!=b)return false; // } // return true; // } // public static boolean validHashValue(String 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){ // 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){ // 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){ // 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(obj instanceof FingerPrint){ // return Arrays.equals(this.binaryzationMatrix,((FingerPrint)obj).binaryzationMatrix); // }else // return super.equals(obj); // } // // /** // * 与指定的压缩格式指纹比较相似度 // * @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(BufferedImage image2){ // return compare(new FingerPrint(image2)); // } // /** // * 比较指纹相似度 // * @param src // * @return // * @see #compare(byte[], byte[]) // */ // public float compare(FingerPrint 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){ // if(f1.length!=f2.length) // throw new IllegalArgumentException("mismatch FingerPrint length"); // int sameCount=0; // for(int i=0;i