diff --git a/README.md b/README.md
index ec9c65d..d209e86 100644
--- a/README.md
+++ b/README.md
@@ -32,9 +32,15 @@
2、[PCN](https://github.com/Rock-100/FaceKit/tree/master/PCN)
+### 版本1.1.0更新
+
+* 1、修复已知BUG
+* 2、添加人脸比对1:1接口,详见文档:[05、人脸比对服务](https://gitee.com/open-visual/face-search/blob/dev-1.1.0/scripts/docs/doc-1.1.0.md#05%E4%BA%BA%E8%84%B8%E6%AF%94%E5%AF%B9%E6%9C%8D%E5%8A%A1)
+
+
### 项目文档
-* 在线文档:[文档-1.0.0](https://gitee.com/open-visual/face-search/blob/master/scripts/docs/doc-1.0.0.md)
+* 在线文档:[文档-1.1.0](https://gitee.com/open-visual/face-search/blob/dev-1.1.0/scripts/docs/doc-1.1.0.md)
* swagger文档:启动项目且开启swagger,访问:host:port/doc.html, 如 http://127.0.0.1:8080/doc.html
@@ -45,12 +51,12 @@
com.visual.face.search
face-search-client
- 1.0.0
+ 1.1.0
```
* 其他语言依赖
- 使用restful接口:[文档-1.0.0](https://gitee.com/open-visual/face-search/blob/master/scripts/docs/doc-1.0.0.md)
+ 使用restful接口:[文档-1.1.0](https://gitee.com/open-visual/face-search/blob/dev-1.1.0/scripts/docs/doc-1.1.0.md)
### 项目部署
diff --git a/face-search-client/pom.xml b/face-search-client/pom.xml
index 837041f..ce948ee 100644
--- a/face-search-client/pom.xml
+++ b/face-search-client/pom.xml
@@ -7,7 +7,7 @@
face-search-client
com.visual.face.search
- 1.0.0
+ 1.1.0
1.8
diff --git a/face-search-core/pom.xml b/face-search-core/pom.xml
index 097bf53..c90f1fb 100644
--- a/face-search-core/pom.xml
+++ b/face-search-core/pom.xml
@@ -5,7 +5,7 @@
face-search
com.visual.face.search
- 1.0.0
+ 1.1.0
4.0.0
face-search-core
diff --git a/face-search-core/src/main/java/com/visual/face/search/core/domain/ImageMat.java b/face-search-core/src/main/java/com/visual/face/search/core/domain/ImageMat.java
index e61f2a8..2588dad 100644
--- a/face-search-core/src/main/java/com/visual/face/search/core/domain/ImageMat.java
+++ b/face-search-core/src/main/java/com/visual/face/search/core/domain/ImageMat.java
@@ -9,7 +9,6 @@ import org.opencv.dnn.Dnn;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
-import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import java.awt.*;
@@ -20,6 +19,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Base64;
/**
* 图片加载工具
@@ -66,8 +66,11 @@ public class ImageMat implements Serializable {
public static ImageMat fromBase64(String base64Str){
InputStream inputStream = null;
try {
- BASE64Decoder decoder = new BASE64Decoder();
- byte[] data = decoder.decodeBuffer(base64Str);
+ // 新版本JDK被移除,替换为Base64.Decoder
+ // BASE64Decoder decoder = new BASE64Decoder();
+ // byte[] data = decoder.decodeBuffer(base64Str);
+ Base64.Decoder decoder = Base64.getMimeDecoder();
+ byte[] data = decoder.decode(base64Str);
inputStream = new ByteArrayInputStream(data);
return fromInputStream(inputStream);
}catch (Exception e){
diff --git a/face-search-core/src/main/java/com/visual/face/search/core/utils/MatUtil.java b/face-search-core/src/main/java/com/visual/face/search/core/utils/MatUtil.java
index 8757957..a43672d 100644
--- a/face-search-core/src/main/java/com/visual/face/search/core/utils/MatUtil.java
+++ b/face-search-core/src/main/java/com/visual/face/search/core/utils/MatUtil.java
@@ -1,10 +1,10 @@
package com.visual.face.search.core.utils;
import org.opencv.core.Mat;
-import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
+import java.util.Base64;
import java.util.Objects;
public class MatUtil {
@@ -42,8 +42,11 @@ public class MatUtil {
byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(matToBufferedImage(mat), "jpg", byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
- BASE64Encoder encoder = new BASE64Encoder();
- return encoder.encodeBuffer(Objects.requireNonNull(bytes));
+ // 新版本JDK被移除,替换为Base64.Encoder
+// BASE64Encoder encoder = new BASE64Encoder();
+// return encoder.encodeBuffer(Objects.requireNonNull(bytes));
+ Base64.Encoder encoder = Base64.getMimeEncoder();
+ return encoder.encodeToString(Objects.requireNonNull(bytes));
}catch (Exception e){
throw new RuntimeException(e);
}finally {
diff --git a/face-search-core/src/main/java/com/visual/face/search/core/utils/Similarity.java b/face-search-core/src/main/java/com/visual/face/search/core/utils/Similarity.java
index 98e62f9..b8a0e23 100644
--- a/face-search-core/src/main/java/com/visual/face/search/core/utils/Similarity.java
+++ b/face-search-core/src/main/java/com/visual/face/search/core/utils/Similarity.java
@@ -29,6 +29,27 @@ public class Similarity {
}
return (float) cosineSimilarity;
}
-
+
+
+ /**
+ * 两个向量可以为任意维度,但必须保持维度相同,表示n维度中的两点
+ * 欧式距离
+ * @param vector1
+ * @param vector2
+ * @return 两点间距离
+ */
+ public static float euclideanDistance(float[] vector1, float[] vector2) {
+ double distance = 0;
+ if (vector1.length == vector2.length) {
+ for (int i = 0; i < vector1.length; i++) {
+ double temp = Math.pow((vector1[i] - vector2[i]), 2);
+ distance += temp;
+ }
+ distance = Math.sqrt(distance);
+ }else {
+ throw new RuntimeException("vector length not equal");
+ }
+ return (float) distance;
+ }
}
diff --git a/face-search-engine/pom.xml b/face-search-engine/pom.xml
index 35bacf6..3897032 100644
--- a/face-search-engine/pom.xml
+++ b/face-search-engine/pom.xml
@@ -5,7 +5,7 @@
face-search
com.visual.face.search
- 1.0.0
+ 1.1.0
4.0.0
face-search-engine
diff --git a/face-search-server/pom.xml b/face-search-server/pom.xml
index 30afd0b..714550e 100644
--- a/face-search-server/pom.xml
+++ b/face-search-server/pom.xml
@@ -5,7 +5,7 @@
face-search
com.visual.face.search
- 1.0.0
+ 1.1.0
4.0.0
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/bootstrap/conf/SwaggerConfig.java b/face-search-server/src/main/java/com/visual/face/search/server/bootstrap/conf/SwaggerConfig.java
index ad65e83..a26bc0f 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/bootstrap/conf/SwaggerConfig.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/bootstrap/conf/SwaggerConfig.java
@@ -38,7 +38,7 @@ public class SwaggerConfig implements WebMvcConfigurer {
return new ApiInfoBuilder()
.title("人脸搜索服务API")
.description("人脸搜索服务API")
- .version("1.0.0")
+ .version("1.1.0")
.build();
}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/controller/health/HealthController.java b/face-search-server/src/main/java/com/visual/face/search/server/controller/health/HealthController.java
index 851705e..dbd4912 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/controller/health/HealthController.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/controller/health/HealthController.java
@@ -7,7 +7,7 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
-@Api(tags="05、公共服务-健康检测")
+@Api(tags="06、公共服务-健康检测")
@RestController("healthController")
@RequestMapping("/common/health")
public class HealthController {
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/controller/server/api/FaceCompareControllerApi.java b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/api/FaceCompareControllerApi.java
new file mode 100644
index 0000000..54ef408
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/api/FaceCompareControllerApi.java
@@ -0,0 +1,19 @@
+package com.visual.face.search.server.controller.server.api;
+
+import com.visual.face.search.server.domain.common.ResponseInfo;
+import com.visual.face.search.server.domain.request.FaceCompareReqVo;
+import com.visual.face.search.server.domain.response.FaceCompareRepVo;
+
+/**
+ * 人脸1:1比对
+ */
+public interface FaceCompareControllerApi {
+
+ /**
+ * 人脸比对1:1接口
+ * @param compareReq
+ * @return
+ */
+ public ResponseInfo faceCompare(FaceCompareReqVo compareReq);
+
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/controller/server/impl/FaceCompareControllerImpl.java b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/impl/FaceCompareControllerImpl.java
new file mode 100644
index 0000000..49f4b03
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/impl/FaceCompareControllerImpl.java
@@ -0,0 +1,28 @@
+package com.visual.face.search.server.controller.server.impl;
+
+import javax.annotation.Resource;
+import com.visual.face.search.server.controller.base.BaseController;
+import com.visual.face.search.server.controller.server.api.FaceCompareControllerApi;
+import com.visual.face.search.server.domain.common.ResponseInfo;
+import com.visual.face.search.server.domain.request.FaceCompareReqVo;
+import com.visual.face.search.server.domain.response.FaceCompareRepVo;
+import com.visual.face.search.server.service.api.FaceCompareService;
+import com.visual.face.search.server.utils.ResponseBuilder;
+
+
+public class FaceCompareControllerImpl extends BaseController implements FaceCompareControllerApi {
+
+ @Resource
+ private FaceCompareService faceCompareService;
+
+ @Override
+ public ResponseInfo faceCompare(FaceCompareReqVo compareReq) {
+ try {
+ return ResponseBuilder.success(faceCompareService.faceCompare(compareReq));
+ }catch (Exception e){
+ logger.error("do faceCompare exception:", e);
+ return ResponseBuilder.exception(e.getMessage(), null);
+ }
+ }
+
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceCompareController.java b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceCompareController.java
new file mode 100644
index 0000000..0dbfe17
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceCompareController.java
@@ -0,0 +1,27 @@
+package com.visual.face.search.server.controller.server.restful;
+
+import com.visual.face.search.server.controller.server.impl.FaceCompareControllerImpl;
+import com.visual.face.search.server.domain.common.ResponseInfo;
+import com.visual.face.search.server.domain.request.FaceCompareReqVo;
+import com.visual.face.search.server.domain.response.FaceCompareRepVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags="05、人脸比对服务")
+@RestController("visualFaceCompareController")
+@RequestMapping("/visual/compare")
+public class FaceCompareController extends FaceCompareControllerImpl {
+
+
+ @ApiOperation(value="1、人脸比对1:1", position = 1)
+ @Override
+ @ResponseBody
+ @RequestMapping(value = "/do", method = RequestMethod.POST)
+ public ResponseInfo faceCompare(FaceCompareReqVo compareReq) {
+ return super.faceCompare(compareReq);
+ }
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceSearchController.java b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceSearchController.java
index da49284..4f81a73 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceSearchController.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/controller/server/restful/FaceSearchController.java
@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/visual/search")
public class FaceSearchController extends FaceSearchControllerImpl {
- @ApiOperation(value="1、人脸搜索1:N", position = 1)
+ @ApiOperation(value="1、人脸搜索M:N", position = 1)
@Override
@ResponseBody
@RequestMapping(value = "/do", method = RequestMethod.POST)
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/domain/base/CollectVo.java b/face-search-server/src/main/java/com/visual/face/search/server/domain/base/CollectVo.java
index a747fea..ccd5c15 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/domain/base/CollectVo.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/domain/base/CollectVo.java
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Min;
+import java.util.ArrayList;
import java.util.List;
/***
@@ -33,10 +34,10 @@ public class CollectVo> extends BaseVo {
private Integer shardsNum;
/**自定义的样本字段**/
@ApiModelProperty(value="自定义的样本属性字段", position = 5,required = false)
- private List sampleColumns;
+ private List sampleColumns = new ArrayList<>();
/**自定义的人脸字段**/
@ApiModelProperty(value="自定义的人脸属性字段", position = 6,required = false)
- private List faceColumns;
+ private List faceColumns = new ArrayList<>();
/**启用binlog同步**/
@ApiModelProperty(value="启用binlog同步。扩展字段,暂不支持该功能。", position = 7,required = false)
private Boolean syncBinLog;
@@ -101,7 +102,9 @@ public class CollectVo> extends BaseVo {
}
public ExtendsVo setSampleColumns(List sampleColumns) {
- this.sampleColumns = sampleColumns;
+ if(null != sampleColumns){
+ this.sampleColumns = sampleColumns;
+ }
return (ExtendsVo) this;
}
@@ -110,7 +113,9 @@ public class CollectVo> extends BaseVo {
}
public ExtendsVo setFaceColumns(List faceColumns) {
- this.faceColumns = faceColumns;
+ if(null != faceColumns){
+ this.faceColumns = faceColumns;
+ }
return (ExtendsVo) this;
}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/domain/extend/CompareFace.java b/face-search-server/src/main/java/com/visual/face/search/server/domain/extend/CompareFace.java
new file mode 100644
index 0000000..d648035
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/domain/extend/CompareFace.java
@@ -0,0 +1,53 @@
+package com.visual.face.search.server.domain.extend;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class CompareFace {
+
+ /**人脸质量分数**/
+ @ApiModelProperty(value="A图片人脸分数:[0,100]", position = 1, required = true)
+ private Float faceScoreA;
+ /**人脸质量分数**/
+ @ApiModelProperty(value="B图片人脸分数:[0,100]", position = 1, required = true)
+ private Float faceScoreB;
+
+ /**人脸位置信息**/
+ @ApiModelProperty(value="A图片人脸位置信息", position = 3, required = true)
+ private FaceLocation locationA;
+ /**人脸位置信息**/
+ @ApiModelProperty(value="B图片人脸位置信息", position = 4, required = true)
+ private FaceLocation locationB;
+
+
+ public Float getFaceScoreA() {
+ return faceScoreA;
+ }
+
+ public void setFaceScoreA(Float faceScoreA) {
+ this.faceScoreA = faceScoreA;
+ }
+
+ public FaceLocation getLocationA() {
+ return locationA;
+ }
+
+ public void setLocationA(FaceLocation locationA) {
+ this.locationA = locationA;
+ }
+
+ public Float getFaceScoreB() {
+ return faceScoreB;
+ }
+
+ public void setFaceScoreB(Float faceScoreB) {
+ this.faceScoreB = faceScoreB;
+ }
+
+ public FaceLocation getLocationB() {
+ return locationB;
+ }
+
+ public void setLocationB(FaceLocation locationB) {
+ this.locationB = locationB;
+ }
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/domain/request/FaceCompareReqVo.java b/face-search-server/src/main/java/com/visual/face/search/server/domain/request/FaceCompareReqVo.java
new file mode 100644
index 0000000..a42f76b
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/domain/request/FaceCompareReqVo.java
@@ -0,0 +1,66 @@
+package com.visual.face.search.server.domain.request;
+
+import com.visual.face.search.server.domain.base.BaseVo;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+public class FaceCompareReqVo extends BaseVo {
+
+ /**图像Base64编码值**/
+ @NotNull(message = "imageBase64A cannot be empty")
+ @ApiModelProperty(value="图像A的Base64编码值", position = 1,required = true)
+ private String imageBase64A;
+
+ /**图像Base64编码值**/
+ @NotNull(message = "imageBase64B cannot be empty")
+ @ApiModelProperty(value="图像B的Base64编码值", position = 2,required = true)
+ private String imageBase64B;
+
+ /**人脸质量分数阈值**/
+ @Size(min = 0, max = 100, message = "faceScoreThreshold is not in the range")
+ @ApiModelProperty(value="人脸质量分数阈值,范围:[0,100]:默认0。当设置为0时,会默认使用当前模型的默认值,该方法为推荐使用方式", position = 3,required = false)
+ private Float faceScoreThreshold = 0f;
+
+ /**是否需要人脸信息**/
+ @ApiModelProperty(value="是否需要人脸信息,默认为:true", position = 4,required = false)
+ private Boolean needFaceInfo = true;
+
+
+ public String getImageBase64A() {
+ return imageBase64A;
+ }
+
+ public void setImageBase64A(String imageBase64A) {
+ this.imageBase64A = imageBase64A;
+ }
+
+ public String getImageBase64B() {
+ return imageBase64B;
+ }
+
+ public void setImageBase64B(String imageBase64B) {
+ this.imageBase64B = imageBase64B;
+ }
+
+ public Float getFaceScoreThreshold() {
+ return faceScoreThreshold;
+ }
+
+ public void setFaceScoreThreshold(Float faceScoreThreshold) {
+ if(null != faceScoreThreshold && faceScoreThreshold >= 0 && faceScoreThreshold <= 100){
+ this.faceScoreThreshold = faceScoreThreshold;
+ }
+ }
+
+ public Boolean getNeedFaceInfo() {
+ return needFaceInfo;
+ }
+
+ public void setNeedFaceInfo(Boolean needFaceInfo) {
+ if(null != needFaceInfo){
+ this.needFaceInfo = needFaceInfo;
+ }
+ }
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/domain/response/FaceCompareRepVo.java b/face-search-server/src/main/java/com/visual/face/search/server/domain/response/FaceCompareRepVo.java
new file mode 100644
index 0000000..f7a1018
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/domain/response/FaceCompareRepVo.java
@@ -0,0 +1,41 @@
+package com.visual.face.search.server.domain.response;
+
+import com.visual.face.search.server.domain.base.BaseVo;
+import com.visual.face.search.server.domain.extend.CompareFace;
+import io.swagger.annotations.ApiModelProperty;
+
+public class FaceCompareRepVo extends BaseVo {
+ /**向量的距离**/
+ @ApiModelProperty(value="向量欧式距离:>=0", position = 1, required = true)
+ private Float distance;
+ /**转换后的置信度**/
+ @ApiModelProperty(value="余弦距离转换后的置信度:[-100,100],值越大,相似度越高。", position = 2, required = true)
+ private Float confidence;
+ /**人脸信息**/
+ @ApiModelProperty(value="人脸信息,参数needFaceInfo=false时,值为null", position = 3, required = false)
+ private CompareFace faceInfo;
+
+ public Float getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Float distance) {
+ this.distance = distance;
+ }
+
+ public Float getConfidence() {
+ return confidence;
+ }
+
+ public void setConfidence(Float confidence) {
+ this.confidence = confidence;
+ }
+
+ public CompareFace getFaceInfo() {
+ return faceInfo;
+ }
+
+ public void setFaceInfo(CompareFace faceInfo) {
+ this.faceInfo = faceInfo;
+ }
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/service/api/FaceCompareService.java b/face-search-server/src/main/java/com/visual/face/search/server/service/api/FaceCompareService.java
new file mode 100644
index 0000000..38dadc7
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/service/api/FaceCompareService.java
@@ -0,0 +1,10 @@
+package com.visual.face.search.server.service.api;
+
+import com.visual.face.search.server.domain.request.FaceCompareReqVo;
+import com.visual.face.search.server.domain.response.FaceCompareRepVo;
+
+public interface FaceCompareService {
+
+ public FaceCompareRepVo faceCompare(FaceCompareReqVo compareReq);
+
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceCompareServiceImpl.java b/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceCompareServiceImpl.java
new file mode 100644
index 0000000..9f060da
--- /dev/null
+++ b/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceCompareServiceImpl.java
@@ -0,0 +1,94 @@
+package com.visual.face.search.server.service.impl;
+
+import com.visual.face.search.core.domain.ExtParam;
+import com.visual.face.search.core.domain.FaceImage;
+import com.visual.face.search.core.domain.FaceInfo;
+import com.visual.face.search.core.domain.ImageMat;
+import com.visual.face.search.core.extract.FaceFeatureExtractor;
+import com.visual.face.search.core.utils.Similarity;
+import com.visual.face.search.server.domain.extend.CompareFace;
+import com.visual.face.search.server.domain.extend.FaceLocation;
+import com.visual.face.search.server.domain.request.FaceCompareReqVo;
+import com.visual.face.search.server.domain.response.FaceCompareRepVo;
+import com.visual.face.search.server.service.api.FaceCompareService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+
+@Service("visualFaceCompareServiceImpl")
+public class FaceCompareServiceImpl implements FaceCompareService {
+
+ @Resource
+ private FaceFeatureExtractor faceFeatureExtractor;
+
+
+ @Override
+ public FaceCompareRepVo faceCompare(FaceCompareReqVo compareReq) {
+ FaceInfo faceInfoA = getFaceInfo(compareReq.getFaceScoreThreshold(), compareReq.getImageBase64A());
+ if(null == faceInfoA){
+ throw new RuntimeException("Image A is not face");
+ }
+ FaceInfo faceInfoB = getFaceInfo(compareReq.getFaceScoreThreshold(), compareReq.getImageBase64B());
+ if(null == faceInfoB){
+ throw new RuntimeException("Image B is not face");
+ }
+ //计算余弦相似度
+ float simVal = Similarity.cosineSimilarity(faceInfoA.embedding.embeds, faceInfoB.embedding.embeds);
+ float confidence = (float) Math.floor(simVal * 1000000)/10000;
+ //欧式距离
+ float euclideanDistance = Similarity.euclideanDistance(faceInfoA.embedding.embeds, faceInfoB.embedding.embeds);
+ float distance = (float) Math.floor(euclideanDistance * 10000)/10000;
+ //构建返回值
+ FaceCompareRepVo faceCompareRep = new FaceCompareRepVo();
+ faceCompareRep.setDistance(distance);
+ faceCompareRep.setConfidence(confidence);
+ if(compareReq.getNeedFaceInfo()){
+ CompareFace compareFace = new CompareFace();
+ compareFace.setFaceScoreA((float) Math.floor(faceInfoA.score * 1000000)/10000);
+ compareFace.setFaceScoreB((float) Math.floor(faceInfoA.score * 1000000)/10000);
+ FaceInfo.FaceBox boxA = faceInfoA.box;
+ compareFace.setLocationA(FaceLocation.build(boxA.leftTop.x, boxA.leftTop.y, boxA.width(), boxA.height()));
+ FaceInfo.FaceBox boxB = faceInfoB.box;
+ compareFace.setLocationB(FaceLocation.build(boxB.leftTop.x, boxB.leftTop.y, boxB.width(), boxB.height()));
+ faceCompareRep.setFaceInfo(compareFace);
+ }
+ //返回对象
+ return faceCompareRep;
+ }
+
+
+ /**
+ * 图片检测并提取人脸特征
+ * @param faceScoreThreshold
+ * @param imageBase64
+ * @return
+ */
+ private FaceInfo getFaceInfo(float faceScoreThreshold, String imageBase64){
+ faceScoreThreshold = faceScoreThreshold < 0 ? 0 : faceScoreThreshold;
+ faceScoreThreshold = faceScoreThreshold > 100 ? 100 : faceScoreThreshold;
+ faceScoreThreshold = faceScoreThreshold > 1 ? faceScoreThreshold / 100 : faceScoreThreshold;
+
+ ExtParam extParam = ExtParam.build().setMask(true).setScoreTh(faceScoreThreshold).setIouTh(0).setTopK(1);
+ ImageMat imageMat = null;
+ FaceImage faceImage = null;
+ try {
+ imageMat = ImageMat.fromBase64(imageBase64);
+ faceImage = faceFeatureExtractor.extract(imageMat, extParam, new HashMap<>());
+ }finally {
+ if(null != imageMat){
+ imageMat.release();
+ }
+ }
+ if(null == faceImage){
+ throw new RuntimeException("FeatureExtractor extract error");
+ }
+
+ List faceInfos = faceImage.faceInfos();
+ if(faceInfos.size() > 0){
+ return faceInfos.get(0);
+ }
+ return null;
+ }
+}
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceSearchServiceImpl.java b/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceSearchServiceImpl.java
index 66e65be..8c61320 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceSearchServiceImpl.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/service/impl/FaceSearchServiceImpl.java
@@ -123,7 +123,7 @@ public class FaceSearchServiceImpl extends BaseService implements FaceSearchServ
FaceInfo.FaceBox box = faceInfos.get(i).box;
FaceSearchRepVo vo = FaceSearchRepVo.build();
vo.setLocation(FaceLocation.build(box.leftTop.x, box.leftTop.y, box.width(), box.height()));
- vo.setFaceScore((float)Math.floor(faceInfos.get(i).score * 10000)/100);
+ vo.setFaceScore((float)Math.floor(faceInfos.get(i).score * 1000000)/10000);
List match = new ArrayList<>();
SearchResult searchResult = result.get(i);
List documents = searchResult.getDocuments();
@@ -135,7 +135,7 @@ public class FaceSearchServiceImpl extends BaseService implements FaceSearchServ
String faceVectorStr = MapUtils.getString(face, Constant.ColumnNameFaceVector);
float[] faceVector = ValueUtil.convertVector(faceVectorStr);
float simVal = Similarity.cosineSimilarity(faceInfos.get(i).embedding.embeds, faceVector);
- float confidence = (float) Math.floor(simVal * 10000)/100;
+ float confidence = (float) Math.floor(simVal * 1000000)/10000;
if(null != sampleId && sampleMapping.containsKey(sampleId) && confidence >= search.getConfidenceThreshold()){
Map sample = sampleMapping.get(sampleId);
SampleFaceVo faceVo = SampleFaceVo.build();
@@ -143,7 +143,7 @@ public class FaceSearchServiceImpl extends BaseService implements FaceSearchServ
faceVo.setFaceId(document.getFaceId());
faceVo.setFaceScore(faceScore);
faceVo.setConfidence(confidence);
- faceVo.setDistance((float) Math.floor(document.getScore() * 100) / 100);
+ faceVo.setDistance((float) Math.floor(document.getScore() * 10000) / 10000);
faceVo.setFaceData(ValueUtil.getFieldKeyValues(face, ValueUtil.getFaceColumns(collection)));
faceVo.setSampleData(ValueUtil.getFieldKeyValues(sample, ValueUtil.getSampleColumns(collection)));
match.add(faceVo);
diff --git a/face-search-server/src/main/java/com/visual/face/search/server/utils/ValueUtil.java b/face-search-server/src/main/java/com/visual/face/search/server/utils/ValueUtil.java
index 784c97b..07568bc 100644
--- a/face-search-server/src/main/java/com/visual/face/search/server/utils/ValueUtil.java
+++ b/face-search-server/src/main/java/com/visual/face/search/server/utils/ValueUtil.java
@@ -16,24 +16,27 @@ import java.util.Map;
public class ValueUtil {
public static List getFaceColumns(Collection collection){
- if(null != collection.getSchemaInfo() && !collection.getSchemaInfo().isEmpty()){
+ if(null != collection.getSchemaInfo() && !collection.getSchemaInfo().isEmpty()) {
CollectRepVo collectVo = JsonUtil.toEntity(collection.getSchemaInfo(), CollectRepVo.class);
- return collectVo.getFaceColumns();
- }else{
- return new ArrayList<>();
+ if (null != collectVo && null != collectVo.getFaceColumns()) {
+ return collectVo.getFaceColumns();
+ }
}
+ return new ArrayList<>();
}
public static List getSampleColumns(Collection collection){
if(null != collection.getSchemaInfo() && !collection.getSchemaInfo().isEmpty()){
CollectRepVo collectVo = JsonUtil.toEntity(collection.getSchemaInfo(), CollectRepVo.class);
- return collectVo.getSampleColumns();
- }else{
- return new ArrayList<>();
+ if (null != collectVo && null != collectVo.getSampleColumns()) {
+ return collectVo.getSampleColumns();
+ }
}
+ return new ArrayList<>();
}
public static FieldKeyValues getFieldKeyValues(Map map , List columns){
+ columns = null != columns ? columns : new ArrayList<>();
Map keyMap = new HashMap<>();
for(FiledColumn column : columns){
for(String dataKey : map.keySet()){
diff --git a/face-search-server/src/main/resources/application-dev.yml b/face-search-server/src/main/resources/application-dev.yml
index c700023..07b14f2 100644
--- a/face-search-server/src/main/resources/application-dev.yml
+++ b/face-search-server/src/main/resources/application-dev.yml
@@ -120,184 +120,3 @@ spring:
wall:
config:
multi-statement-allow: true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-## 用户配置
-#user:
-# password:
-# # 密码错误{maxRetryCount}次锁定10分钟
-# maxRetryCount: 5
-#
-## Spring配置
-#spring:
-# # 模板引擎
-# thymeleaf:
-# mode: HTML
-# encoding: utf-8
-# # 禁用缓存
-# cache: false
-# # 资源信息
-# messages:
-# # 国际化资源文件路径
-# basename: static/i18n/messages
-# jackson:
-# time-zone: GMT+8
-# date-format: yyyy-MM-dd HH:mm:ss
-# # 文件上传
-# servlet:
-# multipart:
-# # 单个文件大小
-# max-file-size: 10MB
-# # 设置总上传的文件大小
-# max-request-size: 20MB
-# #数据源
-# datasource:
-# type: com.alibaba.druid.pool.DruidDataSource
-# driverClassName: com.mysql.cj.jdbc.Driver
-# druid:
-# # 主库数据源
-# master:
-# url: jdbc:mysql://127.0.0.1:3306/open_lab?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-# username: root
-# password: root
-# # 从库数据源
-# slave:
-# # 从数据源开关/默认关闭
-# enabled: false
-# url:
-# username:
-# password:
-# # 初始连接数
-# initialSize: 5
-# # 最小连接池数量
-# minIdle: 10
-# # 最大连接池数量
-# maxActive: 20
-# # 配置获取连接等待超时的时间
-# maxWait: 60000
-# # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-# timeBetweenEvictionRunsMillis: 60000
-# # 配置一个连接在池中最小生存的时间,单位是毫秒
-# minEvictableIdleTimeMillis: 300000
-# # 配置一个连接在池中最大生存的时间,单位是毫秒
-# maxEvictableIdleTimeMillis: 900000
-# # 配置检测连接是否有效
-# validationQuery: SELECT 1 FROM DUAL
-# testWhileIdle: true
-# testOnBorrow: false
-# testOnReturn: false
-# webStatFilter:
-# enabled: true
-# statViewServlet:
-# enabled: true
-# # 设置白名单,不填则允许所有访问
-# allow:
-# url-pattern: /druid/*
-# # 控制台管理用户名和密码
-# login-username:
-# login-password:
-# filter:
-# stat:
-# enabled: true
-# # 慢SQL记录
-# log-slow-sql: true
-# slow-sql-millis: 1000
-# merge-sql: true
-# wall:
-# config:
-# multi-statement-allow: true
-# session:
-# store-type: redis
-# redis:
-# database: 2
-# host: 127.0.0.1
-# port: 6379
-# password: # 密码(默认为空)
-# timeout: 6000 # 连接超时时长(毫秒)
-# jedis:
-# pool:
-# max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
-# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
-# max-idle: 10 # 连接池中的最大空闲连接
-# min-idle: 5 # 连接池中的最小空闲连接
-#
-## MyBatis
-#mybatis:
-# # 搜索指定包别名
-# typeAliasesPackage: com.open.lab.manager.**.domain
-# # 配置mapper的扫描,找到所有的mapper.xml映射文件
-# mapperLocations: classpath*:mapper/**/*Mapper.xml
-# # 加载全局的配置文件
-# configLocation: classpath:mybatis/mybatis-config.xml
-#
-## PageHelper分页插件
-#pagehelper:
-# helperDialect: mysql
-# reasonable: true
-# supportMethodsArguments: true
-# params: count=countSql
-#
-## Shiro
-#shiro:
-# cache:
-# storeEngine: redis
-# user:
-# # 登录地址
-# loginUrl: /login
-# # 权限认证失败地址
-# unauthorizedUrl: /unauth
-# # 首页地址
-# indexUrl: /index
-# # 验证码开关
-# captchaEnabled: true
-# # 验证码类型 math 数组计算 char 字符
-# captchaType: math
-# cookie:
-# # 设置Cookie的域名 默认空,即当前访问的域名
-# domain:
-# # 设置cookie的有效访问路径
-# path: /
-# # 设置HttpOnly属性
-# httpOnly: true
-# # 设置Cookie的过期时间,天为单位
-# maxAge: 30
-# # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeToString(deskey.getEncoded()));
-# cipherKey: zSyK5Kp6PZAAjlT+eeNMlg==
-# session:
-# # Session超时时间,-1代表永不过期(默认30分钟)
-# expireTime: 30
-# # 同步session到数据库的周期(默认1分钟)
-# dbSyncPeriod: 1
-# # 相隔多久检查一次session的有效性,默认就是10分钟
-# validationInterval: 10
-# # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
-# maxSession: -1
-# # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
-# kickoutAfter: false
-#
-## 防止XSS攻击
-#xss:
-# # 过滤开关
-# enabled: true
-# # 排除链接(多个用逗号分隔)
-# excludes: /system/notice/*
-# # 匹配链接
-# urlPatterns: /system/*,/monitor/*,/tool/*
-#
-## Swagger配置
-#swagger:
-# # 是否开启swagger
-# enabled: true
diff --git a/face-search-test/pom.xml b/face-search-test/pom.xml
index c20e69d..7f3a3e8 100644
--- a/face-search-test/pom.xml
+++ b/face-search-test/pom.xml
@@ -6,7 +6,7 @@
face-search-test
com.visual.face.search
- 1.0.0
+ 1.1.0
1.8
@@ -18,7 +18,7 @@
com.visual.face.search
face-search-client
- 1.0.0
+ 1.1.0
diff --git a/pom.xml b/pom.xml
index b803de2..7987365 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
com.visual.face.search
face-search
- 1.0.0
+ 1.1.0
pom
diff --git a/scripts/docker-compose-milvus.yml b/scripts/docker-compose-milvus.yml
index a133f89..caf6117 100644
--- a/scripts/docker-compose-milvus.yml
+++ b/scripts/docker-compose-milvus.yml
@@ -62,7 +62,7 @@ services:
visual-facesearch:
container_name: face-search-server-standalone
- image: divenswu/face-search:1.0.0
+ image: divenswu/face-search:1.1.0
environment:
SPRING_DATASOURCE_URL: 'jdbc:mysql://visual-mysql:3306/visual_face_search?useUnicode=true&characterEncoding=utf8'
SPRING_DATASOURCE_USERNAME: root
diff --git a/scripts/docker-compose-proxima.yml b/scripts/docker-compose-proxima.yml
index 5f6211d..79bcd2f 100644
--- a/scripts/docker-compose-proxima.yml
+++ b/scripts/docker-compose-proxima.yml
@@ -30,7 +30,7 @@ services:
visual-facesearch:
container_name: face-search-server-standalone
- image: divenswu/face-search:1.0.0
+ image: divenswu/face-search:1.1.0
environment:
SPRING_DATASOURCE_URL: 'jdbc:mysql://visual-mysql:3306/visual_face_search?useUnicode=true&characterEncoding=utf8'
SPRING_DATASOURCE_USERNAME: root
diff --git a/scripts/docker_build.sh b/scripts/docker_build.sh
index 547f42d..b660579 100644
--- a/scripts/docker_build.sh
+++ b/scripts/docker_build.sh
@@ -1,4 +1,4 @@
-version='1.0.0'
+version='1.1.0'
SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
cd ${SHELL_FOLDER}
diff --git a/scripts/docs/doc-1.1.0.md b/scripts/docs/doc-1.1.0.md
new file mode 100644
index 0000000..eba37c3
--- /dev/null
+++ b/scripts/docs/doc-1.1.0.md
@@ -0,0 +1,1340 @@
+
+**人脸搜索服务API**
+
+
+**简介**:人脸搜索服务API
+
+
+**HOST**:127.0.0.1:8080
+
+
+**联系人**:
+
+
+**Version**:1.1.0
+
+**接口路径**:/v2/api-docs
+
+
+# 01、集合(数据库)管理
+
+
+## 1、创建一个集合(数据库)
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/collect/create`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+**请求示例**:
+```json
+{
+ "namespace": "",
+ "collectionName": "",
+ "collectionComment": "",
+ "maxDocsPerSegment": 0,
+ "shardsNum": 0,
+ "sampleColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "faceColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "syncBinLog": true
+}
+```
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collect| 集合信息 | body | true |CollectReqVo | CollectReqVo |
+
+**schema属性说明**
+
+
+
+**CollectReqVo**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|collectionName| 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|collectionComment| 集合描述:最大128个字符 | body | false |string | |
+|maxDocsPerSegment| 数据分片中最大的文件个数,默认为0(不限制),仅对Proxima引擎生效 | body | false |integer(int64) | |
+|shardsNum| 要创建的集合的分片数,默认为0(即系统默认),仅对Milvus引擎生效 | body | false |integer(int32) | |
+|sampleColumns| 自定义的样本属性字段 | body | false |array | FiledColumn |
+|faceColumns| 自定义的人脸属性字段 | body | false |array | FiledColumn |
+|syncBinLog| 启用binlog同步。扩展字段,暂不支持该功能。 | body | false |boolean | |
+
+**FiledColumn**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|name| 字段名称,支持小写字母、数字和下划线的组合,最大32个字符 | body | true |string | |
+|comment| 字段描述,最大64个字符 | body | false |string | |
+|dataType| 字段类型,不能为UNDEFINED类型,可用值:UNDEFINED,STRING,BOOL,INT,FLOAT,DOUBLE | body | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+## 2、根据命名空间,集合名称删除集合
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/collect/delete`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|namespace| 命名空间 | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+## 3、根据命名空间,集合名称查看集合信息
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/collect/get`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|namespace| 命名空间 | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": {
+ "namespace": "",
+ "collectionName": "",
+ "collectionComment": "",
+ "maxDocsPerSegment": 0,
+ "shardsNum": 0,
+ "sampleColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "faceColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "syncBinLog": true
+ }
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |CollectRepVo | CollectRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**CollectRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|namespace | 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionName | 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionComment | 集合描述:最大128个字符 |string | |
+|maxDocsPerSegment | 数据分片中最大的文件个数,默认为0(不限制),仅对Proxima引擎生效 |integer(int64) | |
+|shardsNum | 要创建的集合的分片数,默认为0(即系统默认),仅对Milvus引擎生效 |integer(int32) | |
+|sampleColumns | 自定义的样本属性字段 |array | FiledColumn |
+|faceColumns | 自定义的人脸属性字段 |array | FiledColumn |
+|syncBinLog | 启用binlog同步。扩展字段,暂不支持该功能。 |boolean | |
+
+**FiledColumn**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|name | 字段名称,支持小写字母、数字和下划线的组合,最大32个字符 |string | |
+|comment | 字段描述,最大64个字符 |string | |
+|dataType | 字段类型,不能为UNDEFINED类型,可用值:UNDEFINED,STRING,BOOL,INT,FLOAT,DOUBLE |string | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«CollectRepVo»|
+## 4、根据命名空间查看集合列表
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/collect/list`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间 | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": [
+ {
+ "namespace": "",
+ "collectionName": "",
+ "collectionComment": "",
+ "maxDocsPerSegment": 0,
+ "shardsNum": 0,
+ "sampleColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "faceColumns": [
+ {
+ "name": "",
+ "comment": "",
+ "dataType": ""
+ }
+ ],
+ "syncBinLog": true
+ }
+ ]
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |array | CollectRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**CollectRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|namespace | 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionName | 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionComment | 集合描述:最大128个字符 |string | |
+|maxDocsPerSegment | 数据分片中最大的文件个数,默认为0(不限制),仅对Proxima引擎生效 |integer(int64) | |
+|shardsNum | 要创建的集合的分片数,默认为0(即系统默认),仅对Milvus引擎生效 |integer(int32) | |
+|sampleColumns | 自定义的样本属性字段 |array | FiledColumn |
+|faceColumns | 自定义的人脸属性字段 |array | FiledColumn |
+|syncBinLog | 启用binlog同步。扩展字段,暂不支持该功能。 |boolean | |
+
+**FiledColumn**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|name | 字段名称,支持小写字母、数字和下划线的组合,最大32个字符 |string | |
+|comment | 字段描述,最大64个字符 |string | |
+|dataType | 字段类型,不能为UNDEFINED类型,可用值:UNDEFINED,STRING,BOOL,INT,FLOAT,DOUBLE |string | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«List«CollectRepVo»»|
+# 02、人脸样本管理
+
+## 1、创建一个样本
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/sample/create`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+**请求示例**:
+```json
+{
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "sampleData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ]
+}
+```
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|sample| 样本信息 | body | true |SampleDataReqVo | SampleDataReqVo |
+
+**schema属性说明**
+
+
+
+**SampleDataReqVo**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|collectionName| 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|sampleId| 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|sampleData| 扩展字段 | body | false |array | FieldKeyValue |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|key| 字段名,与创建集合时给定的字段名一致 | body | true |string | |
+|value| 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 | body | false |object | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+## 3、根据条件删除样本
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/sample/delete`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|namespace| 命名空间 | query | true |string | |
+|sampleId| 样本ID | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+## 4、根据条件查看样本
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/sample/get`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|namespace| 命名空间 | query | true |string | |
+|sampleId| 样本ID | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": {
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "sampleData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ],
+ "faces": [
+ {
+ "faceId": "",
+ "faceData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ],
+ "faceScore": 0
+ }
+ ]
+ }
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |SampleDataRepVo | SampleDataRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**SampleDataRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|namespace | 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionName | 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 |string | |
+|sampleId | 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 |string | |
+|sampleData | 扩展字段 |array | FieldKeyValue |
+|faces | 人脸数据 |array | SimpleFaceVo |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|key | 字段名,与创建集合时给定的字段名一致 |string | |
+|value | 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 |object | |
+
+**SimpleFaceVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|faceId | 人脸ID |string | |
+|faceData | 人脸扩展的额外数据 |array | FieldKeyValue |
+|faceScore | 人脸分数 |number(float) | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«SampleDataRepVo»|
+## 5、根据查询信息查看样本列表
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/sample/list`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|limit| 样本数目:默认10 | query | true |integer | |
+|namespace| 命名空间 | query | true |string | |
+|offset| 起始记录:默认0 | query | true |integer | |
+|order| 排列方式:默认asc,包括asc(升序)和desc(降序) | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": [
+ {
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "sampleData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ],
+ "faces": [
+ {
+ "faceId": "",
+ "faceData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ],
+ "faceScore": 0
+ }
+ ]
+ }
+ ]
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |array | SampleDataRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**SampleDataRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|namespace | 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionName | 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 |string | |
+|sampleId | 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 |string | |
+|sampleData | 扩展字段 |array | FieldKeyValue |
+|faces | 人脸数据 |array | SimpleFaceVo |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|key | 字段名,与创建集合时给定的字段名一致 |string | |
+|value | 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 |object | |
+
+**SimpleFaceVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|faceId | 人脸ID |string | |
+|faceData | 人脸扩展的额外数据 |array | FieldKeyValue |
+|faceScore | 人脸分数 |number(float) | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«List«SampleDataRepVo»»|
+## 2、更新一个样本
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/sample/update`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+**请求示例**:
+```json
+{
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "sampleData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ]
+}
+```
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|sample| 样本信息 | body | true |SampleDataReqVo | SampleDataReqVo |
+
+**schema属性说明**
+
+
+
+**SampleDataReqVo**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|collectionName| 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|sampleId| 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|sampleData| 扩展字段 | body | false |array | FieldKeyValue |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|key| 字段名,与创建集合时给定的字段名一致 | body | true |string | |
+|value| 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 | body | false |object | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+# 03、人脸数据管理
+
+## 1、创建一个人脸数据
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/face/create`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+**请求示例**:
+```json
+{
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "imageBase64": "",
+ "faceScoreThreshold": 0,
+ "minConfidenceThresholdWithThisSample": 0,
+ "maxConfidenceThresholdWithOtherSample": 0,
+ "faceData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ]
+}
+```
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|face| face | body | true |FaceDataReqVo | FaceDataReqVo |
+
+**schema属性说明**
+
+
+
+**FaceDataReqVo**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|collectionName| 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|sampleId| 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 | body | true |string | |
+|imageBase64| 图像Base64编码值 | body | true |string | |
+|faceScoreThreshold| 人脸质量分数阈值,范围:[0,100]:默认0。当设置为0时,会默认使用当前模型的默认值,该方法为推荐使用方式 | body | false |number(float) | |
+|minConfidenceThresholdWithThisSample| 当前样本的人脸相似度的最小阈值,范围:[0,100]:默认0。当设置为0时,表示不做类间相似度判断逻辑,开启后对效率有较大影响 | body | false |number(float) | |
+|maxConfidenceThresholdWithOtherSample| 当前样本与其他样本的人脸相似度的最大阈值,范围:[0,100]:默认0。当设置为0时,表示不做类间相似度判断逻辑,开启后对效率有较大影响 | body | false |number(float) | |
+|faceData| 扩展字段 | body | false |array | FieldKeyValue |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|key| 字段名,与创建集合时给定的字段名一致 | body | true |string | |
+|value| 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 | body | false |object | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": {
+ "namespace": "",
+ "collectionName": "",
+ "sampleId": "",
+ "faceId": "",
+ "faceScore": 0,
+ "faceData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ]
+ }
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |FaceDataRepVo | FaceDataRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**FaceDataRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|namespace | 命名空间:最大12个字符,支持小写字母、数字和下划线的组合 |string | |
+|collectionName | 集合名称:最大24个字符,支持小写字母、数字和下划线的组合 |string | |
+|sampleId | 样本ID:最大32个字符,支持小写字母、数字和下划线的组合 |string | |
+|faceId | 人脸ID |string | |
+|faceScore | 人脸人数质量 |number(float) | |
+|faceData | 扩展字段 |array | FieldKeyValue |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|key | 字段名,与创建集合时给定的字段名一致 |string | |
+|value | 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 |object | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«FaceDataRepVo»|
+## 2、根据条件删除人脸数据
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/face/delete`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|collectionName| 集合名称 | query | true |string | |
+|faceId| 人脸ID | query | true |string | |
+|namespace| 命名空间 | query | true |string | |
+|sampleId| 样本ID | query | true |string | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": true
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |boolean | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«boolean»|
+# 04、人脸搜索服务
+
+## 1、人脸搜索M:N
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/search/do`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+**请求示例**:
+```json
+{
+ "namespace": "",
+ "collectionName": "",
+ "imageBase64": "",
+ "faceScoreThreshold": 0,
+ "confidenceThreshold": 0,
+ "limit": 0,
+ "maxFaceNum": 0
+}
+```
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|search| 人脸搜索参数 | body | true |FaceSearchReqVo | FaceSearchReqVo |
+
+**schema属性说明**
+
+
+
+**FaceSearchReqVo**
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|namespace| 命名空间 | body | true |string | |
+|collectionName| 集合名称 | body | true |string | |
+|imageBase64| 图像Base64编码值 | body | true |string | |
+|faceScoreThreshold| 人脸质量分数阈值,范围:[0,100]:默认0。当设置为0时,会默认使用当前模型的默认值,该方法为推荐使用方式 | body | false |number(float) | |
+|confidenceThreshold| 人脸匹配分数阈值,范围:[-100,100]:默认0 | body | false |number(float) | |
+|limit| 最大搜索条数:默认5 | body | false |integer(int32) | |
+|maxFaceNum| 对输入图像中多少个人脸进行检索比对:默认5 | body | false |integer(int32) | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": [
+ {
+ "location": {
+ "x": 0,
+ "y": 0,
+ "w": 0,
+ "h": 0
+ },
+ "faceScore": 0,
+ "match": [
+ {
+ "sampleId": "",
+ "faceId": "",
+ "faceScore": 0,
+ "distance": 0,
+ "confidence": 0,
+ "sampleData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ],
+ "faceData": [
+ {
+ "key": "",
+ "value": {}
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |array | FaceSearchRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**FaceSearchRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|location | 人脸位置信息 |FaceLocation | FaceLocation |
+|faceScore | 人脸分数:[0,100] |number(float) | |
+|match | 匹配的人脸列表 |array | SampleFaceVo |
+
+**FaceLocation**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|x | 左上角x坐标 |integer(int32) | |
+|y | 左上角y坐标 |integer(int32) | |
+|w | 人脸宽度 |integer(int32) | |
+|h | 人脸高度 |integer(int32) | |
+
+**SampleFaceVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|sampleId | 样本ID |string | |
+|faceId | 人脸ID |string | |
+|faceScore | 人脸分数:[0,100] |number(float) | |
+|distance | 向量距离:>=0 |number(float) | |
+|confidence | 转换后的置信度:[-100,100],值越大,相似度越高。 |number(float) | |
+|sampleData | 样本扩展的额外数据 |array | FieldKeyValue |
+|faceData | 人脸扩展的额外数据 |array | FieldKeyValue |
+
+**FieldKeyValue**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|key | 字段名,与创建集合时给定的字段名一致 |string | |
+|value | 字段值,与创建集合时给定的类型一致,若为字符串,最大为512个字符 |object | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«List«FaceSearchRepVo»»|
+# 05、人脸比对服务
+
+## 1、人脸比对1:1
+
+
+**接口描述**:
+
+
+**接口地址**:`/visual/compare/do`
+
+
+**请求方式**:`POST`
+
+
+**consumes**:`["application/json"]`
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+
+| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
+| ------------ | -------------------------------- |-----------|--------|----|--- |
+|faceScoreThreshold| 人脸质量分数阈值,范围:[0,100]:默认0。当设置为0时,会默认使用当前模型的默认值,该方法为推荐使用方式 | query | false |number | |
+|imageBase64A| 图像A的Base64编码值 | query | true |string | |
+|imageBase64B| 图像B的Base64编码值 | query | true |string | |
+|needFaceInfo| 是否需要人脸信息,默认为:true | query | false |boolean | |
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": {
+ "distance": 0,
+ "confidence": 0,
+ "faceInfo": {
+ "faceScoreA": 0,
+ "faceScoreB": 0,
+ "locationA": {
+ "x": 0,
+ "y": 0,
+ "w": 0,
+ "h": 0
+ },
+ "locationB": {
+ "x": 0,
+ "y": 0,
+ "w": 0,
+ "h": 0
+ }
+ }
+ }
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |FaceCompareRepVo | FaceCompareRepVo |
+
+
+
+**schema属性说明**
+
+
+
+
+**FaceCompareRepVo**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|distance | 向量欧式距离:>=0 |number(float) | |
+|confidence | 余弦距离转换后的置信度:[-100,100],值越大,相似度越高。 |number(float) | |
+|faceInfo | 人脸信息,参数needFaceInfo=false时,值为null |CompareFace | CompareFace |
+
+**CompareFace**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|faceScoreA | A图片人脸分数:[0,100] |number(float) | |
+|faceScoreB | B图片人脸分数:[0,100] |number(float) | |
+|locationA | A图片人脸位置信息 |FaceLocation | FaceLocation |
+|locationB | B图片人脸位置信息 |FaceLocation | FaceLocation |
+
+**FaceLocation**
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | ------------------|--------|----------- |
+|x | 左上角x坐标 |integer(int32) | |
+|y | 左上角y坐标 |integer(int32) | |
+|w | 人脸宽度 |integer(int32) | |
+|h | 人脸高度 |integer(int32) | |
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«FaceCompareRepVo»|
+# 06、公共服务-健康检测
+
+## 公共-服务健康检测
+
+
+**接口描述**:
+
+
+**接口地址**:`/common/health/check`
+
+
+**请求方式**:`GET`
+
+
+**consumes**:``
+
+
+**produces**:`["*/*"]`
+
+
+
+**请求参数**:
+暂无
+
+
+
+**响应示例**:
+
+```json
+{
+ "code": 0,
+ "message": "",
+ "data": ""
+}
+```
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| ------------ | -------------------|-------|----------- |
+|code| 返回代码 |integer(int32) | integer(int32) |
+|message| 返回信息 |string | |
+|data| 数据信息 |string | |
+
+
+
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| ------------ | -------------------------------- |---------------------- |
+| 200 | OK |ResponseInfo«string»|