You need to enable JavaScript to run this app.
导航
3D人脸算法
最近更新时间:2025.03.17 14:05:11首次发布时间:2025.03.17 14:05:11
我的收藏
有用
有用
无用
无用
简介

3d 人脸在基础的2d 人脸关键点之上,可以得到3d的人脸关键点。

技术规格
支持平台Android、iOS
支持输入格式RGBA8888、BGRA8888
内存占用<42M (测试设备OPPO R11)
检测速度<5ms(测试设备OPPO R11)
C接口说明

详细接口说明查看头文件: bef_effect_ai_facefitting.h

1.创建3dmesh算法句柄

BEF_SDK_API
bef_effect_result_t bef_effect_ai_facefitting_create(bef_ai_facefitting_handle *handle);

参数说明

参数名参数类型参数说明
handlebef_ai_facefitting_handle*创建的3D mesh 算法句柄
BEF_SDK_API
bef_effect_result_t bef_effect_ai_facefitting_init(bef_ai_facefitting_handle handle, const char *model_path);

参数说明

参数名参数类型参数说明
handlebef_ai_facefitting_handle创建的3D mesh 算法句柄
model_pathconst char *模型的路径

返回值
成功返回 BEF_RESULT_SUC, 失败返回相应错误码, 具体请参考 bef_effect_ai_public_define.h

2.3d mesh 算法执行

/**
 * 输入人脸id和106点关键点,返回mesh信息
 * @param handle
 * @param args  输入
 * @param ret   输出,该部分内存空间生命周期由sdk管理,会在内部分配空间
 * @return
 */
BEF_SDK_API
bef_effect_result_t bef_effect_ai_do_fitting_3dmesh(bef_ai_facefitting_handle handle, bef_ai_facefitting_args* args, bef_ai_facefitting_result* ret);

// pack input
typedef struct {
    bef_ai_facefitting_landmark_info face_landmark_info[BEF_FITTING_MAX_FACE];
    int face_landmark_info_count;                   //输入的人脸的个数
    int view_width;
    int view_height;
    float cameraParams[3];          // focal_length, centerx, centery
} bef_ai_facefitting_args;


//pack output
typedef struct {
    bef_ai_facefitting_mesh_info face_mesh_info[BEF_FITTING_MAX_FACE];
    int face_mesh_info_count;               //返回mesh的个数, 请使用face_mesh_info_count来取face_mesh_info的前几个的内容,不要越界!!
    bef_ai_facefitting_mesh_config face_mesh_config;
} bef_ai_facefitting_result;

//与模型文件一一对应, 内容不会改变的, 由sdk管理内存分配与释放
typedef struct {
    int version_code;                           // 模型的版本号
    float* uv;                            // 标准展开图像的 uv坐标, 由sdk管理内存分配与释放
    int uv_count;                               // uv数组的长度
    unsigned short* flist;                // 3d模型顶点 的索引数组(face),  由sdk管理内存分配与释放
    int flist_count;                            // flist数组的长度
    unsigned short* landmark_triangle;    // landmark做三角剖分后的三角形数组,    由sdk管理内存分配与释放
    int landmark_triangle_count;                // landmark数组的长度

    int num_vertex;                             // = uv_count/2 = vertex_count/3    表示顶点元素的个数,      uv是标准3d模型的展开后的2d坐标
    int num_flist;                              // = flist_count / 3                面的个数
    int num_landmark_triangle;                  // = landmark_triangle_count / 2    三角形的个数
    int mum_landmark;                           // = landmark_count / 3             landmrk的个数
    int num_param;                              // = param_count                    求解参数的个数
} bef_ai_facefitting_mesh_config;

// pack landmark
typedef struct {
    int id;                     // 人脸的id
    bef_ai_fpoint * landmark106;         // 106点数组               required
    bool eye_lv2;              // true 使用二级网络的眼睛             optional
    bool eyebrow_lv2;          // true 使用二级网络的眉毛             optional
    bool lips_lv2;             // true 使用二级网络的嘴巴             optional
    bool iris_lv2;             // true 使用二级网络的iris             optional
    bef_ai_fpoint * eye_left;       // 左眼关键点                  optional
    bef_ai_fpoint * eye_right;      // 右眼关键点                  optional
    bef_ai_fpoint * eyebrow_left;   // 左眉毛关键点                 optional
    bef_ai_fpoint * eyebrow_right;  // 右眉毛关键点                 optional
    bef_ai_fpoint * lips;           // 嘴唇关键点                  optional
    bef_ai_fpoint * left_iris;      // 左虹膜关键点             optional
    bef_ai_fpoint * right_iris;     // 右虹膜关键点             optional
} bef_ai_facefitting_landmark_info;

//manager memory by sdk, count与num的解释:count表示数组的长度,num表示数组具有多少元素, 例如 一个2d坐标点(x,y)数组  [x,y,x,y,x,y,x,y]  ===> count = 8, num = 4
typedef struct {
    int id;                     // 人脸sdk返回的id,用来表示这个mesh属于哪一个人脸
    float* vertex;        // 3d模型的顶点,  由sdk管理内存分配与释放
    int vertex_count;           // vertex数组的长度
    float* landmark;      // 3d模型投影会图像坐标的landmark坐标值数组. 由sdk管理内存分配与释放
    int landmark_count;         // landmark数组的长度
    float* param;         // 解优化的参数,[scale,rotatex, rotatey, rotatez, tx, ty, alpha0, alpha1 ......], manager memory by sdk
    int param_count;            // param数组的长度
    float mvp[16];              // 将vertex变为ndc坐标的矩阵
    float model[16];            // 包括了对原始模型的旋转平移缩放的模型矩阵         正交投影下使用
    float * normal;       // 模型空间下的法线, 长度和vertex_count是一样的,   由sdk管理内存分配与释放
    float * tangent;      // 模型空间下的切线, 长度和vertex_count是一样的,   由sdk管理内存分配与释放
    float * bitangent;    // 模型空间下的副切线, 长度和vertex_count是一样的,  由sdk管理内存分配与释放
    float rvec[3];              // opencv solvepnp输出的旋转向量
    float tvec[3];              // opencv solvepnp输出的平移向量
} bef_ai_facefitting_mesh_info;


参数说明

参数名参数类型参数说明
handlebef_image_quality_enhancement_handle3D mesh 算法句柄
argsconst bef_ai_facefitting_args*人脸算法的结果作为输入
retbef_ai_facefitting_result*3d mesh 算法输出

返回值
成功返回 BEF_RESULT_SUC, 失败返回相应错误码, 具体请参考 bef_effect_ai_public_define.h

3.释放句柄

BEF_SDK_API bef_effect_result_t
bef_effect_result_t bef_effect_ai_facefitting_release(bef_ai_facefitting_handle handle);

参数说明

参数名参数类型参数说明
handlebef_effect_ai_facefitting_release3d mesh 算法的句柄

返回值
成功返回 BEF_RESULT_SUC, 失败返回相应错误码, 具体请参考 bef_effect_ai_public_define.h

4.3d mesh 算法授权

// 离线license检测方式
BEF_SDK_API bef_effect_result_t
bef_effect_ai_facefitting_check_license(
    bef_ai_facefitting_handle handle, 
    const char* license_path);

BEF_SDK_API bef_effect_result_t
bef_effect_ai_facefitting_check_license(JNIEnv *env, jobject context, bef_ai_facefitting_handle handle, const char* licensePath);

// 在线license检测方式
BEF_SDK_API bef_effect_result_t
bef_effect_ai_facefitting_check_onine_license(
    bef_ai_facefitting_handle handle, 
    const char* license_path);

参数说明

参数名参数类型参数说明
handlebef_ai_facefitting_handle3d mesh 算法句柄
licensePathconst char *授权文件字符串

返回值
成功返回 BEF_RESULT_SUC, 失败返回相应错误码, 具体请参考 bef_effect_ai_public_define.h

5.3d mesh 算法分配和释放结果

BEF_SDK_API bef_effect_result_t
bef_effect_ai_facefitting_malloc_result(bef_ai_facefitting_handle handle, bef_ai_facefitting_result ** result);


BEF_SDK_API bef_effect_result_t
bef_effect_ai_facefitting_free_result(bef_ai_facefitting_handle handle, bef_ai_facefitting_result * result);

参数说明

参数名参数类型参数说明
handlebef_ai_facefitting_handle3d mesh 算法句柄
resultbef_ai_facefitting_result *算法结果结构体

6.3d mesh 算法设置参数

typedef enum {
    BEF_AI_FACEFITTING_Solver_Lambda = 1,      // Solver parameter
    BEF_AI_FACEFITTING_Solver_MaxIter = 2,
    BEF_AI_FACEFITTING_Solver_Eps = 3,
    BEF_AI_FACEFITTING_Solver_Ratio = 4,
    BEF_AI_FACEFITTING_Solver_Smooth = 5,
    BEF_AI_FACEFITTING_Solver_Camera_Type = 6,
    BEF_AI_FACEFITTING_Config_Cal_TB = 7,
    BEF_AI_FACEFITTING_Eyelash_Flag = 8,
    BEF_AI_FACEFITTING_Use_Semantic_Lmk = 9,
    BEF_AI_FACEFITTING_Mouth_BS_Limit = 10
} bef_ai_facefitting_param_type;

BEF_SDK_API
bef_effect_result_t bef_effect_ai_facefitting_set_param(bef_ai_facefitting_handle handle, bef_ai_facefitting_param_type type, float value);

参数说明

参数名参数类型参数说明
handlebef_ai_facefitting_handle3d mesh 算法句柄
typebef_ai_facefitting_param_type参数类型
valuefloat参数的值
Java 接口说明

接口说明
详细接口说明查看文件:com.bytedance.labcv.effectsdk.FaceFitting.java

1.初始化3d mesh 句柄

int init(Context context, String modelPath, String licensePath, boolean onlineLicense) 

参数说明

参数名参数类型参数说明
contextStringjava context
licensePathString授权文件绝对路径
onlineLicenseboolean授权类型

返回值
成功返回BEF_RESULT_SUC,否则返回对应的错误码
备注
关于InitConfig可参考com.bytedance.labcv.effectsdk.FaceFitting.java,并且其定义与C接口bef_effect_ai_facefitting保持一致。

2.face 3d mesh 算法处理

public int detect(BefFaceInfo faceInfo, int viewWidth, int viewHeight, float cameraParams[])

参数说明

参数名参数类型参数说明
faceInfoBefFaceInfo人脸结果信息
viewWidthint视口宽
viewHeightint视口的高
cameraParamsfloat[]相机参数

3.释放face 3d mesh句柄

public void destroy()

4.得到face 3d mesh结果

public FaceFittingResult getFaceFittingResult()

 public static class FaceFittingMeshInfo {
        public FaceFittingMeshInfo() {
        }

        public int getId() {
            return id;
        }

        public float[] getVertex() {
            return vertex;
        }

        public int getVertex_count() {
            return vertex_count;
        }

        public float[] getLandmark() {
            return landmark;
        }

        public int getLandmark_count() {
            return landmark_count;
        }

        public float[] getParam() {
            return param;
        }

        public int getParam_count() {
            return param_count;
        }

        public float[] getMvp() {
            return mvp;
        }

        public float[] getModel() {
            return model;
        }

        public float[] getNormal() {
            return normal;
        }

        public float[] getTangent() {
            return tangent;
        }

        public float[] getBitangent() {
            return bitangent;
        }

        public float[] getRvec() {
            return rvec;
        }

        public float[] getTvec() {
            return tvec;
        }

        int id;                     // 人脸sdk返回的id,用来表示这个mesh属于哪一个人脸
        float[] vertex;        // 3d模型的顶点,  由sdk管理内存分配与释放
        int vertex_count;           // vertex数组的长度
        float[] landmark;      // 3d模型投影会图像坐标的landmark坐标值数组. 由sdk管理内存分配与释放
        int landmark_count;         // landmark数组的长度
        float[] param;         // 解优化的参数,[scale,rotatex, rotatey, rotatez, tx, ty, alpha0, alpha1 ......], manager memory by sdk
        int param_count;            // param数组的长度
        float mvp[];              // 将vertex变为ndc坐标的矩阵
        float model[];            // 包括了对原始模型的旋转平移缩放的模型矩阵         正交投影下使用
        float [] normal;       // 模型空间下的法线, 长度和vertex_count是一样的,   由sdk管理内存分配与释放
        float [] tangent;      // 模型空间下的切线, 长度和vertex_count是一样的,   由sdk管理内存分配与释放
        float [] bitangent;    // 模型空间下的副切线, 长度和vertex_count是一样的,  由sdk管理内存分配与释放
        float rvec[];              // opencv solvepnp输出的旋转向量
        float tvec[];              // opencv solvepnp输出的平移向量
    };

    public static class FaceFittingMeshConfig {
        public FaceFittingMeshConfig() {
        }

        public int getVersion_code() {
            return version_code;
        }

        public float[] getUv() {
            return uv;
        }

        public int getUv_count() {
            return uv_count;
        }

        public short[] getFlist() {
            return flist;
        }

        public int getFlist_count() {
            return flist_count;
        }

        public short[] getLandmark_triangle() {
            return landmark_triangle;
        }

        public int getLandmark_triangle_count() {
            return landmark_triangle_count;
        }

        public int getNum_vertex() {
            return num_vertex;
        }

        public int getNum_flist() {
            return num_flist;
        }

        public int getNum_landmark_triangle() {
            return num_landmark_triangle;
        }

        public int getMum_landmark() {
            return mum_landmark;
        }

        public int getNum_param() {
            return num_param;
        }

        int version_code;                           // 模型的版本号
        float[] uv;                            // 标准展开图像的 uv坐标, 由sdk管理内存分配与释放
        int uv_count;                               // uv数组的长度
        short[] flist;                // 3d模型顶点 的索引数组(face),  由sdk管理内存分配与释放
        int flist_count;                            // flist数组的长度
        short[] landmark_triangle;    // landmark做三角剖分后的三角形数组,    由sdk管理内存分配与释放
        int landmark_triangle_count;                // landmark数组的长度

        int num_vertex;                             // = uv_count/2 = vertex_count/3    表示顶点元素的个数,      uv是标准3d模型的展开后的2d坐标
        int num_flist;                              // = flist_count / 3                面的个数
        int num_landmark_triangle;                  // = landmark_triangle_count / 2    三角形的个数
        int mum_landmark;                           // = landmark_count / 3             landmrk的个数
        int num_param;                              // = param_count
    };

    public static class FaceFittingResult {
        public FaceFittingResult() {
            config = null;
            faceFittingMeshInfo = new FaceFittingMeshInfo[FaceFittingMaxFaceCount];
        }

        public FaceFittingMeshInfo[] getFaceFittingMeshInfo() {
            return faceFittingMeshInfo;
        }

        public int getFaceCount() {
            return faceCount;
        }

        public FaceFittingMeshConfig getConfig() {
            return config;
        }

        FaceFittingMeshInfo faceFittingMeshInfo[];
        int faceCount;
        FaceFittingMeshConfig config;
    };

FAQ

1.如果出现任何异常,请查看是否有以下类型日志

答:建议首先查看以下tag输出Error类型的日志:
bef_effect_ai 和SMASH_E_LOG 以及 EffectSDK

错误码

错误码请参考错误码表