001package net.gdface.sdk.fse;
002
003import java.nio.LongBuffer;
004import java.util.Arrays;
005import java.util.Comparator;
006
007import net.gdface.sdk.FseResult;
008import net.gdface.utils.BufferUtils;
009import net.gdface.utils.BinaryUtils;
010
011/**
012 * 特征码内存对象<br>
013 * 特征码内存JNI内存对象的Java层映射,
014 * 该类实现了{@link Comparable}接口,可以根据相似度结果字段({@link CodeBean#similarity})排序
015 * @author guyadong
016 *
017 */
018public  class CodeBean implements Comparable<CodeBean>{ 
019        /**
020         * 特征码ID,
021         * 特征码的MD5校验值(使用MD5保证特征码ID的唯一性)
022         */
023        public  byte[] id=null;
024        /**
025         * 人脸特征码(人脸模板)数据,数据长度与实际应用的算法相关
026         */
027        public byte[] code=null;
028        /**
029         * 当前特征码所属的图像的MD5校验值(图像ID),可为{@code null},
030         * 应用层也可将此字段根据业务需要解释为其他含义
031         */
032        public String imgMD5=null;
033        /**
034         * 相似度比较结果,该字段只在特征码搜索方法返回值中有效。用于当前存储人脸特征方法调用搜索返回结果.
035         * 代表当前特征码与输入搜索人脸特征的相似度比较值。
036         */
037        public double similarity=0;
038        
039        public CodeBean() {
040        }
041        public CodeBean(byte[] id, byte[] code, String imgMD5, Double similarity) {
042                this.id = id;
043                this.code = code;
044                this.imgMD5 = imgMD5;
045                if(similarity != null){
046                        this.similarity = similarity;
047                }
048        }
049        
050        @Override
051        public int hashCode() {
052                final int prime = 31;
053                int result = 1;
054                result = prime * result + Arrays.hashCode(code);
055                result = prime * result + Arrays.hashCode(id);
056                result = prime * result + ((imgMD5 == null) ? 0 : imgMD5.hashCode());
057                return result;
058        }
059        @Override
060        public boolean equals(Object obj) {
061                if (this == obj)
062                        return true;
063                if (obj == null)
064                        return false;
065                if (!(obj instanceof CodeBean))
066                        return false;
067                CodeBean other = (CodeBean) obj;
068                if (!Arrays.equals(code, other.code))
069                        return false;
070                if (!Arrays.equals(id, other.id))
071                        return false;
072                if (imgMD5 == null) {
073                        if (other.imgMD5 != null)
074                                return false;
075                } else if (!imgMD5.equals(other.imgMD5))
076                        return false;
077                return true;
078        }
079        @Override
080        public String toString() {
081                return toString(false);
082        }
083        public String toString(boolean full) {
084                String out=String.format("id=[%s],imgMD5=[%s],similarity=%f", BinaryUtils.toHex(id),imgMD5,similarity);
085                if(full){
086                        out+=String.format("\ncode:\n%s\n", null==code?"null":BinaryUtils.toHex(code));
087                }
088                return out;
089        }
090        @Override
091        public int compareTo(CodeBean o) {
092                double sub = similarity - o.similarity;
093                return sub > 0 ? 1 : (sub < 0 ? -1 : 0);
094        }
095
096        /**
097         * 将{@link #imgMD5}转为应用id(Long),如果{@link #imgMD5}为{@code null}则返回{@code null}
098         * @return
099         */
100        public Long appLongId(){
101                return asAppID(imgMD5);
102        }
103        /**
104         * 将{@link #imgMD5}转为应用id(Integer),如果{@link #imgMD5}为{@code null}则返回{@code null}
105         * @return
106         */
107        public Integer appIntId(){
108                Long l = asAppID(imgMD5);
109                return l == null ? null : l.intValue();
110        }
111        /**
112         * 用于相似度排序的{@link Comparator}实例
113         */
114        public static final Comparator<CodeBean> COMPARATOR = new Comparator<CodeBean>() {
115                @Override
116                public int compare(CodeBean o1, CodeBean o2) {
117                        return o1.compareTo(o2);
118                }
119        };
120        /**
121         * 将Long类型整数转为32位的字符串,用于 {@link #imgMD5}字段
122         * @param appid
123         * @return appid为{@code null}则返回{@code null}
124         */
125        public static String asImgMD5(long appid){
126                LongBuffer buffer = LongBuffer.allocate(2).put(0).put(appid);
127                return BinaryUtils.toHex(BufferUtils.asByteArray(buffer.array()));
128        }
129        /**
130         * 从{@link #imgMD5}字段返回Long类型整数,
131         * @param imgMD5 HEX格式(32字节长)的MD5
132         * @return imgMD5为{@code null}则返回{@code null}
133         */
134        public static Long asAppID(String imgMD5){
135                if(imgMD5 != null && imgMD5.getBytes().length == 32){                   
136                        return BufferUtils.asLongArray(BinaryUtils.hex2Bytes(imgMD5))[1];
137                }
138                return null;
139        }
140        public byte[] getId() {
141                return id;
142        }
143        public void setId(byte[] id) {
144                this.id = id;
145        }
146        public byte[] getCode() {
147                return code;
148        }
149        public void setCode(byte[] code) {
150                this.code = code;
151        }
152        public String getImgMD5() {
153                return imgMD5;
154        }
155        public void setImgMD5(String imgMD5) {
156                this.imgMD5 = imgMD5;
157        }
158        public double getSimilarity() {
159                return similarity;
160        }
161        public void setSimilarity(double similarity) {
162                this.similarity = similarity;
163        }
164        public static final FseResult[] toFseResult(CodeBean[] codeBeans){
165                if(codeBeans != null){
166                        FseResult[] result = new FseResult[codeBeans.length];
167                        for(int i =0;i<result.length;++i){
168                                result[i] = new FseResult(codeBeans[i].id, codeBeans[i].imgMD5, codeBeans[i].similarity);
169                        }
170                        return result;
171                }
172                return null;
173        }
174}