KKSU
2024-08-22 7a372033d44ba48383d9d1bc97e5d583b26a266f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
//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<hashValue.length();++i){
//            if('0'!=hashValue.charAt(i)&&'1'!=hashValue.charAt(i))return false;
//        }
//        return true;
//    }
//    public byte[] compact(){
//        return compact(binaryzationMatrix);
//    }
//
//    /**
//     * 指纹数据按位压缩
//     * @param hashValue
//     * @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;
//            }
//        }
//        return result;
//    }
//
//    /**
//     * 压缩格式的指纹解压缩
//     * @param compactValue
//     * @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;
//        }
//        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<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");
//        }
//        return result;
//    }
//    /**
//     * 缩放图像到指定尺寸
//     * @param src
//     * @param width
//     * @param height
//     * @return
//     */
//    private static BufferedImage resize(Image src,int width,int height){
//        BufferedImage result = new BufferedImage(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();
//        }
//        return result;
//    }
//    /**
//     * 计算均值
//     * @param src
//     * @return
//     */
//    private static  int mean(byte[] src){
//        long sum=0;
//        // 将数组元素转为无符号整数
//        for(byte b:src)sum+=(long)b&0xff;
//        return (int) (Math.round((float)sum/src.length));
//    }
//    /**
//     * 二值化处理
//     * @param src
//     * @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);
//        }
//        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<f1.length;++i){
//            if(f1[i]==f2[i])++sameCount;
//        }
//        return (float)sameCount/f1.length;
//    }
//    public static float compareCompact(byte[] f1,byte[] f2){
//        return compare(uncompact(f1),uncompact(f2));
//    }
//    public static float compare(BufferedImage image1,BufferedImage image2){
//        return new FingerPrint(image1).compare(new FingerPrint(image2));
//    }
//
//}