增加换肤功能

This commit is contained in:
启星
2025-08-14 10:07:49 +08:00
parent f6964c1e89
commit 4f9318d98e
8789 changed files with 978530 additions and 2 deletions

View File

@@ -0,0 +1,97 @@
//
// Created by sunnydu on 2024/5/10.
//
#ifndef VERIFICATION_DETECTFACEINFO_H
#define VERIFICATION_DETECTFACEINFO_H
/// opencv
#ifdef __ANDROID__
#include <core.hpp>
#include <resize.hpp>
#include "cvtColor.hpp"
#else
#include <YTCv/core.hpp>
#include <YTCv/cvtColor.hpp>
#include <YTCv/resize.hpp>
#endif // __ANDROID__
/// opencv end
#include <vector>
/// 动作类型
typedef enum :int{
/// 眨眨眼动作
POSETYPE_BLINK_EYE = 1,
/// 张张嘴动作
POSETYPE_OPEN_MOUSE = 2,
//不建议使用的动作检测方式,安全性不如眨眼和张嘴高
/// 点点头动作
POSETYPE_NOD_HEAD = 3,
/// 摇摇头
POSETYPE_SHAKE_HEAD = 4,
/// 静默动作
POSETYPE_SILENCE = 5,
//缓慢向左转头
POSETYPE_TURN_LEFT = 6,
//缓慢向右转头
POSETYPE_TURN_RIGHT = 7,
//由近及远
POSETYPE_CLOSER_FAR = 8,
//由远及近
POSETYPE_FAR_CLOSER = 9,
POSETYPE_COUNT = POSETYPE_SILENCE+1
}POSETYPE;
/// 动作检测返回码
typedef enum :int{
/// 动作检测通过
POSE_RET_POSE_COMMIT = 1,
/// 动作检测中
POSE_RET_POSE_DETECTING = 0,
/// 姿态不正确
POSE_RET_POSE_NOT_RIGHT = -1,
/// 无人脸
POSE_RET_NO_FACE = -2,
/// 半边人脸
POSE_RET_HALF_FACE = -3,
/// 光线不合适
POSE_RET_LIGHT_NOT_RIGHT = -4,
/// 晃动
POSE_RET_SHAKING = -5,
///点位信息不对
POSE_SHAPE_ERROR = -6,
/// 授权不通过
POSE_RET_AUTH_FAILED = -1024,
/// 人脸质量最佳帧不通过 (ppl层 根据归因转换tips)
FACE_QUALITY_DELETE_FAILED = -1025,
/// 人脸质量最佳帧获取中 (ppl tips 请保持姿态)
FACE_QUALITY_KEEP = -1026,
/// 人脸姿态不合格
FACE_QUALITY_STATUS_FAILED = -1029,
/// 人脸质量阶段 角度不符合预期
FACE_QUALITY_STATUS_ANGLE_FAILED = -1030,
/// 闭眼
FACE_QUALITY_EYE_CLOSE = -1031,
/// 张嘴
FACE_QUALITY_MOUTH_OPEN = -1032,
FACE_QUALITY_SHAKING = -1033,
}YT_POSE_RET_TYPE;
struct DetectFaceInfo{
std::vector<float> shape;
std::vector<float> visVec;
POSETYPE postType;
yt_tinycv::Mat3BGR rgbPtr;
float pitch;
float yaw;
float roll;
int faceDetectStatus;
int faceQualityStatus;
yt_tinycv::Rect2i faceRect;
int frameW;
int frameH;
bool isFaceShaking;
};
#endif //VERIFICATION_DETECTFACEINFO_H

View File

@@ -0,0 +1,28 @@
//
// Created by sunnydu on 2023/3/3.
//
#ifndef VERIFICATION_FAR2NEARDATA_H
#define VERIFICATION_FAR2NEARDATA_H
#include <vector>
#ifdef __ANDROID__
#include <core.hpp>
#include <resize.hpp>
#include "cvtColor.hpp"
#else
#include <YTCv/core.hpp>
#include <YTCv/cvtColor.hpp>
#include <YTCv/resize.hpp>
#endif // __ANDROID__
struct FrameData {
float iou;
float area_ratio;
std::vector<float> align;
yt_tinycv::Mat3BGR rgb;
int x;
int y;
long frame_timestamp = 0;
yt_tinycv::Rect2i face_rect;
};
using FaceFrameList = std::vector<FrameData>;
#endif //VERIFICATION_FAR2NEARDATA_H

View File

@@ -0,0 +1,50 @@
#ifndef PoseUtils_h
#define PoseUtils_h
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <sstream>
#include <math.h>
typedef struct _CAPTCHA_V2_ {
int fixedInterval; // 4 or 1
int unit; // ios: 70, andorid 120
std::vector<int> intervals; // 3 - 6
int rand_shift; // 0 - 3
int rand_inv; // -1 1
int version_flag; // 471418
int section_num; // section_num / intervals_num
int action; // -1
int unit_v2;
int live_mode; // 0 is close, 1 only open reflective, 2 only open action, 3. both open.
int64_t time_stamp_tv_sec;
int64_t time_stamp_tv_usec;
std::vector<int> colors; // total
std::vector<int> intervals2; // 2 - ?
std::vector<int> reserved_int; // size is 16, default is 5
std::string reserved;
} CAPTCHA_V2;
class PoseUtils{
public:
PoseUtils();
/**
* @brief 生成一串数字 用于checksum计算
*
* @param CP_string
* @return uint64_t
*/
uint64_t yt_parseCP(const std::string CP_string);
void setColorData(std::string cpStr, std::string clientVersionStr, std::string actStr);
std::string checksum(const std::string data);
std::string getSelectDataChecksum(std::string selectDataStr, std::string actVideochecksum,std::string checksumBest,std::string checksumMouth,std::string checksumEye);
private:
std::string clientVersionStr;
std::string actStr;
uint64_t timestamp;
};
#endif /* PoseUtils_h */

View File

@@ -0,0 +1,13 @@
//
// Version.h
// YTPoseDetector
//
// Created by sunnydu on 2022/10/13.
// Copyright © 2022 PanCheng. All rights reserved.
//
#define P_FRAMEWORK_VERSION "1.1.15.175.1";
#ifndef Version_h
#define Version_h
#endif /* Version_h */

View File

@@ -0,0 +1,234 @@
//
// YTFaceCheckLivePose.hpp
// YTPoseDetector
//
// Created by Cheng Pan on 3/27/18.
// Copyright © 2018 PanCheng. All rights reserved.
//
#ifndef YTFaceCheckLivePose_hpp
#define YTFaceCheckLivePose_hpp
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <sstream>
#include <math.h>
#include "Far2NearData.h"
#include "YTFaceQualityDetect.h"
#include "DetectFaceInfo.h"
#include "PoseUtils.h"
#ifdef __ANDROID__
#include <core.hpp>
#include <resize.hpp>
#include "cvtColor.hpp"
#else
#include <YTCv/core.hpp>
#include <YTCv/cvtColor.hpp>
#include <YTCv/resize.hpp>
#endif // __ANDROID__
#ifdef YTFACETRACK_NAMESPACE
#endif
#ifdef __ANDROID__
#define FACEDETECT_EXPORT
#else
#define FACEDETECT_EXPORT __attribute__((visibility("default")))
#endif
#define YT_FACEPOSE_VERSION "3.7.5"
#define P_FRAMEWORK_VERSION "@FRAMEWORK_VERSION"
namespace youtu {
typedef int (*YtFacePoseSDKLogCallback)(void *caller, int level, std::string message);
typedef void (*PlatformJpegEncoderCallback)(void *context, unsigned char *rgb, int rows, int cols, std::string &jpegData);
class YTPoseLiveDetector;
/// 最佳照片检测时的返回码
typedef enum :int{
/// 当前帧光照质量较差
LIGHT_ERROR = -2,
/// 当前帧的人脸所占屏幕区域较小
FACE_TOO_SMALL = -3,
/// 当前帧的人脸姿态角度过大
POSE_ANGLE_ERROR = -4,
/// 当前帧的人脸嘴部姿态异常
POSE_MOUTH_ERROR = -5,
/// 当前帧其他异常情况
OHTER_ERROR = 0,
/// 检测正常
SUCCESS = 1
}BestImgCode;
/// 动作算法类型
typedef enum :int {
/// 推荐安全类型,光流算法
YTPOSE_SAFETY_RECOMMAND = 0,
/// (点位计算)灵敏度高,但是对遮挡攻击的效果不够理想
YTPOSE_SAFETY_LOW = 1,
/// (光流算法)相对安全,但是灵敏度会略微下降,让面部距离屏幕更近,可以有效提高通过率
YTPOSE_SAFETY_HIGH = 2,
/// 动作类型算法数量
YTPOSE_SAFETY_COUNT = 3
}YTPOSE_SAFETY_LEVEL;
struct YTPoseRect
{
int x;
int y;
int width;
int height;
YTPoseRect() :x(0), y(0), width(0), height(0){}
YTPoseRect(int x_, int y_, int width_, int height_) :x(x_), y(y_), width(width_), height(height_){}
};
struct YTSize
{
int width;
int height;
YTSize() :width(0), height(0){}
YTSize(int width_, int height_) :width(width_), height(height_){}
};
struct YTPosePoint2f
{
float x;
float y;
YTPosePoint2f() :x(0), y(0){}
YTPosePoint2f(int x_, int y_) :x(x_), y(y_){}
YTPosePoint2f operator -(const YTPosePoint2f& rp){
return YTPosePoint2f(x - rp.x, y - rp.y);
}
};
inline float Norm(YTPosePoint2f p)
{
double x = p.x;
double y = p.y;
return sqrt(x * x + y * y);
}
/// 动作检测对象类
class FACEDETECT_EXPORT FaceCheckLivePose
{
public:
/// 动作检测构造接口
/// @param _frameNum 缓存视频帧数推荐20帧
FaceCheckLivePose(int _frameNum=20);
/// 动作检测析构接口
~FaceCheckLivePose();
/// 获取版本信息
/// @note 返回当前版本信息
static std::string getVersion();
/// 重置接口
///@note 每次开始检测动作的时候请调用reset检测不到人脸的时候也应该调用reset以保障动作过程中没有发生人脸切换
/// 获取完最优图和视频帧数据后也请调用reset接口
void reset();
/// 动作安全等级设置接口
/// @param level 参考YTPOSE_SAFETY_LEVEL 目标安全等级
void setSafetyLevel(YTPOSE_SAFETY_LEVEL level);
/// 动作安全等级获取接口
/// @return 返回当前动作安全等级
YTPOSE_SAFETY_LEVEL getSafetyLevel();
/// 动作检测接口
/// @param shapeInput 输入人脸框
/// @param visVec 输入关键点置信度
/// @param poseType 输入目标动作
/// @param rgb 输入帧信息rgb
/// @param yuv 输入帧信息yuv仅android使用其他情况请填充空mat
/// @param pitch 输入人脸俯仰角度
/// @param yaw 输入人脸左右角度
/// @param roll 输入人脸旋转角度
/// @return 返回YT_POSE_RET_TYPE 对应的错误码信息
/**
return -1 姿态不正确
-2 当前没有人脸
-3 当前只有半张脸
-4 光线不合适
-5 当前晃动较大
-1024 授权检测不过
**/
int detect_liveness(DetectFaceInfo& detectFaceInfo);
void registerSDKLogger(int level, YtFacePoseSDKLogCallback listener);
//最优图相关接口
/// 获取最优图
/// @return 返回对应最优图
yt_tinycv::Mat3BGR get_BestImgMat();
/// 获取最优图
/// @param shape 人脸信息
/// @return 返回对应最优图
yt_tinycv::Mat3BGR get_BestImgMat(std::vector<float> & shape);
/// 检测记录完成通知
/// @return 返回是否可以获取序列帧视频和最优图
bool get_RecordingDone();
/// 获取当前已经存储的视频流
/// @return 返回序列帧 yuv格式
std::vector<yt_tinycv::Mat3BGR> get_bgrFrameList();
// 动作+反光合并协议相关接口
/// 获取动作幅度最大图
/// @param bestImg 输出动作最大的图
/// @param bestShape 输出动作最大的点位信息
/// @param eyeImg 输出动作最大的eye部图
/// @param eyeShape 输出动作最大的eye部点位信息
/// @param mouthImg 输出动作最大的mouth部图
/// @param mouthImg 输出动作最大的mouth部点位信息
void get_PoseImgMat(yt_tinycv::Mat3BGR &bestImg, std::vector<float> &bestShape,
yt_tinycv::Mat3BGR &eyeImg, std::vector<float> &eyeShape,
yt_tinycv::Mat3BGR &mouthImg, std::vector<float> &mouthShape
);
int get_actionVideoShortenStrategy();
//主要动作执行完成,可以启动下一个步骤(目前主要用于动作+反光方案)
/// 检测是否可以进入反光
/// @return 返回是否可以进入反光状态
bool get_CanReflect();
/// 更新内部检测参数
/// @param key 参数key
/// @param value 参数值
int updateParam(const std::string &key, const std::string &value);
std::string checksum(const std::string data);
void setColorData(std::string cp, std::string clientVersion, std::string actStr);
void setChecksumJpg(std::string best, std::string eye, std::string mouth);
std::string getSelectDataChecksum(std::string selectDataStr, std::string actionVideo);
yt_tinycv::Mat3BGR get_MaxActionEyeImgMat(std::vector<float> & shape);
yt_tinycv::Mat3BGR get_MaxActionMouthImgMat(std::vector<float> & shape);
bool isFrameListNull();
void initFar2NearParam(int width,int height,int count,float min_r,float max_r);
FaceFrameList GetFaceDistanceDetectData();
std::vector<yt_tinycv::Rect2i> GetFaceDistanceProcessRect();
std::string getFaceDetectDistanceRectParam();
std::vector<int> GetLargeFace();
std::vector<int> GetSmallFace();
float GetFar2NearRectChangeScore();
private:
YTPoseLiveDetector* livenessdetector;
YTFaceQualityDetect* faceQualityDetect;
PoseUtils* poseUtils;
std::string anchorWidths;
std::string checksumBest;
std::string checksumEye;
std::string checksumMouth;
std::string checksumActionVideo;
};
/// 推荐对外使用类型
class FACEDETECT_EXPORT YTFaceCheckLivePose:public FaceCheckLivePose{};
}
#endif /* YTFaceCheckLivePose_hpp */

View File

@@ -0,0 +1,83 @@
//
// YTFaceCheckLivePoseErrorCode.h
//
// Created by tidetzhang 2020/08/06.
// Copyright © 2018 PanCheng. All rights reserved.
//
#ifndef _YTFACECHECKLIVEPOSEERRORCODE_H_
#define _YTFACECHECKLIVEPOSEERRORCODE_H_
namespace youtu
{
/// 动作类型
typedef enum : int {
/// 眨眨眼动作
POSETYPE_BLINK_EYE = 1,
/// 张张嘴动作
POSETYPE_OPEN_MOUSE = 2,
//不建议使用的动作检测方式,安全性不如眨眼和张嘴高
/// 点点头动作
POSETYPE_NOD_HEAD = 3,
/// 摇摇头
POSETYPE_SHAKE_HEAD = 4,
/// 静默动作
POSETYPE_SILENCE = 5,
POSETYPE_COUNT = POSETYPE_SILENCE + 1
} POSETYPE;
/// 动作检测返回码
typedef enum : int {
/// 动作检测通过
POSE_RET_POSE_COMMIT = 1,
/// 动作检测中
POSE_RET_POSE_DETECTING = 0,
/// 姿态不正确
POSE_RET_POSE_NOT_RIGHT = -1,
/// 无人脸
POSE_RET_NO_FACE = -2,
/// 半边人脸
POSE_RET_HALF_FACE = -3,
/// 光线不合适
POSE_RET_LIGHT_NOT_RIGHT = -4,
/// 晃动
POSE_RET_SHAKING = -5,
///点位信息不对
POSE_SHAPE_ERROR = -6,
/// 授权不通过
POSE_RET_AUTH_FAILED = -1024
} YT_POSE_RET_TYPE;
/// 最佳照片检测时的返回码
typedef enum : int {
/// 当前帧光照质量较差
LIGHT_ERROR = -2,
/// 当前帧的人脸所占屏幕区域较小
FACE_TOO_SMALL = -3,
/// 当前帧的人脸姿态角度过大
POSE_ANGLE_ERROR = -4,
/// 当前帧的人脸嘴部姿态异常
POSE_MOUTH_ERROR = -5,
/// 当前帧其他异常情况
OHTER_ERROR = 0,
/// 检测正常
SUCCESS = 1
} BestImgCode;
/// 动作算法类型
typedef enum : int {
/// 推荐安全类型,光流算法
YTPOSE_SAFETY_RECOMMAND = 0,
/// (点位计算)灵敏度高,但是对遮挡攻击的效果不够理想
YTPOSE_SAFETY_LOW = 1,
/// (光流算法)相对安全,但是灵敏度会略微下降,让面部距离屏幕更近,可以有效提高通过率
YTPOSE_SAFETY_HIGH = 2,
/// 动作类型算法数量
YTPOSE_SAFETY_COUNT = 3
} YTPOSE_SAFETY_LEVEL;
} // namespace youtu
#endif /* YTFaceCheckLivePose_hpp */

View File

@@ -0,0 +1,99 @@
//
// Created by sunnydu on 2024/5/9.
//
#ifndef VERIFICATION_YTFACEQUALITYDETECT_H
#define VERIFICATION_YTFACEQUALITYDETECT_H
#include "DetectFaceInfo.h"
#ifdef __ANDROID__
#include <core.hpp>
#include <resize.hpp>
#include "cvtColor.hpp"
#else
#include <YTCv/core.hpp>
#include <YTCv/cvtColor.hpp>
#include <YTCv/resize.hpp>
#endif // __ANDROID__
#include <vector>
class YTFaceQualityDetect {
public:
int needFaceQualityImage = false;
float stableRoiThreshold = 0.98f;//模糊判断
float continuousShelterNumThreshold = 5;
int continuousQualityNumThreshold = 10;
// float faceMaxHeightThreshold = 0.95f;
// float faceRealMinHeightThreshold = 0.4f;
float secondaryYawThreshold = 18;
float secondaryPitchThreshold = 18;
float secondaryRollThreshold = 18;
float closeMouthThreshold = 0.4f;
float closeEyeLeftThreshold = 0.25f;//左睁眼阈值
float closeEyeRightThreshold = 0.25f;//右睁眼阈值
//人脸质量最佳帧
bool isGetImageMat = false;
yt_tinycv::Mat3BGR qualityImageMat;
std::vector<float> qualityShape;
int continuousCount = 0;
int continuousShelterCount = 0;
/**
* 清空连续帧计数
*/
void resetContinuousCount();
/**
* 遮挡累计检测
*/
void shelterDetect();
/**
* 计数器+1然后判断是否满足条件
*/
int faceQualityIsPass(DetectFaceInfo& detectFaceInfo);
private:
yt_tinycv::Rect2i previousFaceRect = yt_tinycv::Rect2i(0,0,0,0);
/**
* 内置二级角度检测
*/
bool faceAngleForceCheck(DetectFaceInfo& detectFaceInfo);
/**
* 检测脸部长度占比,脸部长度占比在图像长度的预设百分比(faceHeightThreshold) 视为通过,否则不通过
* faceHeightThreshold 默认为0不对人脸大小做限制
*
* @return 1 太远
* 2 太近
* 0 合适
*/
int isFaceHeightStandard(DetectFaceInfo& detectFaceInfo);
/**
* 闭眼判断
* @param shape
* @return
*/
bool isEyeOpen(DetectFaceInfo& detectFaceInfo);
/**
* 张嘴检测
* @param detectFaceInfo
* @return
*/
bool isMouthClose(DetectFaceInfo& detectFaceInfo);
/**
* 计算人脸框差值
* @param rect1
* @param outRect
*/
void getIntersectionRect(const yt_tinycv::Rect2i& rect1,yt_tinycv::Rect2i& outRect);
/**
* 遮挡判断
* @param rect
* @return
*/
bool detectScreenShaking(const yt_tinycv::Rect2i& rect);
};
#endif //VERIFICATION_YTFACEQUALITYDETECT_H