001package net.gdface.sdk; 002 003import java.io.File; 004import java.io.InputStream; 005import java.net.URL; 006import java.nio.ByteBuffer; 007import java.util.List; 008import java.util.Map; 009 010import net.gdface.annotation.DeriveMethod; 011import net.gdface.annotation.GenericParam; 012import net.gdface.image.ImageErrorException; 013import net.gdface.image.MatType; 014 015/** 016 * 017 * 人脸识别SDK核心接口<br> 018 * 此接口中mat前缀的方法图像数据参数为图像矩阵(要求图像宽高必须为偶数), 019 * 其他方法中所有byte[]类型的图像参数都指未解码的图像格式(如jpg,bmp,png...),<br> 020 * 目前支持的图像格式类型依赖于JDK的支持能力 021 * @author guyadong 022 */ 023public interface FaceApi { 024 025 /** 026 * 对人脸图像提取特征码,返回比较相似度结果<br> 027 * imgData1和imgData2相等或imgData2为{@code null}时,即比较同一张图像中的两张人脸的相似度 028 * 调用该方法时假设图像({@code imgData1}和{@code imgData2})能正常解码,<br> 029 * 所以当对图像解码出现异常时,将{@link ImageErrorException}异常对象封装到{@link RuntimeException}抛出<br> 030 * 任何参数为{@code null}则抛出{@link IllegalArgumentException} 031 * @param imgData1 032 * 图像1数据(jpg,png...)字节数组 033 * @param facePos1 034 * 检测到的人脸/眼睛位置 035 * @param imgData2 036 * 图像1数据(jpg,png...)字节数组 037 * @param facePos2 038 * 检测到的人脸/眼睛位置 039 * @return 两张人脸之间的相似度(0.0~1) 040 * @throws NotFaceDetectedException 041 * @throws ImageErrorException 042 * @see #getCodeInfo(byte[], int, CodeInfo[]) 043 * @see #compareCode(byte[], byte[]) 044 */ 045 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 046 public abstract double compare2Face( 047 @GenericParam(name="T1")byte[] imgData1, 048 CodeInfo facePos1, 049 @GenericParam(name="T2")byte[] imgData2, 050 CodeInfo facePos2) 051 throws NotFaceDetectedException, ImageErrorException; 052 053 /** 054 * 对两个图像指定范围({@link FRect})进行人脸检测,找到并提取唯一的人脸特征码,然后比较相似度,返回相似度结果<br> 055 * imgData1和imgData2相等或imgData2为{@code null}时, 056 * 即比较同一张图像中的两张人脸的相似度,这种情况下detectRect1和detectRect2都不能为{@code null}<br> 057 * imgData1和imgData2不相等且都不为{@code null}时,detectRect1和detectRect2被忽略 058 * 059 * @param imgData1 060 * 图像1数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 061 * @param detectRect1 062 * 图片检测范围,为null时全图检测 063 * @param imgData2 064 * 图像2数据(jpg,png...)字节数组 065 * @param detectRect2 066 * 图片检测范围,为null时全图检测 067 * @return 两张人脸之间的相似度(0.0~1) 068 * @throws ImageErrorException 069 * @throws NotFaceDetectedException 070 * @see #detectAndGetCodeInfo(byte[], int) 071 * @see #compareCode(byte[], byte[]) 072 */ 073 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 074 public abstract double detectAndCompare2Face( 075 @GenericParam(name="T1")byte[] imgData1, 076 FRect detectRect1, 077 @GenericParam(name="T2")byte[] imgData2, 078 FRect detectRect2) 079 throws ImageErrorException, NotFaceDetectedException; 080 081 /** 082 * 特征码比对<br> 083 * 参数为{@code null}或长度不一致则抛出{@link IllegalArgumentException}异常,返回两个特征码之间的相似度(0.0~1) 084 * @param code1 待比对的特征码 085 * @param code2 待比对的特征码 086 * @return 相似度(0.0~1) 087 */ 088 public abstract double compareCode(@GenericParam(name="T1")byte[] code1, @GenericParam(name="T2")byte[] code2); 089 090 /** 091 * 特征码比对1:N<br> 092 * 返回对应的特征码相似度数组 093 * @param code1 待比对的特征码 094 * @param codes 包含人脸特征的{@link CodeInfo }数组 095 * @return 特征码相似度数组 096 */ 097 public abstract double[] compareCodes(byte[] code1, CodeInfo[] codes); 098 /** 099 * 特征码比对1:N<br> 100 * 对{@code imgData}图像数据检测人脸并提取特征,然后与{@code code}特征进行比对, 101 * 返回包含比对相似度结果的{@link CompareResult}实例 102 * @param code 人脸特征数据 103 * @param imgData 待比对的图像(jpg,png...)(可能有多张人脸) 104 * @param faceNum 参见 {@link #getCodeInfo(byte[], int, CodeInfo[])} 105 * @return {@link CompareResult}实例 106 * @throws NotFaceDetectedException 没有检测到人脸 107 * @throws ImageErrorException 108 * @see #compareCodes(byte[], CodeInfo[]) 109 * @see #detectAndGetCodeInfo(byte[], int) 110 */ 111 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 112 CompareResult compareFaces( 113 @GenericParam(name="T1")byte[] code, 114 @GenericParam(name="T2")byte[] imgData, 115 int faceNum) 116 throws NotFaceDetectedException, ImageErrorException; 117 118 /** 119 * 特征码比对1:N<br> 120 * @param code1 人脸特征数据 121 * @param codes 一组人脸特征 122 * @return 返回对应的特征码相似度列表 123 */ 124 public abstract List<Double> compareFeatures(byte[] code1, List<byte[]> codes); 125 126 /** 127 * 先对图像数据{@code imgData}进行人脸检测,然后提取人脸特征码<br> 128 * 返回所有成功提取特征码的{@link CodeInfo}数组, 129 * 与{@link #getCodeInfo(byte[], int, CodeInfo[])}的返回结果有差别,返回结果中不包含检测到人脸但提取特征码失败的对象 130 * @param imgData 131 * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 132 * @param faceNum 133 * 参见 {@link #getCodeInfo(byte[], int, CodeInfo[])} 134 * @return {@link CodeInfo}数组<br> 135 * @throws ImageErrorException 136 * @throws NotFaceDetectedException 没有检测人脸或提取到特征码的人脸数目不是要求的人脸数目(faceNum>0) 137 */ 138 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 139 public abstract CodeInfo[] detectAndGetCodeInfo(byte[] imgData, int faceNum) 140 throws ImageErrorException, NotFaceDetectedException; 141 /** 142 * 检测指定的人脸是否戴口罩<br> 143 * 返回值有三种状态: 144 * <ul> 145 * <li>{@code true} 戴口罩返回</li> 146 * <li>{@code false} 未戴口罩返回</li> 147 * <li>{@code null} 不知道</li> 148 * </ul> 149 * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException} 150 * @param faceInfo 可见光图像人脸信息 151 * @return 返回口罩检测结果 152 * @throws ImageErrorException 153 * @since 2.1.9 154 */ 155 public Boolean wearMask(byte[] imgData, CodeInfo faceInfo) throws ImageErrorException; 156 157 /** 158 * 对图像({@code imgData})进行人脸检测,返回人脸位置数据对象{@link CodeInfo}数组<br> 159 * 没有检测到人脸则返回空数组 160 * @param imgData 161 * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 162 * @return {@link CodeInfo}数组 163 * @throws ImageErrorException 图像读取错误 164 */ 165 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 166 public abstract CodeInfo[] detectFace(byte[] imgData) throws ImageErrorException; 167 168 /** 169 * 检测最中心的人脸<br> 170 * 返回人脸位置数据对象{@link CodeInfo} 171 * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 172 * @return {@link CodeInfo} 173 * @throws NotFaceDetected 没有检测到人脸 174 * @throws ImageError 图像读取错误 175 */ 176 public CodeInfo detectCenterFace(byte[] imgData) throws NotFaceDetectedException, ImageErrorException; 177 /** 178 * 检测最大的人脸<br> 179 * 返回人脸位置数据对象{@link CodeInfo} 180 * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 181 * @return {@link CodeInfo} 182 * @throws NotFaceDetected 没有检测到人脸 183 * @throws ImageError 图像读取错误 184 */ 185 public CodeInfo detectMaxFace(byte[] imgData) throws NotFaceDetectedException, ImageErrorException; 186 187 /** 188 * 根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br> 189 * 与 {@link #detectAndGetCodeInfo(byte[], int)}不同, 本方法不对图像数据{@code imgData}进行人脸检测,<br> 190 * 假设{@code facePos}是 {@link #detectFace(byte[])}或 {@link #detectFaceAgain(byte[], FRect[])} 的返回结果<br> 191 * 返回facePos,如果没有提取到特征码,则对应元素{@link CodeInfo#getCode()}返回{@code null} 192 * @param imgData 193 * 图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException} 194 * @param faceNum 195 * 要求返回的人脸特征码数目<br> 196 * 大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br> 197 * 小于等于0时,返回所有提取到到人脸特征码 198 * @param facePos 199 * 检测到的人脸位置对象列表<br> 200 * 为{@code null}或数组长度为0时抛出{@link IllegalArgumentException}<br> 201 * 如果元素为{@code null},则跳过<br> 202 * @return 返回facePos 203 * @throws NotFaceDetectedException 提取特征码的人脸数目为0或没有提取到指定数目(faceNum大于0时)的特征码 204 */ 205 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 206 public abstract CodeInfo[] getCodeInfo(byte[] imgData, int faceNum, CodeInfo[] facePos) throws NotFaceDetectedException; 207 208 /** 209 * 根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br> 210 * 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null} 211 * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException} 212 * @param facePos 人脸位置信息对象,为{@code null}则抛出异常 213 * @return {@link CodeInfo} or {@code null} 214 */ 215 @DeriveMethod(methodSuffix="Single",localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 216 public CodeInfo getCodeInfo(byte[] imgData, CodeInfo facePos); 217 218 /** 219 * 多张人脸提取特征(用于多张人脸合成一个特征的算法)<br> 220 * 返回人脸特征数据 221 * {@link #multiFaceFeature()}返回{@code false}时代表此方法未被实现,执行会抛出异常 222 * @param faces 人脸图像数据(jpg,png...)与人脸位置信息对象的映射 223 * @return 人脸特征数据 224 * @throws NotFaceDetectedException 225 */ 226 public abstract byte[] getFeature(Map<ByteBuffer,CodeInfo>faces) throws NotFaceDetectedException; 227 /** 228 * 判断图像是否能提取到人脸特征码<br> 229 * 为{@code true}则能检测到人脸并能提取特征码 230 * @param imgData 231 * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 232 * @return 为{@code true}则能检测到人脸并能提取特征码 233 * @throws ImageErrorException 234 * @see #detectAndGetCodeInfo(byte[], int) 235 */ 236 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 237 public abstract boolean hasFace(byte[] imgData) throws ImageErrorException; 238 239 /** 240 * 1:N 人脸特征搜索<br> 241 * 搜索与{@code code}相似度大于{@code similarty}的记录(最多返回前{@code rows}个结果)<br> 242 * 返回包含相似度计算结果的{@link FseResult}数组,返回结果以相似度降序排列<br> 243 * 相似度值通过 {@link FseResult#getSimilartys()} 获取<br> 244 * 对应的人脸特征ID由 {@link FseResult#getFeatureIds()}获取 245 * @param feature 246 * 要搜索的特征码 247 * @param similarty 248 * 相似度阀值 249 * @param rows 250 * 最多返回的记录数目 251 * @return 包含相似度计算结果的{@link FseResult}数组<br> 252 * @since 3.0.0 253 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持 254 */ 255 public FseResult[] searchFeatures(byte[] feature, double similarty, int rows); 256 257 /** 258 * 1:N 人脸图像搜索<br> 259 * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br> 260 * 返回包含相似度计算结果的FseResult数组<br> 261 * 相似度值通过 FseResult.getSimilartys() 获取<br> 262 * 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br> 263 * 264 * @param imgData 265 * 图片字节数组 266 * @param facePos 267 * 人脸位置对象<br> 268 * 为{@code null}时,先做人脸检测再提取特征码<br> 269 * 不为{@code null}时,直接在指定的位置提取特征码<br> 270 * @param similarty 相似度阀值 271 * @param rows 最多返回的记录数目 272 * @return 包含相似度计算结果的{@link FseResult}数组<br> 273 * @since 3.0.0 274 * @throws NotFaceDetectedException - 275 * @throws ImageErrorException - 276 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持 277 * @see #getCodeInfo(byte[], int, CodeInfo[]) 278 * @see #searchFeatures(byte[], double, int) 279 */ 280 @DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class}) 281 public FseResult[] searchFaces(byte[] imgData, CodeInfo facePos, double similarty, int rows) throws NotFaceDetectedException, ImageErrorException; 282 283 /** 284 * 对图像矩阵进行人脸检测<br> 285 * 返回人脸信息对象列表,没有检测到人脸返回空表 286 * @param matType 图像矩阵类型 287 * @param matData 图像矩阵 288 * @param width 图像宽度 289 * @param height 图像高度 290 * @return 人脸信息对象列表 291 * @since 2.1.9 292 */ 293 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 294 public CodeInfo[] matDetectFace(MatType matType, byte[] matData, int width, int height); 295 /** 296 * 检测最大的人脸<br> 297 * 返回人脸位置数据对象{@link CodeInfo} 298 * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException} 299 * @return {@link CodeInfo} 300 * @throws NotFaceDetected 没有检测到人脸 301 * @since 2.1.9 302 */ 303 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 304 public CodeInfo matDetectMaxFace(MatType matType, byte[] matData, int width, int height) throws NotFaceDetectedException; 305 /** 306 * 根据{@code facePos}提供的人脸信息位置, 在图像矩阵中提取特征码<br> 307 * 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null} 308 * @param matType 图像矩阵类型 309 * @param matData 图像矩阵 310 * @param width 图像宽度 311 * @param height 图像高度 312 * @param facePos 人脸位置信息对象,为{@code null}则抛出异常 313 * @return {@link CodeInfo} or {@code null} 314 */ 315 @DeriveMethod(methodSuffix="Single",localResolvedTypes={ByteBuffer.class}) 316 public CodeInfo matGetCodeInfo(MatType matType, byte[] matData, int width, int height, CodeInfo facePos); 317 318 /** 319 * 根据facePos提供的人脸信息位置, 在图像矩阵中提取特征码<br> 320 * 包含人脸特征数据的facePos 321 * @param matType 图像矩阵类型 322 * @param matData 图像矩阵 323 * @param width 图像宽度 324 * @param height 图像高度 325 * @param facenum 326 * 要求返回的人脸特征码数目<br> 327 * 大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br> 328 * 小于等于0时,返回所有提取到到人脸特征码 329 * @param facePos 人脸位置信息对象,不可为{@code null} 330 * @return always facePos 331 * @throws NotFaceDetectedException 提取特征码的人脸数目为0或没有提取到指定数目(faceNum大于0时)的特征码 332 * @since 2.1.9 333 */ 334 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 335 public CodeInfo[] matGetCodeInfo(MatType matType, byte[] matData, int width, int height, int facenum, CodeInfo[] facePos) throws NotFaceDetectedException; 336 /** 337 * 先对图像矩阵数据{@code imgData}进行人脸检测,然后提取人脸特征码<br> 338 * 返回包含人脸特征数据的{@code CodeInfo}数组 339 * @param matType 图像矩阵类型 340 * @param matData 图像矩阵 341 * @param width 图像宽度 342 * @param height 图像高度 343 * @param faceNum 参见 {@link #getCodeInfo(byte[], int, CodeInfo[])} 344 * @return {@code CodeInfo}数组 345 * @throws NotFaceDetectedException 346 * @since 2.1.9 347 */ 348 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 349 public CodeInfo[] matDetectAndGetCodeInfo(MatType matType, byte[] matData, int width, int height, int faceNum) throws NotFaceDetectedException; 350 /** 351 * 检测指定的人脸是否戴口罩<br> 352 * 返回值有三种状态: 353 * <ul> 354 * <li>{@code true} 戴口罩返回</li> 355 * <li>{@code false} 未戴口罩返回</li> 356 * <li>{@code null} 不知道</li> 357 * </ul> 358 * @param matType 图像矩阵类型 359 * @param matData 图像矩阵 360 * @param width 图像宽度 361 * @param height 图像高度 362 * @param faceInfo 人脸位置信息 363 * @return 返回口罩检测结果 364 * @since 2.1.9 365 */ 366 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 367 public Boolean matWearMask(MatType matType, byte[] matData, int width, int height, CodeInfo faceInfo); 368 /** 369 * 判断图像矩阵是否能提取到人脸特征码<br> 370 * 返回为{@code true}则能检测到人脸并能提取特征码 371 * @param matType 图像矩阵类型 372 * @param matData 图像矩阵,为{@code null}则抛出{@link IllegalArgumentException} 373 * @param width 图像宽度 374 * @param height 图像高度 375 * @return 为{@code true}则能检测到人脸并能提取特征码 376 * @since 2.1.9 377 */ 378 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 379 boolean matHasFace(MatType matType, byte[] matData, int width, int height); 380 381 /** 382 * 1:N 人脸图像搜索<br> 383 * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br> 384 * 返回包含相似度计算结果的FseResult数组<br> 385 * 相似度值通过 FseResult.getSimilartys() 获取<br> 386 * 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br> 387 * @param matType 图像矩阵类型 388 * @param matData 图像矩阵 389 * @param width 图像宽度 390 * @param facePos 391 * 人脸位置对象<br> 392 * 为{@code null}时,先做人脸检测再提取特征码<br> 393 * 不为{@code null}时,直接在指定的位置提取特征码<br> 394 * @param similarty 相似度阀值 395 * @param rows 最多返回的记录数目 396 * @return 包含相似度计算结果的{@link FseResult}数组<br> 397 * @since 3.0.0 398 * @throws NotFaceDetectedException - 399 * @throws ImageErrorException - 400 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持 401 * @see #getCodeInfo(byte[], int, CodeInfo[]) 402 * @see #searchFeatures(byte[], double, int) 403 */ 404 @DeriveMethod(localResolvedTypes={ByteBuffer.class}) 405 public FseResult[] matSearchFaces(MatType matType, byte[] matData, int width, int height, CodeInfo facePos, double similarty, int rows) 406 throws NotFaceDetectedException, ImageErrorException; 407 408 /** 409 * 返回当前SDK特性(能力)描述,已定义字段:<br> 410 * <ul> 411 * <li>SDK_VERSION [string]SDK版本号</li> 412 * <li>MULTI_FACE_FEATURE [boolean]算法是否支持多人脸合成特征</li> 413 * <li>FACE_LIVE [boolean]是否支持活体检测</li> 414 * <li>WEAR_MASK [boolean]是否支持口罩检测</li> 415 * <li>FDDATA_SIZE [int]人脸检测数据的(byte)长度</li> 416 * <li>FEATURE_SIZE [int]人脸特征数据(byte)长度</li> 417 * <li>MAX_FACE_COUNT [int]最大检测人脸数目</li> 418 * <li>FSE_ENABLE [boolean]是否支持特征内存搜索引擎</li> 419 * <li>CODEINFO_RELOCATE [boolean]是否支持CodeInfo对象重定位</li> 420 * <li>LOCAL_DETECT [boolean] 人脸检测是否为本地实现,未定义则为false</li> 421 * </ul> 422 * 以上字段名常量定义参见{@link CapacityFieldConstant} 423 * @return key-value 对描述算法能力的映射 424 * @since 2.2.7 425 */ 426 public Map<String, String> sdkCapacity(); 427 428 /** 429 * 返回当前接口实现方式<br> 430 * false WebService类型<br> 431 * true 本地实现 432 * @return boolean 433 */ 434 public abstract boolean isLocal(); 435}