net.gdface.cassdk.NativeFaceInfo Maven / Gradle / Ivy
package net.gdface.cassdk;
import static net.gdface.utils.BufferUtils.*;
import net.gdface.sdk.CodeInfo;
import net.gdface.sdk.EyeInfo;
import net.gdface.sdk.FAngle;
import net.gdface.sdk.FInt2;
import net.gdface.sdk.FRect;
import net.gdface.utils.Assert;
import static net.gdface.cassdk.CasAndroidConfigProvider.*;
/**
* 人脸检测信息描述对象
* 实现原始人脸检测数据(double[])的解析,以及与{@link CodeInfo}实例的相互转换
* @author guyadong
*
*/
public class NativeFaceInfo extends CodeInfo {
/**
* 人脸检测数据(double数组)的字段名索引
* @author guyadong
*
*/
enum FieldIndex{
/* 人脸位置矩形左上角 x */FRECT_LEFT,
/* 人脸位置矩形左上角 y */FRECT_TOP,
/* 人脸位置矩形宽度 */FRECT_WIDTH,
/* 人脸位置矩形高度 */FRECT_HEIGHT,
/* 质量评价 0-1 1 为质量最高 高分辨率建议阈值 0.5 低分辨率建议阈值 0.3,与模糊度与亮度相关 */FD_QUALITY,
/* 翻滚角,绕 z 轴旋转的角度,-90°~ +90°, 左为负,右为正(观察者视角)*/FANGLE_ROLL,
/* 偏航角,绕 y 轴旋转的角度,-90°~ +90°, 左为负,右为正(观察者视角)*/FANGLE_YAW,
/* 俯仰角,绕 x 轴旋转的角度, -90°~ +90°, 上为正,下为负(观察者视角)*/FANGLE_PITCH,
/* 清晰度,0-100 越大越清晰 */FD_CLARITY,
/* 明亮度,0-255 越大亮度越高 */FD_BRIGHTNESS,
/* 人脸关键点 0 x坐标:左眼皮上端 */FD_POINT0_X,
/* 人脸关键点 0 y坐标:左眼皮上端 */FD_POINT0_Y,
/* 人脸关键点 1 x坐标:右眼皮上端 */FD_POINT1_X,
/* 人脸关键点 1 y坐标:右眼皮上端 */FD_POINT1_Y,
FD_POINT2_X,
FD_POINT2_Y,
FD_POINT3_X,
FD_POINT3_Y,
FD_POINT4_X,
FD_POINT4_Y,
FD_POINT5_X,
FD_POINT5_Y,
FD_POINT6_X,
FD_POINT6_Y,
/* 人脸关键点 7 x坐标:鼻尖 */FD_POINT7_X,
/* 人脸关键点 7 y坐标:鼻尖 */FD_POINT7_Y,
FD_POINT8_X,
FD_POINT8_Y,
FD_POINT9_X,
FD_POINT9_Y,
/* 人脸关键点 10 x坐标:左嘴角 */FD_POINT10_X,
/* 人脸关键点 10 y坐标:左嘴角 */FD_POINT10_Y,
/* 人脸关键点 11 x坐标:右嘴角 */FD_POINT11_X,
/* 人脸关键点 11 y坐标:右嘴角 */FD_POINT11_Y,
FD_POINT12_X,
FD_POINT12_Y,
FD_POINT13_X,
FD_POINT13_Y,
FD_POINT14_X,
FD_POINT14_Y,
FD_POINT15_X,
FD_POINT15_Y,
/* 人脸关键点 16 x坐标:左眼内角 */FD_POINT16_X,
/* 人脸关键点 16 y坐标:左眼内角 */FD_POINT16_Y,
/* 人脸关键点 17 x坐标:左眼皮下端 */FD_POINT17_X,
/* 人脸关键点 17 y坐标:左眼皮下端 */FD_POINT17_Y,
/* 人脸关键点 18 x坐标:左眼外角 */FD_POINT18_X,
/* 人脸关键点 18 y坐标:左眼外角 */FD_POINT18_Y,
/* 人脸关键点 19 x坐标:右眼外角 */FD_POINT19_X,
/* 人脸关键点 19 y坐标:右眼外角 */FD_POINT19_Y,
/* 人脸关键点 20 x坐标:右眼皮下端 */FD_POINT20_X,
/* 人脸关键点 20 y坐标:右眼皮下端 */FD_POINT20_Y,
/* 人脸关键点 21 x坐标:右眼内角 */FD_POINT21_X,
/* 人脸关键点 21 y坐标:右眼内角 */FD_POINT21_Y,
FD_POINT22_X,
FD_POINT22_Y,
FD_POINT23_X,
FD_POINT23_Y,
FD_POINT24_X,
FD_POINT24_Y,
FD_CONFIDENCE
}
private static final long serialVersionUID = 1L;
/**
* 质量评价 0-1 1 为质量最高 高分辨率建议阈值 0.5 低分辨率建议阈值 0.3,与模糊度与亮度相关
*/
double quality;
/**
* 0-100 越大越清晰
*/
int clarity;
/**
* 明亮度,0-255 越大亮度越高
*/
int brightness;
/**
* 人脸检测框置信度(与{@link FAngle#getConfidence()}相同)
*/
double confidence;
/**
* 从JNI动态库返回的原始人脸检测数据 double[61]
*/
double nativeData[];
public NativeFaceInfo(double[] nativeData) {
this(nativeData,0);
}
/**
* 从原始人脸信息数组构造实例
* @param nativeData 原始数据
* @param start 数据起始索引
*/
public NativeFaceInfo(double[] nativeData,int start) {
super();
init(nativeData, start);
}
public NativeFaceInfo(CodeInfo codeInfo) {
super();
Assert.notNull(codeInfo, "codeinfo");
byte[] facialData = codeInfo.getFacialData();
Assert.notNull(facialData, "facialData");
init(asDoubleArray(facialData), 0);
}
/**
* 从原始人脸检测数据(61个double)解析为当前对象对应字段
* @param nativeData
* @param start
*/
private void init(double[] nativeData, int start){
Assert.isTrue(start>=0,"start>=0", "invalid start");
Assert.isTrue(nativeData!=null && nativeData.length-start>=FDDATA_LEN,
"nativeData!=null && nativeData.length-start>=CaffeMobile.FDDATA_LEN","invalid nativeData");
this.nativeData = new double[FDDATA_LEN];
System.arraycopy(nativeData, start, this.nativeData, 0, this.nativeData.length);
////////////////////
FRect pos = getPos();
if(pos == null){
pos = new FRect();
}
pos.setLeft((int) this.nativeData[FieldIndex.FRECT_LEFT.ordinal()]);
pos.setTop((int) this.nativeData[FieldIndex.FRECT_TOP.ordinal()]);
pos.setWidth((int) this.nativeData[FieldIndex.FRECT_WIDTH.ordinal()]);
pos.setHeight((int) this.nativeData[FieldIndex.FRECT_HEIGHT.ordinal()]);
setPos(pos);
/////////////////////////
FAngle angle = getAngle();
if(angle == null){
angle = new FAngle();
}
angle.setRoll((int)this.nativeData[FieldIndex.FANGLE_ROLL.ordinal()]);
angle.setYaw((int)this.nativeData[FieldIndex.FANGLE_YAW.ordinal()]);
angle.setPitch((int)this.nativeData[FieldIndex.FANGLE_PITCH.ordinal()]);
angle.setConfidence((int)(this.nativeData[FieldIndex.FD_CONFIDENCE.ordinal()]*100));
setAngle(angle);
//////////////////////////
EyeInfo ei = getEi();
if(ei == null){
ei = new EyeInfo();
}
{
// 计算左右眼中间点位置
double lx = (this.nativeData[FieldIndex.FD_POINT0_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT16_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT17_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT18_X.ordinal()])/4;
double ly = (this.nativeData[FieldIndex.FD_POINT0_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT16_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT17_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT18_Y.ordinal()])/4;
double rx = (this.nativeData[FieldIndex.FD_POINT1_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT19_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT20_X.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT21_X.ordinal()])/4;
double ry = (this.nativeData[FieldIndex.FD_POINT1_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT19_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT20_Y.ordinal()]
+ this.nativeData[FieldIndex.FD_POINT21_Y.ordinal()])/4;
ei.setLeftx((int)lx);
ei.setLefty((int)ly);
ei.setRightx((int)rx);
ei.setRighty((int)ry);
setEi(ei);
}
//////////////////////////
FInt2 mouth = getMouth();
if(mouth == null){
mouth = new FInt2();
}
mouth.setX((int)this.nativeData[FieldIndex.FD_POINT14_X.ordinal()]);
mouth.setY((int)this.nativeData[FieldIndex.FD_POINT14_Y.ordinal()]);
setMouth(mouth);
////////////////////////
FInt2 nose = getNose();
if(nose == null){
nose = new FInt2();
}
nose.setX((int)this.nativeData[FieldIndex.FD_POINT7_X.ordinal()]);
nose.setY((int)this.nativeData[FieldIndex.FD_POINT7_Y.ordinal()]);
setNose(nose);
//////////////////////
quality = this.nativeData[FieldIndex.FD_QUALITY.ordinal()];
clarity = (int) this.nativeData[FieldIndex.FD_CLARITY.ordinal()];
brightness = (int) this.nativeData[FieldIndex.FD_BRIGHTNESS.ordinal()];
confidence = this.nativeData[FieldIndex.FD_CONFIDENCE.ordinal()];
setFacialData(asByteArray(this.nativeData));
}
/**
* {@link CodeInfo} 转换为{@link NativeFaceInfo}
* @param code
* @return
*/
public static NativeFaceInfo toNative(CodeInfo code){
if(code == null){
return null;
}
if(code instanceof NativeFaceInfo){
return (NativeFaceInfo)code;
}
return new NativeFaceInfo(code);
}
public double getQuality() {
return quality;
}
public int getClarity() {
return clarity;
}
public int getBrightness() {
return brightness;
}
public double getConfidence() {
return confidence;
}
public double[] getNativeData() {
return nativeData;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy