001/** 002 * 003 */ 004package net.gdface.sdk; 005import java.io.ByteArrayOutputStream; 006import java.io.PrintStream; 007/** 008 * @Title: CodeInfo.java 009 * @Package net.gdface.sdk 010 * @Description: 人脸信æ¯å˜å‚¨ç±» 011 * @author guyadong 012 * @date 2014-9-19 下åˆ3:37:24 013 * @version V1.0 014 */ 015import java.io.Serializable; 016import java.util.Arrays; 017 018/** 019 * 人脸特å¾ç ä¿¡æ¯æè¿°å¯¹è±¡<br> 020 * 包括人脸ä½ç½®,眼ç›ã€å˜´å·´,ã€é¼»åä½ç½®,人脸角度,特å¾ç æ•°æ® 021 * @author guyadong 022 * 023 */ 024public class CodeInfo implements Serializable { 025 /** 026 * 027 */ 028 private static final long serialVersionUID = 1L; 029 030 protected static final FInt2 ZERO_OFFSET = new FInt2(0,0); 031 /** 032 * 特å¾ç 数组 033 */ 034 private byte[] code; 035 /** 036 * 人脸ä½ç½®ä¿¡æ¯ï¼ˆç›¸å¯¹äºŽåŽŸå§‹å›¾åƒï¼‰ 037 */ 038 private FRect pos; 039 /** 040 * 眼ç›ä½ç½®ä¿¡æ¯ï¼ˆç›¸å¯¹äºŽåŽŸå§‹å›¾åƒï¼‰ 041 */ 042 private EyeInfo ei; 043 044 /** 045 * 嘴巴ä½ç½® 046 */ 047 private FInt2 mouth; 048 /** 049 * é¼»åä½ç½® 050 */ 051 private FInt2 nose; 052 /** 053 * 人脸角度 054 */ 055 private FAngle angle; 056 /** 057 * é¢éƒ¨æ•°æ® 058 */ 059 private byte[] facialData; 060 /** 061 * 人脸信æ¯åæ ‡åç§»é‡<br> 062 * æ¤å—æ®µå±žäºŽçŠ¶æ€æè¿°å—æ®µï¼Œä¸å±žäºŽäººè„¸ä¿¡æ¯ï¼Œ 063 * æ¤å—段ä¸ä¸º{@code null}时用于æè¿°å½“å‰äººè„¸ä¿¡æ¯å¯¹è±¡ä¸æ‰€æœ‰çš„åæ ‡æ•°æ®çš„原点相对实际原点的åç§»é‡ 064 */ 065 private FInt2 offset; 066 public CodeInfo() { 067 this(null,null,null,null,null,null, null); 068 } 069 070 public CodeInfo(byte[] code, FRect pos, EyeInfo ei, FInt2 mouth, FInt2 nose, FAngle angle, byte[] facialData) { 071 this.code = code; 072 this.pos = pos; 073 this.ei = ei; 074 this.mouth = mouth; 075 this.nose = nose; 076 this.angle = angle; 077 this.facialData=facialData; 078 } 079 080 public byte[] getCode() { 081 return code; 082 } 083 084 /** 085 * @return the ei 086 */ 087 public EyeInfo getEi() { 088 return ei; 089 } 090 091 public FRect getPos() { 092 return pos; 093 } 094 095 public void setCode(byte[] code) { 096 this.code = code; 097 } 098 099 /** 100 * @param ei the ei to set 101 */ 102 public void setEi(EyeInfo ei) { 103 this.ei = ei; 104 } 105 106 public void setPos(FRect pos) { 107 this.pos = pos; 108 } 109 110 /** 111 * @return mouth 112 */ 113 public FInt2 getMouth() { 114 return mouth; 115 } 116 117 /** 118 * @param mouth è¦è®¾ç½®çš„ mouth 119 */ 120 public void setMouth(FInt2 mouth) { 121 this.mouth = mouth; 122 } 123 124 /** 125 * @return nose 126 */ 127 public FInt2 getNose() { 128 return nose; 129 } 130 131 /** 132 * @param nose è¦è®¾ç½®çš„ nose 133 */ 134 public void setNose(FInt2 nose) { 135 this.nose = nose; 136 } 137 138 /** 139 * @return angle 140 */ 141 public FAngle getAngle() { 142 return angle; 143 } 144 145 /** 146 * @param angle è¦è®¾ç½®çš„ angle 147 */ 148 public void setAngle(FAngle angle) { 149 this.angle = angle; 150 } 151 152 /** 153 * @return facialData 154 */ 155 public byte[] getFacialData() { 156 return facialData; 157 } 158 159 /** 160 * @param facialData è¦è®¾ç½®çš„ facialData 161 */ 162 public void setFacialData(byte[] facialData) { 163 this.facialData = facialData; 164 } 165 /** 166 * 人脸信æ¯åæ ‡åç§»é‡<br> 167 * æ¤å—æ®µå±žäºŽçŠ¶æ€æè¿°å—æ®µï¼Œä¸æ˜¯å±žäºŽäººè„¸ä¿¡æ¯éƒ¨åˆ†ï¼Œ 168 * æ¤å—段ä¸ä¸º{@code null}时用于æè¿°å½“å‰äººè„¸ä¿¡æ¯å¯¹è±¡ä¸æ‰€æœ‰çš„åæ ‡æ•°æ®çš„原点相对实际原点的åç§»é‡ 169 * @return åç§»é‡å¯¹è±¡ï¼Œä¸º{@code null}æ— å移或å移为0 170 */ 171 public FInt2 getOffset() { 172 return offset; 173 } 174 175 public void setOffset(FInt2 offset) { 176 this.offset = offset; 177 } 178 public CodeInfo withOffset(int x,int y) { 179 setOffset(new FInt2(x, y)); 180 return this; 181 } 182 /** 183 * 将当å‰äººè„¸ä½ç½®å¯¹è±¡ä¸çš„åæ ‡æ•°æ®æ ¹æ®åç§»åæ ‡({@link #offset})釿–°å®šä½<br> 184 * æ‰€æœ‰æ°´å¹³åæ ‡ - offset.x<br> 185 * æ‰€æœ‰åž‚ç›´åæ ‡ - offset.y<br> 186 * è¿”å›žé‡æ–°å®šä½çš„当å‰å¯¹è±¡ 187 * @return è¿”å›žé‡æ–°å®šä½çš„当å‰å¯¹è±¡ 188 */ 189 public final CodeInfo relocate(){ 190 if(null != offset && !ZERO_OFFSET.equals(offset) ){ 191 int x = offset.getX(); 192 int y = offset.getY(); 193 if(null != pos){ 194 pos.setLeft(pos.getLeft() - x); 195 pos.setTop(pos.getTop() - y); 196 } 197 if(null != ei){ 198 ei.setLeftAndRight(ei.getLeftx() - x, ei.getLefty() - y, ei.getRightx() - x, ei.getRighty() - y); 199 } 200 if(null != mouth){ 201 mouth.setX(mouth.getX() - x); 202 mouth.setY(mouth.getY() - y); 203 } 204 if(null != nose){ 205 nose.setX(nose.getX() - x); 206 nose.setY(nose.getY() - y); 207 } 208 relocateFacialData(); 209 // 完æˆé‡å®šä½åŽå°† offset 置为null 210 offset = null; 211 } 212 return this; 213 } 214 /** 215 * 对é¢éƒ¨æ•°æ®é‡æ–°å®šä½<br> 216 * 默认实现对é¢éƒ¨æ•°æ®({@link #facialData})ä¸åšä»»ä½•修改,åç±»å¯é‡å†™æ¤æ–¹æ³• 217 */ 218 protected void relocateFacialData(){ 219 // DO NOTHING 220 } 221 @Override 222 public String toString() { 223 ByteArrayOutputStream bo = new ByteArrayOutputStream(); 224 toStream(new PrintStream(bo)); 225 return bo.toString(); 226 } 227 /** 228 * 以文本形å¼å‘{@link PrintStream}输出对象内容 229 * @param stream 230 */ 231 public void toStream(PrintStream stream) { 232 stream.printf("[pos=%s,ei=%s,mouth=%s,nose=%s,angle=%s,offset=%s,code.length=%s,facialData.length=%s]" 233 ,this.pos,this.ei,this.mouth,this.nose,this.angle,this.offset 234 ,null==code?"null":Integer.toString(code.length) 235 ,null==facialData?"null":Integer.toString(facialData.length)); 236 } 237 238 @Override 239 public int hashCode() { 240 final int prime = 31; 241 int result = 1; 242 result = prime * result + ((angle == null) ? 0 : angle.hashCode()); 243 result = prime * result + Arrays.hashCode(code); 244 result = prime * result + ((ei == null) ? 0 : ei.hashCode()); 245 result = prime * result + Arrays.hashCode(facialData); 246 result = prime * result + ((mouth == null) ? 0 : mouth.hashCode()); 247 result = prime * result + ((nose == null) ? 0 : nose.hashCode()); 248 result = prime * result + ((pos == null) ? 0 : pos.hashCode()); 249 return result; 250 } 251 252 @Override 253 public boolean equals(Object obj) { 254 if (this == obj) { 255 return true; 256 } 257 if (obj == null) { 258 return false; 259 } 260 if (!(obj instanceof CodeInfo)) { 261 return false; 262 } 263 CodeInfo other = (CodeInfo) obj; 264 if (angle == null) { 265 if (other.angle != null) { 266 return false; 267 } 268 } else if (!angle.equals(other.angle)) { 269 return false; 270 } 271 if (!Arrays.equals(code, other.code)) { 272 return false; 273 } 274 if (ei == null) { 275 if (other.ei != null) { 276 return false; 277 } 278 } else if (!ei.equals(other.ei)) { 279 return false; 280 } 281 if (!Arrays.equals(facialData, other.facialData)) { 282 return false; 283 } 284 if (mouth == null) { 285 if (other.mouth != null) { 286 return false; 287 } 288 } else if (!mouth.equals(other.mouth)) { 289 return false; 290 } 291 if (nose == null) { 292 if (other.nose != null) { 293 return false; 294 } 295 } else if (!nose.equals(other.nose)) { 296 return false; 297 } 298 if (pos == null) { 299 if (other.pos != null) { 300 return false; 301 } 302 } else if (!pos.equals(other.pos)) { 303 return false; 304 } 305 return true; 306 } 307}