mirror of
https://gitee.com/open-visual/face-search.git
synced 2025-07-25 19:41:42 +08:00
update:更新scrfd模型,并且对其增加旋转角度检测功能,可通过参数控制是否启用。
This commit is contained in:
parent
5493302c59
commit
a4fb5298de
@ -27,7 +27,11 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
//给人脸框一个默认的缩放
|
||||
public final static float defBoxScale = 1.0f;
|
||||
//人脸框缩放参数KEY
|
||||
public final static String boxScaleParamKey = "boxScale";
|
||||
public final static String scrfdFaceboxScaleParamKey = "scrfdFaceboxScale";
|
||||
//人脸框默认需要进行角度检测
|
||||
public final static boolean defNeedCheckFaceAngle = true;
|
||||
//是否需要进行角度检测的参数KEY
|
||||
public final static String scrfdFaceNeedCheckFaceAngleParamKey = "scrfdFaceNeedCheckFaceAngle";
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
@ -73,7 +77,10 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
.blobFromImageAndDoReleaseMat(1.0/128, new Scalar(127.5, 127.5, 127.5), true)
|
||||
.to4dFloatOnnxTensorAndDoReleaseMat(true);
|
||||
output = getSession().run(Collections.singletonMap(getInputName(), tensor));
|
||||
return fitterBoxes(output, scoreTh, iouTh, tensor.getInfo().getShape()[3], imgScale, boxScale);
|
||||
//获取人脸信息
|
||||
List<FaceInfo> faceInfos = fitterBoxes(output, scoreTh, iouTh, tensor.getInfo().getShape()[3], imgScale, boxScale);
|
||||
//对人脸进行角度检查
|
||||
return this.checkFaceAngle(faceInfos, this.getNeedCheckFaceAngle(params));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}finally {
|
||||
@ -152,11 +159,68 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
return faces;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对人脸进行角度检测,这里通过5个关键点来确定当前人脸的角度
|
||||
* @param faceInfos 人脸信息
|
||||
* @param needCheckFaceAngle 是否启用检测
|
||||
* @return
|
||||
*/
|
||||
private List<FaceInfo> checkFaceAngle(List<FaceInfo> faceInfos, boolean needCheckFaceAngle){
|
||||
if(!needCheckFaceAngle || null == faceInfos || faceInfos.isEmpty()){
|
||||
return faceInfos;
|
||||
}
|
||||
for(FaceInfo faceInfo : faceInfos){
|
||||
//计算当前人脸的角度数据
|
||||
float ax1 = faceInfo.points.get(1).x;
|
||||
float ay1 = faceInfo.points.get(1).y;
|
||||
float ax2 = faceInfo.points.get(0).x;
|
||||
float ay2 = faceInfo.points.get(0).y;
|
||||
int atan = Double.valueOf(Math.atan2((ay2-ay1), (ax2-ax1)) / Math.PI * 180).intValue();
|
||||
int angle = (180 - atan + 360) % 360;
|
||||
int ki = (angle + 45) % 360 / 90;
|
||||
int rotate = angle - (90 * ki); //
|
||||
float scaling = 1 + Double.valueOf(Math.abs(Math.sin(Math.toRadians(rotate)))).floatValue() / 3;
|
||||
faceInfo.angle = angle;
|
||||
//重组坐标点, 旋转及缩放
|
||||
if(ki == 0){
|
||||
FaceInfo.Point leftTop = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y1());
|
||||
FaceInfo.Point rightTop = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y1());
|
||||
FaceInfo.Point rightBottom = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y2());
|
||||
FaceInfo.Point leftBottom = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y2());
|
||||
faceInfo.box = new FaceInfo.FaceBox(leftTop, rightTop, rightBottom, leftBottom);
|
||||
faceInfo.box = faceInfo.box.rotate(rotate).scaling(scaling).rotate(-angle);
|
||||
}else if(ki == 1){
|
||||
FaceInfo.Point leftTop = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y2());
|
||||
FaceInfo.Point rightTop = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y1());
|
||||
FaceInfo.Point rightBottom = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y1());
|
||||
FaceInfo.Point leftBottom = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y2());
|
||||
faceInfo.box = new FaceInfo.FaceBox(leftTop, rightTop, rightBottom, leftBottom);
|
||||
faceInfo.box = faceInfo.box.rotate(rotate).scaling(scaling).rotate(-angle);
|
||||
}else if(ki == 2){
|
||||
FaceInfo.Point leftTop = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y2());
|
||||
FaceInfo.Point rightTop = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y2());
|
||||
FaceInfo.Point rightBottom = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y1());
|
||||
FaceInfo.Point leftBottom = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y1());
|
||||
faceInfo.box = new FaceInfo.FaceBox(leftTop, rightTop, rightBottom, leftBottom);
|
||||
faceInfo.box = faceInfo.box.rotate(rotate).scaling(scaling).rotate(-angle);
|
||||
}else if(ki == 3){
|
||||
FaceInfo.Point leftTop = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y1());
|
||||
FaceInfo.Point rightTop = FaceInfo.Point.build(faceInfo.box.x2(),faceInfo.box.y2());
|
||||
FaceInfo.Point rightBottom = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y2());
|
||||
FaceInfo.Point leftBottom = FaceInfo.Point.build(faceInfo.box.x1(),faceInfo.box.y1());
|
||||
faceInfo.box = new FaceInfo.FaceBox(leftTop, rightTop, rightBottom, leftBottom);
|
||||
faceInfo.box = faceInfo.box.rotate(rotate).scaling(scaling).rotate(-angle);
|
||||
}
|
||||
}
|
||||
return faceInfos;
|
||||
}
|
||||
|
||||
/**人脸框的默认缩放比例**/
|
||||
private float getBoxScale(Map<String, Object> params){
|
||||
float boxScale = 0;
|
||||
try {
|
||||
if(null != params && params.containsKey(boxScaleParamKey)){
|
||||
Object value = params.get(boxScaleParamKey);
|
||||
if(null != params && params.containsKey(scrfdFaceboxScaleParamKey)){
|
||||
Object value = params.get(scrfdFaceboxScaleParamKey);
|
||||
if(null != value){
|
||||
if (value instanceof Number){
|
||||
boxScale = ((Number) value).floatValue();
|
||||
@ -168,4 +232,24 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
}catch (Exception e){}
|
||||
return boxScale > 0 ? boxScale : defBoxScale;
|
||||
}
|
||||
|
||||
/**获取是否需要进行角度探测**/
|
||||
private boolean getNeedCheckFaceAngle(Map<String, Object> params){
|
||||
boolean needCheckFaceAngle = defNeedCheckFaceAngle;
|
||||
try {
|
||||
if(null != params && params.containsKey(scrfdFaceNeedCheckFaceAngleParamKey)){
|
||||
Object value = params.get(scrfdFaceNeedCheckFaceAngleParamKey);
|
||||
if(null != value){
|
||||
if (value instanceof Boolean){
|
||||
needCheckFaceAngle = (boolean) value;
|
||||
}else{
|
||||
needCheckFaceAngle = Boolean.parseBoolean(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return needCheckFaceAngle;
|
||||
}
|
||||
}
|
||||
|
BIN
face-search-core/src/main/resources/model/onnx/detection_face_scrfd/scrfd_500m_bnkps.onnx
Executable file → Normal file
BIN
face-search-core/src/main/resources/model/onnx/detection_face_scrfd/scrfd_500m_bnkps.onnx
Executable file → Normal file
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
Loading…
x
Reference in New Issue
Block a user