All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.facelib.mtfsdk.NativeFaceInfo Maven / Gradle / Ivy

There is a newer version: 3.0.6
Show newest version
package net.facelib.mtfsdk;

import static net.facelib.mtfsdk.NativeFaceInfo.FieldIndex.*;
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;

/**
 * 人脸检测信息描述对象
* 实现原始人脸检测数据(double[])的解析,以及与{@link CodeInfo}实例的相互转换 * @author guyadong * */ public class NativeFaceInfo extends CodeInfo implements MtfsdkConstant { /** * 人脸检测数据(double数组)的字段名索引 * @author guyadong * */ enum FieldIndex{ /* 人脸位置矩形左上角 x */FRECT_LEFT, /* 人脸位置矩形左上角 y */FRECT_TOP, /* 人脸位置矩形宽度 */FRECT_WIDTH, /* 人脸位置矩形高度 */FRECT_HEIGHT, /* 人脸关键点 0 x坐标:左眼 */FD_LEFT_EYE_X, /* 人脸关键点 0 y坐标:左眼 */FD_LEFT_EYE_Y, /* 人脸关键点 1 x坐标:右眼 */FD_RIGHT_EYE_X, /* 人脸关键点 1 y坐标:右眼 */FD_RIGHT_EYE_Y, /* 人脸关键点 2 x坐标:鼻子 */FD_NOSE_X, /* 人脸关键点 2 y坐标:鼻子 */FD_NOSE_Y, /* 人脸关键点 3 x坐标:左嘴角*/FD_MOUTH_LEFT_X, /* 人脸关键点 3 y坐标:左嘴角 */FD_MOUTH_LEFT_Y, /* 人脸关键点 4 x坐标:右嘴角*/FD_MOUTH_RIGHT_X, /* 人脸关键点 4 y坐标:右嘴角 */FD_MOUTH_RIGHT_Y, /* 置信度 */FD_CONFIDENCE, /* 人脸框预测x步进值,只有在使用位置关联函数才有赋值 */FD_FACE_OFFSET_Y, /* 人脸框预测y步进值,只有在使用位置关联函数才有赋值 */FD_FACE_OFFSET_X, /* 人脸姿态角度:旋转角roll */FD_ANGLE_ROLL, /* 人脸姿态角度:偏转角yaw */FD_ANGLE_YAW, /* 人脸姿态角度:倾斜角pitch */FD_ANGLE_PITCH, /* 识别标记(是否已经识别) */FD_DETECTED_FLAG, } private static final long serialVersionUID = 1L; /** * 人脸检测框置信度(与{@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); setOffset(codeInfo.getOffset()); } /** * 从原始人脸检测数据(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[FRECT_LEFT.ordinal()]); pos.setTop((int) this.nativeData[FRECT_TOP.ordinal()]); pos.setWidth((int) this.nativeData[FRECT_WIDTH.ordinal()]); pos.setHeight((int) this.nativeData[FRECT_HEIGHT.ordinal()]); setPos(pos); ///////////////////////// FAngle angle = getAngle(); if(angle == null){ angle = new FAngle(); } angle.setRoll((int) this.nativeData[FD_ANGLE_ROLL.ordinal()]); angle.setYaw((int) this.nativeData[FD_ANGLE_YAW.ordinal()]); angle.setPitch((int) this.nativeData[FD_ANGLE_PITCH.ordinal()]); angle.setConfidence((int)(this.nativeData[FD_CONFIDENCE.ordinal()]*100)); setAngle(angle); ////////////////////////// EyeInfo ei = getEi(); if(ei == null){ ei = new EyeInfo(); } ei.setLeftx((int)this.nativeData[FD_LEFT_EYE_X.ordinal()]); ei.setLefty((int)this.nativeData[FD_LEFT_EYE_Y.ordinal()]); ei.setRightx((int)this.nativeData[FD_RIGHT_EYE_X.ordinal()]); ei.setRighty((int)this.nativeData[FD_RIGHT_EYE_Y.ordinal()]); setEi(ei); ////////////////////////// FInt2 mouth = getMouth(); if(mouth == null){ mouth = new FInt2(); } { // 计算左右眼中间点位置 double x = (this.nativeData[FD_MOUTH_LEFT_X.ordinal()] + this.nativeData[FD_MOUTH_RIGHT_X.ordinal()])/2; double y = (this.nativeData[FD_MOUTH_LEFT_Y.ordinal()] + this.nativeData[FD_MOUTH_RIGHT_Y.ordinal()])/2; mouth.setX((int)x); mouth.setY((int)y); setMouth(mouth); } //////////////////////// FInt2 nose = getNose(); if(nose == null){ nose = new FInt2(); } nose.setX((int)this.nativeData[FD_NOSE_X.ordinal()]); nose.setY((int)this.nativeData[FD_NOSE_Y.ordinal()]); setNose(nose); ////////////////////// confidence = this.nativeData[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; } CodeInfo faceInfo = code instanceof NativeFaceInfo ? code : new NativeFaceInfo(code); return (NativeFaceInfo) faceInfo.relocate(); } public static long getSerialversionuid() { return serialVersionUID; } public double getConfidence() { return confidence; } /** * @return原始人脸检测数据 double[61] */ public double[] getNativeData() { return nativeData; } @Override protected void relocateFacialData() { if(null != getOffset() && !ZERO_OFFSET.equals(getOffset()) ){ double[] ndata = this.nativeData; if(null == ndata){ ndata = asDoubleArray(getFacialData()); } if(null != ndata){ int ox = getOffset().getX(); int oy = getOffset().getY(); try { ndata[FRECT_LEFT.ordinal()] -= ox; ndata[FRECT_TOP.ordinal()] -= oy; ndata[FD_LEFT_EYE_X.ordinal()] -= ox; ndata[FD_LEFT_EYE_Y.ordinal()] -= oy; ndata[FD_RIGHT_EYE_X.ordinal()] -= ox; ndata[FD_RIGHT_EYE_Y.ordinal()] -= oy; ndata[FD_NOSE_X.ordinal()] -= ox; ndata[FD_NOSE_Y.ordinal()] -= oy; ndata[FD_MOUTH_LEFT_X.ordinal()] -= ox; ndata[FD_MOUTH_LEFT_Y.ordinal()] -= oy; ndata[FD_MOUTH_RIGHT_X.ordinal()] -= ox; ndata[FD_MOUTH_RIGHT_Y.ordinal()] -= oy; } catch (IndexOutOfBoundsException e) { // 数组访问越界则抛出异常 throw new IllegalStateException( String.format("INVALID nativeData %d float required cased by IndexOutOfBoundsException", FDDATA_LEN)); } if(null != getFacialData()){ setFacialData(asByteArray(ndata)); } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy