增加换肤功能
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// TencentCloudHuiyanSDKFace.h
|
||||
// Pods
|
||||
//
|
||||
// Created by Leon on 2022/11/14.
|
||||
//
|
||||
|
||||
#ifndef TencentCloudHuiyanSDKFace_h
|
||||
#define TencentCloudHuiyanSDKFace_h
|
||||
#import <TencentCloudHuiyanSDKFace/WBFaceError.h>
|
||||
#import <TencentCloudHuiyanSDKFace/WBFaceVerifyConst.h>
|
||||
#import <TencentCloudHuiyanSDKFace/WBFaceVerifyCustomerService.h>
|
||||
#import <TencentCloudHuiyanSDKFace/WBFaceVerifyResult.h>
|
||||
#import <TencentCloudHuiyanSDKFace/WBFaceVerifySDKConfig.h>
|
||||
#endif /* TencentCloudHuiyanSDKFace_h */
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// WBFaceError.h
|
||||
// Pods
|
||||
//
|
||||
// Created by pp on 2017/8/15.
|
||||
//
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
/*
|
||||
Domain(错误出现的地方) Code Desc(描述) Reason(详细实际原因)
|
||||
WBFaceErrorDomainInputParams 12000 传入参数为空 传入的xx为空
|
||||
12001 传入的keyLicence不可用 传入的keyLicence不可用
|
||||
12002 身份证格式不正确 身份证格式不正确
|
||||
12003 使用自带对比源,传入参数错误,非base64 传入的srcPhotoString不是base64
|
||||
12004 使用自带对比源,传入参数错误,超过3M 传入的srcPhotoString超过3M
|
||||
12005 sdk资源引入版本不匹配 没有引入资源包或者引入的资源包版本与当前SDK版本不匹配
|
||||
12006 订单号不能为0或者超过32位
|
||||
12007 nonce字符串位数不为32
|
||||
12008 faceid不合法,需要保证faceid与接口对应
|
||||
12009 定制化SDK生成参数失败
|
||||
12010 定制化参数校验错误
|
||||
12011 当前版本意愿性表达服务暂不支持
|
||||
WBFaceErrorDomainLoginNetwork 22100 网络异常 登陆时网络异常(请求未到达后台)
|
||||
22200 网络异常 登陆时后台返回参数有误(请求到达后台)
|
||||
|
||||
WBFaceErrorDomainLoginServer 其他 透传后台错误码(请参考后台错误) 例如签名问题等等
|
||||
|
||||
|
||||
WBFaceErrorDomainGetInfo 32100 网络异常 获取数字/活体类型/光线阈值,网络异常(请求未到达后台)
|
||||
32200 网络异常 获取数字/活体类型/光线阈值,后台返回参数有误(请求到达后台)
|
||||
|
||||
|
||||
WBFaceErrorDomainNativeProcess 42000 用户取消 回到后台/点击home/左上角/上传时左上角 取消
|
||||
42001 网络环境不满足认证需求 无网络/2g网络
|
||||
42002 权限异常,未获取权限 相机/麦克风/read phone/external storage
|
||||
42003 相机运行中出错
|
||||
42004 视频录制中出错 不能存/启动失败/结束失败
|
||||
42005 请勿晃动人脸,保持姿势 未获取到最佳图片
|
||||
42006 视频大小不满足要求 视频大小不满足要求
|
||||
42007 超时 预检测/动作活体
|
||||
42008 检测中人脸移出框外 活体/数字/反光
|
||||
42009 光线活体本地错误
|
||||
42010 风险控制超出次数 用户重试太多次
|
||||
42011 没有检测到读数声音 数字活体过程中没有发声
|
||||
42012 模型初始化失败
|
||||
42013 意愿模块初始化失败
|
||||
42015 登录态失效
|
||||
42016 请求异常
|
||||
42101 音频录制中出错
|
||||
42102 没有检测到麦克风声音
|
||||
42103 播报音频文件加载失败
|
||||
42104 麦克风被占用,音频播报失败
|
||||
42105 视频录制中出错
|
||||
42106 音量过低,用户主动退出
|
||||
42107 点头检测超时
|
||||
WBFaceErrorDomainCompareNetwork 52100 网络异常 对比时,网络异常(请求未到达后台)
|
||||
52200 网络异常 对比时,后台返回参数有误(请求到达后台)
|
||||
|
||||
WBFaceErrorDomainCompareServer 其他 透传后台错误码
|
||||
*/
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*
|
||||
错误domain划分成两类:
|
||||
|
||||
1. 出现在登录时, 通过调用startXXXX 方法的failure block进行回调返回:
|
||||
WBFaceErrorDomainInputParams, WBFaceErrorDomainLoginNetwork, WBFaceErrorDomainLoginServer
|
||||
|
||||
|
||||
2. 人脸服务结果返回(封装在WBFaceVerifyResult中):
|
||||
WBFaceErrorDomainGetInfo, WBFaceErrorDomainNativeProcess, WBFaceErrorDomainCompareNetwork, WBFaceErrorDomainCompareServer
|
||||
*/
|
||||
|
||||
/* 登录时传入参数有误 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainInputParams;
|
||||
/* 登录时网络请求错误 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainLoginNetwork;
|
||||
/* 登录时后台拒绝登录, 具体参考后台word版本错误码, 这里直接透传 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainLoginServer;
|
||||
/* 拉取有效信息时候网络错误 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainGetInfo;
|
||||
/* native本地在活体检测中, 某些原因导致错误 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainNativeProcess;
|
||||
/* 上送后台比对时,网络错误 */
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainCompareNetwork;
|
||||
/* 后台比对完成,返回比对结果的错误原因*/
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainCompareServer;
|
||||
/* 后台比对未完成,返回失败的错误原因*/
|
||||
UIKIT_EXTERN NSString *const WBFaceErrorDomainServerFailed;
|
||||
|
||||
@interface WBFaceError: NSObject
|
||||
/**
|
||||
错误发生的地方, 具体的发生地方由上面定义的 WBFaceErrorDomainXXXX 指定
|
||||
*/
|
||||
@property (nonatomic, readonly, copy) NSString *domain;
|
||||
/**
|
||||
每个domain中有相应的错误代码, 具体的错误代码见
|
||||
*/
|
||||
@property (nonatomic, readonly, assign) NSInteger code; //错误代码
|
||||
@property (nonatomic, readonly, copy) NSString *desc; //获取本地化描述
|
||||
@property (nonatomic, readonly, copy) NSString *reason; // 错误出现的真实原因原因
|
||||
@property (nonatomic, readonly, copy) NSDictionary * _Nullable otherInfo;// 预留接口
|
||||
|
||||
|
||||
+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code desc:(NSString *)desc;
|
||||
+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code desc:(NSString *)desc reason:(NSString *)reason;
|
||||
+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code desc:(NSString *)desc reason:(NSString *)reason otherInfo:(nullable NSDictionary *)otherInfo;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// WBFaceVerifyConst.h
|
||||
// Pods
|
||||
//
|
||||
// Created by pp on 2017/7/31.
|
||||
//
|
||||
//
|
||||
#import <UIKit/UIKit.h>
|
||||
#ifndef WBFaceVerifyConst_h
|
||||
#define WBFaceVerifyConst_h
|
||||
#define WBCloudReflectionFaceVerifyVersion @"8.7.0"
|
||||
|
||||
UIKIT_EXTERN NSString *const WBCloudFaceVerifySDKVersion;
|
||||
|
||||
/**
|
||||
SDK使用的主题风格
|
||||
|
||||
- WBFaceVerifyThemeDarkness: 暗黑色系主题
|
||||
- WBFaceVerifyThemeLightness: 明亮色系主题
|
||||
- WBFaceVerifyThemeCustom: 自定义主题,通过修改bundle中的custom.json实现自定义
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, WBFaceVerifyTheme) {
|
||||
WBFaceVerifyThemeDarkness = 0,
|
||||
WBFaceVerifyThemeLightness,
|
||||
WBFaceVerifyThemeCustom,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, WBFaceVerifyLanguage) {
|
||||
WBFaceVerifyLanguage_ZH_CN = 0, //简体中文
|
||||
WBFaceVerifyLanguage_ZH_HK, //繁体中文
|
||||
WBFaceVerifyLanguage_EN, //英语
|
||||
WBFaceVerifyLanguage_ID, //印尼语
|
||||
WBFaceVerifyLanguage_JA, //日语
|
||||
WBFaceVerifyLanguage_KO, //韩语
|
||||
WBFaceVerifyLanguage_TH //泰语
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, WBFaceCustomTipsLoc) {
|
||||
WBFaceCustomTipsLoc_Bottom = 0, //提示语在下
|
||||
WBFaceCustomTipsLoc_Top,
|
||||
};
|
||||
#endif /* WBFaceVerifyConst_h */
|
||||
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// WBFaceVerifyCustomerService.h
|
||||
// WBFaceV2
|
||||
//
|
||||
// Created by tank on 25/10/2016.
|
||||
// Copyright © 2016 tencent. All rights reserved.
|
||||
//
|
||||
|
||||
/**
|
||||
注意拉起页面的方式:
|
||||
|
||||
SDK会创建一个UIWindow覆盖在当前界面,并在新创建的UIWindow界面进行人脸认证,并且可以通过实现 wbfaceVerifyServiceGetWindowLevel 代理方法,传入创建的UIWindow的windowLevel, 传入的windowLevel必须是1~999, 默认情况如果不实现 wbfaceVerifyServiceGetWindowLevel 方法,windowLevel = UIWindowLevelNormal + 1
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "WBFaceVerifyConst.h"
|
||||
#import "WBFaceVerifySDKConfig.h"
|
||||
#import "WBFaceVerifyResult.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
|
||||
// SDK在运行结束退出时候会发出通知. 具体的通知内容可以见delegate方法wbfaceVerifyCustomerServiceDidFinished:中的注释
|
||||
UIKIT_EXTERN NSString *const WBFaceVerifyCustomerServiceDidFinishedNotification;
|
||||
|
||||
@class WBFaceVerifyCustomerService;
|
||||
/**
|
||||
处理刷脸回调
|
||||
*/
|
||||
@protocol WBFaceVerifyCustomerServiceDelegate <NSObject>
|
||||
@optional
|
||||
-(void)wbfaceVerifyCustomerServiceWillUploadBestImage:(UIImage *)bestImage;
|
||||
|
||||
@required
|
||||
-(void)wbfaceVerifyCustomerServiceDidFinishedWithFaceVerifyResult:(WBFaceVerifyResult *)faceVerifyResult;
|
||||
@end
|
||||
|
||||
@interface WBFaceVerifyCustomerService : NSObject
|
||||
@property (nullable,nonatomic,weak) id<WBFaceVerifyCustomerServiceDelegate> delegate;
|
||||
@property (nonatomic, assign, readonly) BOOL isService;
|
||||
|
||||
/*
|
||||
全局唯一单例
|
||||
*/
|
||||
+(instancetype)sharedInstance;
|
||||
|
||||
/*
|
||||
初始化云刷脸sdk,仅做参数初始化与登陆,不拉起刷脸页面
|
||||
登陆有时效性,建议在登陆完成后success回调中拉起刷脸页面!!
|
||||
登陆过程为异步操作,多次登陆以最后一次收到的结果为准!!
|
||||
|
||||
此SDK接口中
|
||||
合作方后台开发需要通过后台接口获取sign,
|
||||
然后根据自带比对源接口, 通过后台接口获取faceId!!!!(native端无需传入自带比对源图)
|
||||
|
||||
*** faceId为空时,启用仅活体检测服务,不做比对 !!!
|
||||
|
||||
注意, 请使用 dispatch_async(dispatch_get_main_queue(), ^{ }); 异步调用SDK的入口方法
|
||||
|
||||
@param userid 用户唯一标识, 由合作方自行定义(具体要求,参考word接入文档)
|
||||
@param nonce 满足接入要求的32位随机数(具体要求,参考word接入文档)
|
||||
@param sign 满足接入要求的40位签名值(具体要求,参考word接入文档)
|
||||
@param appid 腾讯服务分配的appid
|
||||
@param orderNo 每次人脸身份认证请求的唯一订单号: 建议为32位字符串(不超过32位)
|
||||
@param apiVersion 后台api接口版本号(不是SDK的版本号),默认请填写@"1.0.0"
|
||||
@param licence 腾讯给合作方派发的前端使用的licence(该licence同app当前使用的bundle id绑定)
|
||||
@param faceId 合作方必须要先在获取faceId的接口里送入用户自带比对源图片信息,得到相应的faceId后,再送入sdk!!!!(参考word接入文档)
|
||||
*** faceId为空时,启用仅活体检测服务,不做比对 !!!
|
||||
@param sdkConfig SDK基础配置项目
|
||||
@param success 服务登录成功回调,登录成功以后开始进行活体和检测服务
|
||||
@param failure 服务登录失败回调,具体参考错误码文档(参考word接入文档)
|
||||
*/
|
||||
-(void)initSDKWithUserId:(NSString *)userid
|
||||
nonce:(NSString *)nonce
|
||||
sign:(NSString *)sign
|
||||
appid:(NSString *)appid
|
||||
orderNo:(NSString *)orderNo
|
||||
apiVersion:(NSString *)apiVersion
|
||||
licence:(NSString *)licence
|
||||
faceId:(nullable NSString *)faceId
|
||||
sdkConfig:(WBFaceVerifySDKConfig *)sdkConfig
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(WBFaceError * _Nonnull error))failure;
|
||||
|
||||
/*
|
||||
Plus级SDK核身入口,注意传入的faceId不能为空,否则会报failure
|
||||
|
||||
@param userid 用户唯一标识, 由合作方自行定义(具体要求,参考word接入文档)
|
||||
@param nonce 满足接入要求的32位随机数(具体要求,参考word接入文档)
|
||||
@param sign 满足接入要求的40位签名值(具体要求,参考word接入文档)
|
||||
@param appid 腾讯服务分配的appid
|
||||
@param orderNo 每次人脸身份认证请求的唯一订单号: 建议为32位字符串(不超过32位)
|
||||
@param apiVersion 后台api接口版本号(不是SDK的版本号),默认请填写@"1.0.0"
|
||||
@param licence 腾讯给合作方派发的前端使用的licence(该licence同app当前使用的bundle id绑定)
|
||||
@param faceId 合作方必须要先获取*增强级*faceId,再送入sdk,不允许为空(参考word接入文档)
|
||||
@param sdkConfig SDK基础配置项目
|
||||
@param success 服务登录成功回调,登录成功以后开始进行活体和检测服务
|
||||
@param failure 服务登录失败回调,具体参考错误码文档(参考word接入文档)
|
||||
*/
|
||||
- (void)initPlusSDKWithUserId:(NSString *)userid
|
||||
nonce:(NSString *)nonce
|
||||
sign:(NSString *)sign
|
||||
appid:(NSString *)appid
|
||||
orderNo:(NSString *)orderNo
|
||||
apiVersion:(NSString *)apiVersion
|
||||
licence:(NSString *)licence
|
||||
faceId:(nullable NSString *)faceId
|
||||
sdkConfig:(WBFaceVerifySDKConfig *)sdkConfig
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(WBFaceError * _Nonnull error))failure;
|
||||
|
||||
/*
|
||||
增强级SDK核身入口,注意传入的faceId不能为空,且必须为增强faceId,否则会报failure
|
||||
|
||||
@param userid 用户唯一标识, 由合作方自行定义(具体要求,参考word接入文档)
|
||||
@param nonce 满足接入要求的32位随机数(具体要求,参考word接入文档)
|
||||
@param sign 满足接入要求的40位签名值(具体要求,参考word接入文档)
|
||||
@param appid 腾讯服务分配的appid
|
||||
@param orderNo 每次人脸身份认证请求的唯一订单号: 建议为32位字符串(不超过32位)
|
||||
@param apiVersion 后台api接口版本号(不是SDK的版本号),默认请填写@"1.0.0"
|
||||
@param licence 腾讯给合作方派发的前端使用的licence(该licence同app当前使用的bundle id绑定)
|
||||
@param faceId 合作方必须要先获取*增强级*faceId,再送入sdk,不允许为空(参考word接入文档)
|
||||
@param sdkConfig SDK基础配置项目
|
||||
@param success 服务登录成功回调,登录成功以后开始进行活体和检测服务
|
||||
@param failure 服务登录失败回调,具体参考错误码文档(参考word接入文档)
|
||||
*/
|
||||
-(void)initAdvanceSDKWithUserId:(NSString *)userid
|
||||
nonce:(NSString *)nonce
|
||||
sign:(NSString *)sign
|
||||
appid:(NSString *)appid
|
||||
orderNo:(NSString *)orderNo
|
||||
apiVersion:(NSString *)apiVersion
|
||||
licence:(NSString *)licence
|
||||
faceId:(nonnull NSString *)faceId
|
||||
sdkConfig:(WBFaceVerifySDKConfig *)sdkConfig
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(WBFaceError * _Nonnull error))failure;
|
||||
|
||||
/**
|
||||
以上一次的登陆结果拉起刷脸页面,必须先登录再拉起刷脸页面
|
||||
|
||||
@return 拉起是否成功
|
||||
*/
|
||||
- (BOOL)startWbFaceVeirifySdk;
|
||||
|
||||
#pragma mark - 意愿性表达接口
|
||||
/*
|
||||
意愿性SDK入口,注意传入的faceId不能为空
|
||||
|
||||
@param userid 用户唯一标识, 由合作方自行定义(具体要求,参考word接入文档)
|
||||
@param nonce 满足接入要求的32位随机数(具体要求,参考word接入文档)
|
||||
@param sign 满足接入要求的40位签名值(具体要求,参考word接入文档)
|
||||
@param appid 腾讯服务分配的appid
|
||||
@param orderNo 每次人脸身份认证请求的唯一订单号: 建议为32位字符串(不超过32位)
|
||||
@param apiVersion 后台api接口版本号(不是SDK的版本号),默认请填写@"1.0.0"
|
||||
@param licence 腾讯给合作方派发的前端使用的licence(该licence同app当前使用的bundle id绑定)
|
||||
@param faceId 合作方必须要先获取*增强级*faceId,再送入sdk,不允许为空(参考word接入文档)
|
||||
@param sdkConfig SDK基础配置项目
|
||||
@param success 服务登录成功回调,登录成功以后开始进行活体和检测服务
|
||||
@param failure 服务登录失败回调,具体参考错误码文档(参考word接入文档)
|
||||
*/
|
||||
-(void)initWillSDKWithUserId:(NSString *)userid
|
||||
nonce:(NSString *)nonce
|
||||
sign:(NSString *)sign
|
||||
appid:(NSString *)appid
|
||||
orderNo:(NSString *)orderNo
|
||||
apiVersion:(NSString *)apiVersion
|
||||
licence:(NSString *)licence
|
||||
faceId:(nonnull NSString *)faceId
|
||||
sdkConfig:(WBFaceVerifySDKConfig *)sdkConfig
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(WBFaceError * _Nonnull error))failure;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// WBFaceVerifyResult.h
|
||||
// Pods
|
||||
//
|
||||
// Created by pp on 2017/8/22.
|
||||
//
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "WBFaceError.h"
|
||||
#import "WBFaceVerifyConst.h"
|
||||
|
||||
@interface WBFaceWillModeResult : NSObject
|
||||
/*
|
||||
核身结果的对应错误码
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *faceCode;
|
||||
/*
|
||||
核身结果的对应错误描述
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *faceMsg;
|
||||
/*
|
||||
意愿性结果的对应错误码
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *willCode;
|
||||
/*
|
||||
意愿性结果的对应错误描述
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *willMsg;
|
||||
|
||||
@property (nonatomic, strong, readonly) NSURL *videoURL;
|
||||
|
||||
@end
|
||||
|
||||
@interface WBFaceSimpleModeResult : NSObject
|
||||
|
||||
/**
|
||||
结果对应的订单号
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *orderNo;
|
||||
|
||||
/**
|
||||
接下来用于人脸对比的安全性参数
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *encryptAESKey;
|
||||
|
||||
/**
|
||||
视频编码
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *userVideoString;
|
||||
|
||||
/**
|
||||
使用传入publickey加密过的AES
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *videoEncryptAESKey;
|
||||
/**
|
||||
用于后面进行人脸比对的数据参数
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *identifyStr;
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
增强级结果,具体参数含义参考后台返回字段,结果为透传
|
||||
*/
|
||||
@interface WBFaceRiskInfo : NSObject
|
||||
@property (nonatomic, copy, readonly) NSString *deviceInfoLevel;
|
||||
@property (nonatomic, copy, readonly) NSString *deviceInfoTag;
|
||||
@property (nonatomic, copy, readonly) NSString *riskInfoLevel;
|
||||
@property (nonatomic, copy, readonly) NSString *riskInfoTag;
|
||||
@end
|
||||
/**
|
||||
人脸服务返回结果对象
|
||||
*/
|
||||
@interface WBFaceVerifyResult : NSObject
|
||||
/**
|
||||
人脸比对结果是否通过:
|
||||
|
||||
YES: 表示人脸服务通过
|
||||
NO: 表示人脸服务不通过
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL isSuccess;
|
||||
|
||||
/**
|
||||
结果对应的订单号
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *orderNo;
|
||||
|
||||
/**
|
||||
isSuccess == YES 时, sign有值, 通过该sign可以去后台拉取本次人脸服务的照片,视频存证
|
||||
isSuccess == NO 时, sign 无意义
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString * sign;
|
||||
|
||||
/**
|
||||
活体检测服务得分
|
||||
|
||||
isSuccess == YES 时, liveRate 有值:
|
||||
1. liveRate 可能是 @"分数为空", 这种情况具体咨询合作方
|
||||
2. float类型的字符串, 请调用 [liveRate floatValue] 获取具体分数
|
||||
isSuccess == NO 时, liveRate 无意义
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString * liveRate;
|
||||
|
||||
/**
|
||||
人脸比对服务得分
|
||||
|
||||
isSuccess == YES 时, similarity 有值:
|
||||
1. similarity 可能是 @"分数为空", 这种情况具体咨询合作方
|
||||
2. float类型的字符串, 请调用 [similarity floatValue] 获取具体分数
|
||||
isSuccess == NO 时, similarity 无意义
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString * similarity;
|
||||
|
||||
/**
|
||||
人脸比对图片之一
|
||||
|
||||
isSuccess == YES 时, 该属性是上送比对图片之一UIImage的base64编码字符串(图片格式是jpg)
|
||||
|
||||
isSuccess == NO 时, 该属性为nil
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString * userImageString;
|
||||
|
||||
/**
|
||||
isSuccess == YES 时候, error 无意义
|
||||
isSuccess == NO 时, error中存储的具体错误信息,参考 WBFaceError.h
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) WBFaceError * error;
|
||||
|
||||
#pragma mark - 非标专用返回参数
|
||||
|
||||
@property (nonatomic, strong, readonly) WBFaceSimpleModeResult *simpleModeResult;
|
||||
|
||||
#pragma mark - 增强SDK专用参数
|
||||
@property (nonatomic, strong, readonly) WBFaceRiskInfo *riskInfo;
|
||||
|
||||
#pragma mark - 意愿性SDK返回参数
|
||||
@property (nonatomic, strong, readonly) WBFaceWillModeResult *willModeResult;
|
||||
|
||||
-(NSString *)description;
|
||||
@end
|
||||
@@ -0,0 +1,228 @@
|
||||
//
|
||||
// WBFaceVerifySDKConfig.h
|
||||
// Pods
|
||||
//
|
||||
// Created by pp on 2017/8/2.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WBFaceVerifyConst.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, WBCompareType) {
|
||||
/// 活体+比对
|
||||
WBCompareTypeLiveCompare,
|
||||
/// 仅活体
|
||||
WBCompareTypeLive,
|
||||
};
|
||||
|
||||
/**
|
||||
人脸识别SDK 基础配置类
|
||||
*/
|
||||
@interface WBFaceVerifySDKConfig : NSObject
|
||||
|
||||
/// 是否使用非标模式, 默认为NO(具体含义请咨询技术支持)
|
||||
/// - IMPORTANT: 一般不需要开启, 开启前请咨询技术支持
|
||||
/// - IMPORTANT: 使用原WBCloudFaceVerifySimpleSDK升级过来的,务必打开此项
|
||||
@property (nonatomic, assign) BOOL useSimpleMode;
|
||||
|
||||
#pragma mark - common
|
||||
/**
|
||||
sdk中拉起人脸活体识别界面中使用UIWindow时的windowLevel配置,默认配置是1 + UIWindowLevelNormal
|
||||
|
||||
如果接入放app中有其他自定义UIWindow, 为了防止界面覆盖,可以酌情设置该参数
|
||||
*/
|
||||
@property (nonatomic, assign) NSUInteger windowLevel;
|
||||
|
||||
/**
|
||||
人脸识别服务结果页是否展示配置项 - 是否展示人脸对比成功界面 -> 建议关闭
|
||||
|
||||
default: NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL showSuccessPage DEPRECATED_MSG_ATTRIBUTE("SDK 已移除结果页, 若有需要可参考 Demo 实现");
|
||||
|
||||
/**
|
||||
人脸识别服务结果页是否展示配置项 - 是否展示人脸对比失败界面 -> 建议关闭
|
||||
|
||||
default: NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL showFailurePage DEPRECATED_MSG_ATTRIBUTE("SDK 已移除结果页, 若有需要可参考 Demo 实现");
|
||||
|
||||
/**
|
||||
人脸识别服务是否进行通过录像, 从而进行视频存证
|
||||
|
||||
default: NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL recordVideo;
|
||||
|
||||
/**
|
||||
人脸识别服务是否强制校验视频,当视频为空时报错
|
||||
可能会出现在部分性能差的机型
|
||||
|
||||
default: NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL checkVideo;
|
||||
|
||||
/**
|
||||
是否由SDK内部处理sdk网络请求的cookie
|
||||
|
||||
默认值: YES
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL manualCookie;
|
||||
|
||||
/**
|
||||
多语言配置
|
||||
默认中文,当使用其他语言时,强制静音
|
||||
*/
|
||||
@property (nonatomic, assign) WBFaceVerifyLanguage language;
|
||||
/**
|
||||
人脸识别页面中的主题风格, 需要配合不同资源包使用:
|
||||
WBFaceVerifyThemeDarkness - 暗灰主题
|
||||
WBFaceVerifyThemeLightness - 明亮主题
|
||||
- 当前意愿性表达只支持明亮主题, 若使用了意愿性表达功能则强制设定为明亮主题
|
||||
*/
|
||||
@property (nonatomic, assign) WBFaceVerifyTheme theme;
|
||||
|
||||
/**
|
||||
是否静音
|
||||
默认值:YES
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL mute;
|
||||
|
||||
/**
|
||||
刷脸服务走iPv6协议栈
|
||||
默认:YES
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL isIpv6 DEPRECATED_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
是否海外用户
|
||||
默认:NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL isAbroad;
|
||||
|
||||
/**
|
||||
是否打开日志上报
|
||||
1打开 0关闭 -1由SDK内部决定
|
||||
默认:-1
|
||||
*/
|
||||
@property (nonatomic, assign) NSInteger enableTrackLog DEPRECATED_ATTRIBUTE;
|
||||
/*
|
||||
送入自定义提示文案的位置
|
||||
默认:WBFaceCustomTipsLoc_Bottom
|
||||
*/
|
||||
@property (nonatomic, assign) WBFaceCustomTipsLoc tipsLoc;
|
||||
|
||||
/*
|
||||
检测过程中展示的文案
|
||||
默认为空
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *customTipsInDetect;
|
||||
|
||||
/*
|
||||
上传过程中展示的文案
|
||||
默认为空
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *customTipsInUpload;
|
||||
|
||||
/*
|
||||
底部提示文案,长度不超过70字
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSString *bottomCustomTips;
|
||||
/*
|
||||
底部提示文案(富文本版本),长度不超过70字
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSAttributedString *bottomCustomAttributedTips;
|
||||
/*
|
||||
退出二次确认UI配置
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *exitAlertTitle; //标题
|
||||
@property (nonatomic, copy) NSString *exitAlertMessage; //内容
|
||||
@property (nonatomic, copy) NSString *exitAlertYES; //确认按钮
|
||||
@property (nonatomic, copy) NSString *exitAlertNO; //取消按钮
|
||||
|
||||
/*
|
||||
如果有使用苹果分屏模式(UIWindowScene),打开此开关
|
||||
Xcode11新建工程有使用Scene,可以参考资料自行调整
|
||||
默认为NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL useWindowSecene;
|
||||
|
||||
/// 使用 hostVC 以实现基于 Modal 的 transition, **一般不需要配置, 仅建议 native 开发者使用**
|
||||
/// - IMPORTANT: **一般不需要配置, 仅建议 native 开发者酌情使用**
|
||||
@property (nonatomic, weak, nullable) UIViewController *hostVC;
|
||||
|
||||
/**
|
||||
TencentCloudHuiyanSDKFace.bundle 的目录路径,不包含bundle本身(仅当需要自己下发资源时配置,本地资源无需配置)
|
||||
!!!重要:此目录下必须包含TencentCloudHuiyanSDKFace.bundle 文件,否则无法拉起SDK
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *bundlePath;
|
||||
|
||||
/**
|
||||
face-tracker-v003.bundle 的目录路径
|
||||
|
||||
!!!重要:若有值,此目录下必须包含 face-tracker-v003.bundle 文件,否则无法拉起SDK
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSString *faceTrackerBundleDirPath;
|
||||
|
||||
/**
|
||||
face-tracker-v003.bundle 是否经过重新打包, 默认值为 NO, **一般不需要配置**
|
||||
*/
|
||||
@property (nonatomic) BOOL faceTrackerBundleRepackaged;
|
||||
|
||||
/**
|
||||
是否采用增强比对服务,仅增强接口生效,仅活体服务设置为NO
|
||||
默认为 NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL useAdvanceCompare;
|
||||
|
||||
/// 服务类型, 默认为 LiveCompare, **一般不需要修改**
|
||||
@property (nonatomic, assign) WBCompareType compareType;
|
||||
|
||||
/**
|
||||
APP是否只允许横屏,非强制横屏的不用设置,否则可能会出现旋转问题
|
||||
@default NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL forceOrientation;
|
||||
|
||||
#pragma mark - simple //非标特有字段,标准模式无需设置
|
||||
/**
|
||||
是否返回录制的视频
|
||||
|
||||
default: NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL returnVideo;
|
||||
|
||||
/**
|
||||
返回视频加密的公钥,如果不配置则不加密
|
||||
|
||||
需要recordVideo returnVideo同时为YES,才返回加密的视频内容
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *publicKey;
|
||||
|
||||
/**
|
||||
AES加密需要用到的IV
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *aesIV;
|
||||
|
||||
#pragma mark - will //意愿性特有字段,标准模式无需设置
|
||||
@property (nonatomic, assign) BOOL recordWillVideo;
|
||||
|
||||
@property (nonatomic, assign) BOOL checkWillVideo;
|
||||
|
||||
/// 播报音量,值范围(0.1,1]
|
||||
@property (nonatomic, assign) float willVolume;
|
||||
|
||||
/// 当录制意愿视频时,是否同时返回sdk+服务端视频
|
||||
@property (nonatomic, assign) BOOL uploadAndReturnWillVideo;
|
||||
/// 是否允许意愿阶段使用有线耳机, 默认不允许
|
||||
@property (nonatomic, assign) BOOL allowWillHeadset;
|
||||
#pragma mark -
|
||||
/**
|
||||
默认sdk配置
|
||||
*/
|
||||
+(instancetype)sdkConfig;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,6 @@
|
||||
framework module TencentCloudHuiyanSDKFace {
|
||||
umbrella header "TencentCloudHuiyanSDKFace.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// CamRisk.h
|
||||
// CamRisk
|
||||
//
|
||||
// Created by 徐森圣 on 2020/12/1.
|
||||
// Copyright © 2020 Tencent Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <TuringShieldCamRisk/TuringCamRiskTask.h>
|
||||
#import <TuringShieldCamRisk/TuringCamRiskService.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
!!!: 一、服务概览
|
||||
本服务旨在对摄像头风险进行识别。由于识别引擎和预测模型均在云端,因此大多数服务均为异步接口。
|
||||
|
||||
!!!: 二、主要接口介绍
|
||||
|
||||
TuringCamRiskService
|
||||
|
|
||||
| 创建检测任务
|
||||
|
|
||||
v
|
||||
TuringCamRiskTask
|
||||
|
|
||||
| 产生请求数据
|
||||
v
|
||||
NSData
|
||||
|
||||
更多的信息请参阅 TuringCamRiskService.h 和 TuringCamRiskTask.h中的注释
|
||||
|
||||
!!!: 三、一般使用范例
|
||||
```objective-c
|
||||
// 为服务配置上下文(可用的key有多个,这里只简单例举一个,参见TuringCamRiskContextKey中的枚举字符串)
|
||||
[[TuringCamRiskService sharedService] setupContext:@{ TuringCamRiskContextAppIDKey: @"F.R.D." }];
|
||||
|
||||
// 创建一个检测任务
|
||||
TuringCamRiskTask *task = [[TuringCamRiskService sharedService] taskForSceneID:nil];
|
||||
// 为任务指定监控的视图,检测群控风险(此动作可选)
|
||||
[task monitorView:[UIApplication sharedApplication].keyWindow];
|
||||
// 为任务指定监控的摄像头设备,检测劫持风险(注意请提供正在使用的设备;此动作可选)
|
||||
[task monitorCameraWithDevice:cameraDevice session:captureSession previewView:previewLayer];
|
||||
// 获取用于请求的数据
|
||||
[task queryPostDataWithCompletionHandler:^(NSData * _Nullable data, NSError * _Nullable error) {
|
||||
// 如果成功,data非空,error为空;如果失败,data为空,error非空
|
||||
// data可用于http post直接请求图灵盾服务
|
||||
NSLog(@"data = %@, error = %@", error);
|
||||
}];
|
||||
```
|
||||
*/
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// TuringCamRiskService.h
|
||||
// TuringShieldCamRisk
|
||||
//
|
||||
// Created by 徐森圣 on 2020/12/2.
|
||||
// Copyright © 2020 Tencent Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <TuringShieldCamRisk/TuringServiceDefine.h>
|
||||
#import <TuringShieldCamRisk/TuringServiceSettings.h>
|
||||
#import <TuringShieldCamRisk/TuringCamRiskTask.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// 这些常量值用于设置或获取context中的字典数据中的key。
|
||||
typedef NSString * TuringCamRiskContextKey NS_EXTENSIBLE_STRING_ENUM;
|
||||
|
||||
/// 用于设置请求序列编号的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextRequestSequenceKey;
|
||||
|
||||
/// 用于设置meta data的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextMetaDataKey;
|
||||
|
||||
/// 用于设置接入渠道号的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextChannelKey;
|
||||
|
||||
/// 用于设置接入构建号的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSNumber *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextBuildNoKey;
|
||||
|
||||
/// 用于设置接入版本号的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextVersionKey;
|
||||
|
||||
/// 用于设置接入版本LC的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextLCKey;
|
||||
|
||||
/// 用于设置其它额外信息的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextExtraInfoKey;
|
||||
|
||||
/// 用于设置接入App ID的key,参见 `TuringCamRiskContextKey`。该key对应的值应为 NSString *。
|
||||
extern TuringCamRiskContextKey const _Nonnull TuringCamRiskContextAppIDKey;
|
||||
|
||||
|
||||
@interface TuringCamRiskConfiguration : NSObject
|
||||
|
||||
/// 禁止直接生成实例
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@property (assign) int32_t channelID TS_AVAILABLE_IF(TS_ENABLES_CUSTOM_CHANNEL_ID);
|
||||
@property (nullable, nonatomic, copy) NSString *URLForTarsServer TS_AVAILABLE_IF(TS_NETWORKING_TMF_SHARK_SUPPORTS);
|
||||
@property (nullable, nonatomic, copy) NSString *valificationFilePath TS_AVAILABLE_IF(TS_USING_SIGN_VALIFICATION);
|
||||
|
||||
@end
|
||||
|
||||
@interface TuringCamRiskService : NSObject
|
||||
|
||||
+ (nullable NSError *)setupWithConfiguration:(nullable void(^)(TuringCamRiskConfiguration *_Nonnull config))configurationHandler;
|
||||
|
||||
+ (void)setupTarsServerWithURL:(nonnull NSString *)URLString withChannelID:(int32_t)ChannelID TS_AVAILABLE_IF(TS_NETWORKING_TMF_SHARK_SUPPORTS)
|
||||
TS_MSG_DEPRECATED("Use `-setupTarsServerWithURL:withChannelID:withLicense:` instead");
|
||||
|
||||
/// 禁止直接生成实例
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/// 所有服务均以此单例提供
|
||||
+ (nonnull instancetype)sharedService;
|
||||
|
||||
/// 预连接服务器网络,以便加速后续请求的回应速度
|
||||
+ (void)touchNetworking;
|
||||
|
||||
/// 设置全局回调,用于控制HTTP请求的发送
|
||||
/// @param callback 该回调会回传HTTP请求所使用的request对象,修改对象属性可改变请求的行为。回调返回NO时将取消请求,否则正常执行请求。
|
||||
/// @discussion 图灵盾完成一个操作可能会执行多个HTTP请求,中途改变请求的http目标后,无法确保原子操作,需要业务自行控制。建议在调用图灵盾任何操作前调用,并且只调用一次。
|
||||
+ (void)setupTarsHTTPPostCallback:(nullable BOOL(^)(NSMutableURLRequest *_Nonnull request))callback TS_AVAILABLE_IF(TS_ALLOWS_HTTP_POST_HANDLING);
|
||||
|
||||
/// 设置调用相关的上下文。这些上下文由业务设置,同时回传业务的后端,用于数据稽核。
|
||||
/// @param context 上下文的内容。字典中用到的key,请参考`TuringCamRiskContextKey`及其常量定义。
|
||||
- (void)setupContext:(nonnull NSDictionary<TuringCamRiskContextKey, id> *)context;
|
||||
|
||||
/// 生成一个摄像头检测任务并接受TuringCamRiskService的管理。如果相同sceneID的任务已经生成,则会
|
||||
/// 返回同一个任务实例,直到该实例被`- detatchTask:`释放。
|
||||
/// @param sceneID 摄像头检测任务的场景ID
|
||||
/// @discussion 如果sceneID为空,则该任务不会被TuringCamRiskService管理,也不需要调用
|
||||
/// `- detatchTask:`释放
|
||||
- (nonnull TuringCamRiskTask *)taskForSceneID:(nullable NSString *)sceneID;
|
||||
|
||||
/// 释放一个摄像头检测任务
|
||||
/// @param task 要释放的任务实例
|
||||
- (void)detatchTask:(nonnull TuringCamRiskTask *)task;
|
||||
|
||||
+ (nonnull NSDictionary *)SDKInfo;
|
||||
|
||||
@end
|
||||
|
||||
@interface TuringCamRiskService (Validation)
|
||||
|
||||
+ (nullable NSError *)verifySDKUsingLisence:(nullable NSString *)licenseFilePath TS_AVAILABLE_IF(TS_USING_SIGN_VALIFICATION);
|
||||
|
||||
@end
|
||||
|
||||
/// 设备实时风险标签
|
||||
@interface TuringCamRiskService (RiskToken)
|
||||
|
||||
/// 获取实时风险标签
|
||||
/// @param usingCache 是否使用缓存。YES表示由图灵盾SDK根据缓存策略,决定是否更新缓存;NO表示总是联网获取实时结果。
|
||||
/// @param completion 获取结果的回调
|
||||
/// @discussion 一般我们建议usingCache设置为YES。仅当在对风险检测要求特别高的场景下,才设置为NO。图灵盾SDK能有效管理缓存并确保缓存的检测安全效果,同时节省请求流量和服务计算成本。同时,由于您可能不够理解何时可以使用缓存而何时需要更新缓存,因此我们不建议客户端自行缓存我们的结果。
|
||||
- (void)fetchRiskTokenUsingCache:(BOOL)usingCache WithCompletionHandler:(nonnull void(^)(NSString *_Nullable message, NSError *_Nullable error))completion TS_AVAILABLE_IF(TS_ENABLES_RISK_DETECT_FEATURE);
|
||||
|
||||
@end
|
||||
|
||||
@interface TuringCamRiskService (Debugging)
|
||||
|
||||
/// 设置是否使用测试服务器
|
||||
/// @discussion 注意只能在未使用任何 TuringCamRiskService 的服务之前设置,否则某些正在进行中的
|
||||
/// 服务可能会出现错误
|
||||
@property (class, nonatomic) BOOL usesDebugServer TS_AVAILABLE_IF(__TS_OR(TS_NETWORKING_WUP_SUPPORTS, TS_NETWORKING_SHARK_SUPPORTS));
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// TuringCamRiskTask.h
|
||||
// TuringShieldCamRisk
|
||||
//
|
||||
// Created by 徐森圣 on 2020/12/2.
|
||||
// Copyright © 2020 Tencent Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
/// 摄像头检测任务
|
||||
/// @example
|
||||
/// ```
|
||||
/// [task queryPostDataWithCompletionHandler:^(NSData * _Nullable data, NSError * _Nullable error) {
|
||||
/// // error为空时可以用于发送到图灵盾服务器
|
||||
/// }];
|
||||
/// ```
|
||||
@interface TuringCamRiskTask : NSObject
|
||||
|
||||
/// 禁止直接创建摄像头检测任务
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/// 为任务指定要监控的摄像头设备及其相关信息,需要调用`-postWithCompletionHandler:`或者
|
||||
/// `-queryPostDataWithCompletionHandler`之前调用。
|
||||
/// @param cameraDevice 受监控的摄像头设备
|
||||
/// @param session 受监控的摄像会话
|
||||
/// @param previewLayer 受监控的预览图层
|
||||
/// @discussion 调用该方法是可选的,但会提升检测的准确性
|
||||
- (void)monitorCameraWithDevice:(nullable AVCaptureDevice *)cameraDevice session:(nullable AVCaptureSession *)session previewView:(nullable AVCaptureVideoPreviewLayer *)previewLayer;
|
||||
|
||||
/// 为任务指定要监控的用户界面,通常是一个用户可操作的视图,例如viewController.view,或者一个按钮
|
||||
/// @param view 受监控的用户界面
|
||||
/// @discussion 调用该方法是可选的,但会提升检测的准确性
|
||||
- (void)monitorView:(nonnull UIView *)view;
|
||||
|
||||
/// 请求检测
|
||||
/// @param completionHandler 请求完成的回调函数。如果正确返回,则result非空,否则error非空
|
||||
/// @discussion 数据将会直接发送到图灵盾服务器,只是为了便于测试连通性而提供该接口。
|
||||
- (void)postWithCompletionHandler:(nullable void(^)(NSDictionary<NSString *, id> *_Nullable result, NSError *_Nullable error))completionHandler;
|
||||
|
||||
/// 生成用于请求的数据包
|
||||
/// @param completionHandler 请求完成的回调函数。如果正确返回,则data非空,否则error非空
|
||||
- (void)queryPostDataWithCompletionHandler:(nonnull void(^)(NSData *_Nullable data, NSError *_Nullable error))completionHandler;
|
||||
|
||||
/// 任务的场景ID
|
||||
@property (nonatomic, copy, readonly, nonnull) NSString *scene;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
//
|
||||
// TuringServiceDefine.h
|
||||
// TuringShield
|
||||
//
|
||||
// Created by 徐森圣 on 2018/3/13.
|
||||
// Copyright © 2018年 Tecent Inc. All rights reserved.
|
||||
//
|
||||
// $$api_level=TS_TURING_SHIELD_OPEN_API_LEVEL$$
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __TURING_SERVICE_DEFINE_H__
|
||||
#define __TURING_SERVICE_DEFINE_H__
|
||||
|
||||
#import "TuringServiceSettings.h"
|
||||
|
||||
#define TS_OBJECT_CLASS(name) TS_CLASS_##name
|
||||
|
||||
#define TS_OBJECT_IMPL(name) TS_REAL_##name
|
||||
|
||||
#define TS_OBJECT_DECL(name) \
|
||||
@protocol TS_OBJECT_CLASS(name) <NSObject> \
|
||||
@end \
|
||||
typedef NSObject<TS_OBJECT_CLASS(name)> *name##_t
|
||||
|
||||
#define TS_OBJECT_DECL_SUBCLASS(name, super) \
|
||||
@protocol TS_OBJECT_CLASS(name) <TS_OBJECT_CLASS(super)> \
|
||||
@end \
|
||||
typedef NSObject<TS_OBJECT_CLASS(name)> *name##_t
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define TS_BEGIN_DECLS extern "C" {
|
||||
#define TS_END_DECLS }
|
||||
#else
|
||||
#define TS_BEGIN_DECLS
|
||||
#define TS_END_DECLS
|
||||
#endif
|
||||
|
||||
TS_OBJECT_DECL(ts_object);
|
||||
|
||||
|
||||
/**
|
||||
将浮点类型的秒数转换为长整数类型的毫秒数
|
||||
|
||||
@param sec 秒数,需要为double类型
|
||||
@return 毫秒数,long long类型
|
||||
*/
|
||||
#define SEC_TO_MSEC(sec) (int64_t)( (sec) * 1000ll )
|
||||
|
||||
|
||||
|
||||
/**
|
||||
如果condition的定义为0或未定义,则声明函数不可用
|
||||
|
||||
@param condition 一个可展开的宏定义
|
||||
*/
|
||||
#define TS_AVAILABLE_IF(condition) \
|
||||
__TS_IF_ELSE(condition) \
|
||||
/*Case True*/ (__TS_EMPTY()) \
|
||||
/*Case False*/(UNAVAILABLE_ATTRIBUTE)
|
||||
|
||||
|
||||
/**
|
||||
如果c1或c2中任意一个的定义为0或未定义,则声明函数不可用
|
||||
|
||||
@param c1 条件1,一个可展开的宏定义
|
||||
@param c2 条件2,一个可展开的宏定义
|
||||
*/
|
||||
#define TS_AVAILABLE_IFS(c1, c2) \
|
||||
__TS_IF_ELSE(c1) \
|
||||
/*Case True*/ (TS_AVAILABLE_IF(c2)) \
|
||||
/*Case False*/(UNAVAILABLE_ATTRIBUTE)
|
||||
|
||||
|
||||
/**
|
||||
如果当前线程是主线程,直接执行包含的短语句;如果当前不在主线
|
||||
程,将包含的短语句调度到主线程执行,并阻塞当前线程。
|
||||
|
||||
@param ... 一个需要调度到主线程执行的短语句
|
||||
*/
|
||||
#define TSMainThreadProtectCall(...) do { \
|
||||
if ([NSThread isMainThread] == NO) { \
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ \
|
||||
__VA_ARGS__; \
|
||||
}); \
|
||||
} \
|
||||
else { \
|
||||
__VA_ARGS__; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
如果当前线程是主线程,直接执行包含的短语句;如果当前不在主线
|
||||
程,将包含的短语句调度到主线程执行,并阻塞当前线程。然后返回
|
||||
短语句执行的结果。注意,如果返回值是Objective C对象,目前
|
||||
不支持MRC。
|
||||
|
||||
@param ... 一个需要调度到主线程执行的短语句
|
||||
@return 短语句的返回值
|
||||
*/
|
||||
#define TSMainThreadProtectGet(...) ({ \
|
||||
typeof(__VA_ARGS__) val; \
|
||||
if ([NSThread isMainThread] == NO) { \
|
||||
__block typeof(val) bval; \
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ \
|
||||
bval = __VA_ARGS__; \
|
||||
}); \
|
||||
val = bval; \
|
||||
} \
|
||||
else { \
|
||||
val = __VA_ARGS__; \
|
||||
} \
|
||||
val; \
|
||||
})
|
||||
|
||||
|
||||
#define __1second (1.0f)
|
||||
#define __10seconds (__1second * 10)
|
||||
#define __20seconds (__1second * 20)
|
||||
#define __1minute (__1second * 60)
|
||||
#define __10minutes (__1minute * 10)
|
||||
#define __30minutes (__1minute * 30)
|
||||
#define __1hour (__1minute * 60)
|
||||
#define __1day (__1hour * 24)
|
||||
#define __1week (__1day * 7)
|
||||
|
||||
#define ts_shutup(v) (void)(v)
|
||||
|
||||
|
||||
///
|
||||
/// there's a stupid bug in @available:
|
||||
/// If we build TuringShield in Xcode 11 and use @available in TuringShield, Xcode 11 is ALSO required
|
||||
/// on building the An app that integrating TuringShield. The main reason is, the implementation of
|
||||
/// @available in Xcode 11 is different to the one in Xcode 10.
|
||||
/// So let's disable @available for time being.
|
||||
///
|
||||
#if 0
|
||||
#define ts_ios_version_is_at_least(major, minor, patch) @available(iOS major##.##minor##.##patch, *)
|
||||
#else
|
||||
#define ts_ios_version_is_at_least(major, minor, patch) \
|
||||
({ \
|
||||
NSOperatingSystemVersion v = \
|
||||
NSProcessInfo.processInfo.operatingSystemVersion; \
|
||||
v.majorVersion == major ? \
|
||||
( v.minorVersion == minor ? \
|
||||
( v.patchVersion >= patch ) : \
|
||||
( v.minorVersion > minor ) ) : \
|
||||
( v.majorVersion > major ); \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TS_SDK_CHANNEL_ID) && TS_USES_CLASS_ALIAS
|
||||
#define tsclassname(name) __TS_CAT(name, TS_ALIAS_SURFIX)
|
||||
#define tsmethodname(name) __TS_CAT(TS_ALIAS_SURFIX, name)
|
||||
#define tsclass(className) class tsclassname(className); @compatibility_alias className tsclassname(className)
|
||||
#else
|
||||
#define tsclassname(name) name
|
||||
#define tsmethodname(name) name
|
||||
#define tsclass(className) class className
|
||||
#endif
|
||||
|
||||
#define ts_channel_alias(name) __TS_CAT(name, __TS_CAT(_, TS_SDK_CHANNEL_ID))
|
||||
|
||||
#define TS_DEPRECATED __attribute__((deprecated))
|
||||
#define TS_MSG_DEPRECATED(msg) __attribute((deprecated((msg))))
|
||||
|
||||
#pragma mark - Inner Macro, do NOT use
|
||||
|
||||
|
||||
#define __TS_ARG_0_(n, ...) n
|
||||
#define __TS_ARG_1_(x0, n, ...) n
|
||||
#define __TS_ARG_2_(x0, x1, n, ...) n
|
||||
#define __TS_ARG_3_(x0, x1, x2, n, ...) n
|
||||
#define __TS_ARG_4_(x0, x1, x2, x3, n, ...) n
|
||||
#define __TS_ARG_5_(x0, x1, x2, x3, x4, n, ...) n
|
||||
#define __TS_ARG_6_(x0, x1, x2, x3, x4, x5, n, ...) n
|
||||
#define __TS_ARG_7_(x0, x1, x2, x3, x4, x5, x6, n, ...) n
|
||||
#define __TS_ARG_8_(x0, x1, x2, x3, x4, x5, x6, x7, n, ...) n
|
||||
#define __TS_ARG_9_(x0, x1, x2, x3, x4, x5, x6, x7, x8, n, ...) n
|
||||
|
||||
#define __TS_EVAL(...) __TS_EVAL1(__TS_EVAL1(__TS_EVAL1(__VA_ARGS__)))
|
||||
#define __TS_EVAL1(...) __TS_EVAL2(__TS_EVAL2(__TS_EVAL2(__VA_ARGS__)))
|
||||
#define __TS_EVAL2(...) __TS_EVAL3(__TS_EVAL3(__TS_EVAL3(__VA_ARGS__)))
|
||||
#define __TS_EVAL3(...) __TS_EVAL4(__TS_EVAL4(__TS_EVAL4(__VA_ARGS__)))
|
||||
#define __TS_EVAL4(...) __TS_EVAL5(__TS_EVAL5(__TS_EVAL5(__VA_ARGS__)))
|
||||
#define __TS_EVAL5(...) __VA_ARGS__
|
||||
|
||||
#define __TS_TO_CSTRING_(str) #str
|
||||
#define __TS_TO_CSTRING(...) __TS_TO_CSTRING_(__VA_ARGS__)
|
||||
|
||||
#define __TS_TO_NSSTRING_(str) @#str
|
||||
#define __TS_TO_NSSTRING(...) __TS_TO_NSSTRING_(__VA_ARGS__)
|
||||
|
||||
#define __TS_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
|
||||
#define __TS_CAT(a, ...) __TS_PRIMITIVE_CAT(a, __VA_ARGS__)
|
||||
|
||||
#define __TS_ARG_0(n, ...) n
|
||||
#define __TS_ARG_1(x0, n, ...) n
|
||||
#define __TS_IS_PROBE(...) __TS_ARG_1(__VA_ARGS__, 0)
|
||||
#define __TS_PROBE() ~, 1
|
||||
#define __TS_NOT(x) __TS_IS_PROBE(__TS_CAT(__TS_NOT_, x))
|
||||
#define __TS_NOT_0 __TS_PROBE()
|
||||
#define __TS_BOOL(x) __TS_NOT(__TS_NOT(x))
|
||||
|
||||
#define __TS_AND(x1, x2) __TS_IF_ELSE(x1)(__TS_IF_ELSE(x2)(1)(0))(0)
|
||||
#define __TS_AND_3(x1, x2, x3) __TS_AND(x1, __TS_AND(x2, x3))
|
||||
#define __TS_AND_4(x1, x2, x3, x4) __TS_AND(__TS_AND(x1, x2), __TS_AND(x3, x4))
|
||||
|
||||
#define __TS_OR(x1, x2) __TS_IF_ELSE(x1)(1)(__TS_IF_ELSE(x2)(1)(0))
|
||||
#define __TS_OR_3(x1, x2, x3) __TS_OR(x1, __TS_OR(x2, x3))
|
||||
|
||||
#define __TS_IIF(c) __TS_PRIMITIVE_CAT(__TS_IIF_, c)
|
||||
#define __TS_IIF_0(...)
|
||||
#define __TS_IIF_1(...) __VA_ARGS__
|
||||
|
||||
#define __TS_IELSE(c) __TS_PRIMITIVE_CAT(__TS_IELSE_, c)
|
||||
#define __TS_IELSE_0(...) __VA_ARGS__
|
||||
#define __TS_IELSE_1(...)
|
||||
|
||||
#define __TS_IIF_ELSE(c) __TS_PRIMITIVE_CAT(__TS_IIF_ELSE_, c)
|
||||
#define __TS_IIF_ELSE_0(...) __TS_IELSE_0
|
||||
#define __TS_IIF_ELSE_1(...) __VA_ARGS__ __TS_IELSE_1
|
||||
|
||||
#define __TS_IF(c) __TS_IIF(__TS_BOOL(c))
|
||||
#define __TS_IF_ELSE(c) __TS_IIF_ELSE(__TS_BOOL(c))
|
||||
|
||||
#define __TS_EMPTY()
|
||||
#define __TS_DEFER(id) id __TS_EMPTY()
|
||||
#define __TS_OBSTRUCT(...) __VA_ARGS__ __TS_DEFER(__TS_EMPTY)()
|
||||
|
||||
|
||||
#pragma mark - API Levels
|
||||
|
||||
#define TS_ALWAYS_VISIBLE __attribute__ ((visibility ("default")))
|
||||
#define TS_ALWAYS_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
|
||||
|
||||
#define TS_TURING_HIGHER_WRAPPER_LEVEL 1
|
||||
#define TS_TURING_SHIELD_OPEN_API_LEVEL 2
|
||||
#define TS_FRIENDLY_API_LEVEL 3
|
||||
#define TS_PRIVATE_LEVEL 4
|
||||
|
||||
|
||||
#if TS_API_LEVEL >= TS_TURING_HIGHER_WRAPPER_LEVEL && !!TS_TURING_ID_WRAPPER_APIS
|
||||
# define TS_TURING_ID_API 1
|
||||
#else
|
||||
# define TS_TURING_ID_API 0
|
||||
#endif
|
||||
|
||||
#if TS_API_LEVEL >= TS_TURING_HIGHER_WRAPPER_LEVEL && !!TS_TURING_AGE_WRAPPER_APIS
|
||||
# define TS_TURING_AGE_API 1
|
||||
#else
|
||||
# define TS_TURING_AGE_API 0
|
||||
#endif
|
||||
|
||||
#if TS_API_LEVEL >= TS_TURING_SHIELD_OPEN_API_LEVEL
|
||||
# define TS_TURING_SHIELD_OPEN_API 1
|
||||
#else
|
||||
# define TS_TURING_SHIELD_OPEN_API 0
|
||||
#endif
|
||||
|
||||
#if TS_API_LEVEL >= TS_FRIENDLY_API_LEVEL
|
||||
# define TS_FRIENDLY_API 1
|
||||
#else
|
||||
# define TS_FRIENDLY_API 0
|
||||
#endif
|
||||
|
||||
#if TS_API_LEVEL >= TS_PRIVATE_LEVEL
|
||||
# define TS_PRIVATE 1
|
||||
#else
|
||||
# define TS_PRIVATE 0
|
||||
#endif
|
||||
|
||||
#define TS_VISIBLE_LEVEL(APIKind) \
|
||||
__TS_IF_ELSE(APIKind) \
|
||||
/*CASE TRUE*/ (TS_ALWAYS_VISIBLE) \
|
||||
/*CASE FALSE*/ (TS_ALWAYS_HIDDEN)
|
||||
|
||||
|
||||
|
||||
#endif /* __TURING_SERVICE_DEFINE_H__ */
|
||||
@@ -0,0 +1,258 @@
|
||||
//
|
||||
// TuringServiceSettings.h
|
||||
// TuringShield
|
||||
//
|
||||
// Created by 徐森圣 on 2018/3/19.
|
||||
// Copyright © 2018年 Tecent Inc. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#ifndef TuringServiceSettings_h
|
||||
#define TuringServiceSettings_h
|
||||
|
||||
|
||||
/**
|
||||
编译目标,用于检查变量是否正确
|
||||
格式为TS_BUILD_TARGET_xxx
|
||||
|
||||
@discussion
|
||||
受Build Settings中环境变量TS_BUILD_TARGET影响并自动更新
|
||||
*/
|
||||
#define TS_BUILD_TARGET_YOUTU
|
||||
|
||||
/**
|
||||
定义为1,使用主人识别模型
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_OWNER_PROJECT 0
|
||||
|
||||
|
||||
/**
|
||||
定义为1,使用青少年识别模型
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_AGE_PROJECT 0
|
||||
|
||||
/**
|
||||
定义为1,使用人机识别模型
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_HUMAN_PROJECT 0
|
||||
|
||||
/**
|
||||
渠道号,用于决定用哪个模型
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_SDK_CHANNEL_ID 108138
|
||||
#define TS_SDK_CHANNEL_STRING __TS_TO_NSSTRING(TS_SDK_CHANNEL_ID)
|
||||
|
||||
/**
|
||||
SDK是否自带数据请求和回复逻辑
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_DATA_SENDING 1
|
||||
|
||||
/**
|
||||
SDK是否自带数据处理逻辑
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_PREDICTION_PROCEEDING 1
|
||||
|
||||
|
||||
/**
|
||||
SDK是否带请求签名逻辑,云端请求需要WAF服务配合,SDK需要打开
|
||||
TS_ENABLES_DATA_SENDING和TS_HUMAN_PROJECT
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_HTTP_REQUEST_SIGN 0
|
||||
|
||||
/**
|
||||
如果设置为非0,则同一个场景(scene)和事件(action)最多保留指定数量的数据
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_LIMITED_RECORDS_PER_SCENE_ACTION 20
|
||||
|
||||
/**
|
||||
实验室模式,某些逻辑在工程化前后可能有变化,服务器接口的调用方式也可能不一致
|
||||
目前人机部分默认值为0,主人识别部分默认值为1
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_LAB_LOGIC 0
|
||||
|
||||
/**
|
||||
打开日志打印
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENALBLES_LOG_PRINT 0
|
||||
|
||||
/**
|
||||
使用模型预测之前不检查数据非空
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_DONT_CHECK_DATA_SIZE 0
|
||||
|
||||
/**
|
||||
不记录(当然也不上报)触摸事件中的位置信息
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_DONT_RECORD_TOUCH_POSITION 0
|
||||
|
||||
|
||||
/**
|
||||
不加密打包的数据
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_DONT_ENCRYPT_PACKING_DATA 0
|
||||
|
||||
/**
|
||||
不压缩打包的数据
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_DONT_COMPRESS_PACKING_DATA 0
|
||||
|
||||
/**
|
||||
使用设备指纹特性
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_FINGERPRINT_FEATURE 1
|
||||
|
||||
/**
|
||||
支持的打包方式:WUP协议
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_NETWORKING_WUP_SUPPORTS 1
|
||||
|
||||
/**
|
||||
支持的打包方式:Shark协议
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_NETWORKING_SHARK_SUPPORTS 1
|
||||
|
||||
/**
|
||||
支持的打包方式:TMF Shark协议
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_NETWORKING_TMF_SHARK_SUPPORTS 0
|
||||
|
||||
|
||||
/**
|
||||
是否支持云控设备指纹配置;目前私有化部署不支持该选项
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_FINGERPRINT_CONFIG_CONTROL 1
|
||||
|
||||
|
||||
/**
|
||||
是否支持关键API篡改检测
|
||||
|
||||
@discussion
|
||||
受Build Settings中同名环境变量影响并自动更新
|
||||
*/
|
||||
#define TS_ENABLES_KEYED_API_CHECKING 1
|
||||
|
||||
|
||||
/**
|
||||
绑定的App bundle ID
|
||||
|
||||
@discussion
|
||||
设置后SDK将只能运行在指定的App上
|
||||
*/
|
||||
#define TS_BOUND_BUNDLE_IDENTIFIER nil
|
||||
#define TS_BOUND_BUNDLE_TOKEN { 0x00 }
|
||||
|
||||
|
||||
/**
|
||||
是否允许多渠道复用SDK
|
||||
|
||||
@discussion
|
||||
若打开,并且初始渠道号为0,则必须设置渠道号后才可以开始调用相关功能
|
||||
*/
|
||||
#define TS_ENABLES_CUSTOM_CHANNEL_ID 0
|
||||
|
||||
|
||||
|
||||
#define TS_DOMAIN_PREFIX_TOKEN com.tencent.TuringShield.
|
||||
#define TS_DOMAIN_PREFIX_CSTRING __TS_TO_CSTRING(TS_DOMAIN_PREFIX_TOKEN)
|
||||
#define TS_DOMAIN_PREFIX_STRING __TS_TO_NSSTRING(TS_DOMAIN_PREFIX_TOKEN)
|
||||
#define TS_DOMAIN_FOR_REACHABLITTY_TEST 8.8.8.8
|
||||
#define TS_DOMAIN_FOR_REACHABLITTY_TEST_CSTRING __TS_TO_CSTRING(TS_DOMAIN_FOR_REACHABLITTY_TEST)
|
||||
#define TS_DOMAIN_FOR_REACHABLITTY_TEST_STRING __TS_TO_NSSTRING(TS_DOMAIN_FOR_REACHABLITTY_TEST)
|
||||
|
||||
/**
|
||||
一些临时用的开关
|
||||
*/
|
||||
#define TS_ENABLES_SENSOR_RECORDING 0
|
||||
#define TS_ENABLES_SENSOR_REPLAYING 0
|
||||
#define TS_USES_OLD_MOTION_TRACKER_IF_NEEDED 1
|
||||
#define TS_ENABLES_CUSTOM_CLIENT_VERSION 0
|
||||
#define TS_ENABLES_CUSTOM_CHANNEL_ID 0
|
||||
#define TS_USES_CLASS_ALIAS 2
|
||||
#define TS_ACT_AS_TAID_ADVERTISER 0
|
||||
#define TS_ACT_AS_TAID_PROVIDER 1
|
||||
#define TS_ENABLES_FINGERPRINT_CONFIG_TEST 0
|
||||
#define TS_API_LEVEL TS_FRIENDLY_API_LEVEL
|
||||
#define TS_AVOID_USING_IDFA 1
|
||||
#define TS_FEATURE_DELEGATION 0
|
||||
#define TS_ENABLES_DEVICE_INFO_ACCESS 0
|
||||
|
||||
#define TS_TURING_ID_WRAPPER_APIS 0
|
||||
#define TS_TURING_AGE_WRAPPER_APIS 0
|
||||
#define TS_ANTIBOT_SDK 0
|
||||
#define TS_RISK_TOKEN_SDK 0
|
||||
#define TS_ENABLES_UAID_FETCHING 0
|
||||
#define TS_ENABLES_PHONE_MASK_FETCHING 0
|
||||
#define TS_ENABLES_RISK_DETECT_FEATURE 1
|
||||
#define TS_USES_RANDOM_NAMING 1
|
||||
#define TS_USES_GMSSL_AS_ENCRYPTION_ALGORITHM 0
|
||||
#define TS_ALLOWS_HTTP_POST_HANDLING 1
|
||||
#define TS_SKIP_GATHERER_AUTO_HANDLING 0
|
||||
#define TS_SIGNING_TOKEN_FEATURE 0
|
||||
#define TS_USING_SIGN_VALIFICATION 0
|
||||
#define TS_ENABLES_UNIVERSAL_TOKEN 0
|
||||
#define TS_USES_IDFV_LOCK 0
|
||||
#define TS_CAFISBRAIN_SDK 0
|
||||
|
||||
#define TS_SDK_VERSION 20074
|
||||
#define TS_SDK_LC_CODE QINN2D9KC5XY90F0
|
||||
#define TS_SDK_LC __TS_TO_NSSTRING(TS_SDK_LC_CODE)
|
||||
#define TS_SDK_BUILD_DATE 2024-08-15 19:28:34
|
||||
#define TS_ALIAS_SURFIX _YOUTU108138v20074
|
||||
|
||||
#endif /* TuringServiceSettings_h */
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
#define ANDROID_CUSTOM_NONE (1)
|
||||
#define ANDROID_CUSTOM_FOR_IOT (0)
|
||||
#define ANDROID_CUSTOM_FOR_UNIONPAY (0)
|
||||
#define ANDROID_CUSTOM_SUPPORT_VTS (0)
|
||||
//vts && vndk: https://source.android.com/devices/architecture/images/VNDK.pdf
|
||||
|
||||
#define CUSTOM_FOR_QQ (0)
|
||||
|
||||
#define ALLOW_EMPTY_SECRET_KEY (1)
|
||||
|
||||
|
||||
// change namespace for different business
|
||||
#define YTLICENSE_NAMESPACE ytliveness
|
||||
#define CLASS_WITH_PREFIX(__class) YTLiveness##__class
|
||||
#define FUNCTION_WITH_PREFIX(__func) ytliveness_##__func
|
||||
#define INNER_INTERFACE_USE_NAMESPACE (1)
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file yt_auth.h
|
||||
* @author tencent
|
||||
* @brief 鉴权接口
|
||||
* @version 2.0
|
||||
* @date 2020-09-10
|
||||
*
|
||||
* @copyright Copyright (c) 2020
|
||||
*
|
||||
*/
|
||||
#ifndef _YT_AUTH_H_
|
||||
#define _YT_AUTH_H_
|
||||
|
||||
#include "yt_defines.h"
|
||||
|
||||
// license文件申请:https://docs.qq.com/doc/DZERXWmNYeVNyWlF0
|
||||
|
||||
/**
|
||||
* @brief 使用license文件初始化授权
|
||||
* @param `platform_context` Android平台输入JNIEnv*;其他平台输入NULL
|
||||
* @param `license_path` Android平台将license文件打包到assets中,传入文件名;其他平台传入文件完整路径
|
||||
* @param `secret_key` 传入license对应的secret_key,在申请的时候获得
|
||||
* @return 授权结果,0代表成功,错误码参考:[授权错误代码](#errorcode)
|
||||
*/
|
||||
YT_PUBLIC int ytliveness_auth_init_by_path(void* platform_context, const char* license_path, const char* secret_key);
|
||||
|
||||
/**
|
||||
* @brief 使用license字符串初始化鉴权,字符串获取方式:将license文件做base64即可
|
||||
* @param `platform_context` Android平台输入JNIEnv*;其他平台输入NULL
|
||||
* @param `license_string` license字符串
|
||||
* @param `secret_key` 传入license对应的secret_key,在申请的时候获得
|
||||
* @return 授权结果,0代表成功,错误码参考:[授权错误代码](#errorcode)
|
||||
*/
|
||||
YT_PUBLIC int ytliveness_auth_init_by_string(void* platform_context, const char* license_string, const char* secret_key);
|
||||
|
||||
/**
|
||||
* @brief 腾讯内部业务专用授权接口
|
||||
* @param `platform_context` Android平台输入JNIEnv*;其他平台输入NULL
|
||||
* @return 授权结果,0代表成功,错误码参考:[授权错误代码](#errorcode)
|
||||
*/
|
||||
YT_PUBLIC int ytliveness_auth_init_for_qq(void* platform_context);
|
||||
|
||||
/**
|
||||
* @brief 授权成功后,查询授权有效期
|
||||
* @return 授权到期时间的时间戳
|
||||
*/
|
||||
YT_PUBLIC long long ytliveness_auth_get_endtime();
|
||||
|
||||
/**
|
||||
* @brief 查询授权库的版本
|
||||
* @return 授权库的版本号
|
||||
*/
|
||||
YT_PUBLIC const char* ytliveness_auth_get_version();
|
||||
|
||||
/**
|
||||
* @brief 获取已授权的SDK列表
|
||||
* @param sdklist_buf 出参,返回sdklist,调用者自己分配一个int[]数组用于存储SDKlist
|
||||
* @param max_count 入参,传入的sdklist_buf的最大index
|
||||
* @return 实际返回的sdklist数量
|
||||
* @note 如果sdklist_buf传NULL,返回值代表SDK列表的总数
|
||||
*/
|
||||
YT_PUBLIC int ytliveness_auth_get_sdklist_ids(int* sdklist_buf, int max_count);
|
||||
|
||||
/**
|
||||
* @brief 获取sdk_id代表的SDK名称
|
||||
* @param sdk_id
|
||||
* @return 该id代表的SDK名称
|
||||
*/
|
||||
YT_PUBLIC const char* ytliveness_auth_get_sdkname(int sdk_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 设置是否显示log,默认为显示
|
||||
* @param enable,1-显示 0-不显示
|
||||
* @return
|
||||
*/
|
||||
YT_PUBLIC void ytliveness_auth_enable_log(int enable);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
__attribute__((visibility("default"))) @interface YTLivenessAuthManager : NSObject
|
||||
|
||||
+ (int)initAuthByFilePath:(NSString*) license_path withSecretKey:(NSString*) secret_key;
|
||||
|
||||
+ (int)initAuthByString:(NSString*) license_string withSecretKey:(NSString*) secret_key;
|
||||
|
||||
+ (int)initAuthForQQ;
|
||||
|
||||
+ (NSString*)getVersion;
|
||||
|
||||
+ (int64_t)getEndTime;
|
||||
|
||||
+ (NSArray*)getSDKList;
|
||||
|
||||
+ (NSString*)getSDKNameByID:(int)sdk_id;
|
||||
|
||||
+ (void)setEnableLog:(int)enable;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __YT_AUTH_ERRORCODE_H__
|
||||
#define __YT_AUTH_ERRORCODE_H__
|
||||
|
||||
#define YT_AUTH_ERROR_FETCH_FAIL (1002)
|
||||
#define YT_AUTH_ERROR_DECODE_FAIL (3004)
|
||||
#define YT_AUTH_ERROR_EMPTY_STRING (3005)
|
||||
#define YT_AUTH_ERROR_UNMATCH_DEVICE_INFO (3013)
|
||||
#define YT_AUTH_ERROR_UNMATCH_IDENTIFIER (3015)
|
||||
#define YT_AUTH_ERROR_EMPTY_IDENTIFIER (3016)
|
||||
#define YT_AUTH_ERROR_TIME_EXPIRED (3018)
|
||||
#define YT_AUTH_ERROR_UNMATCH_SECRET_KEY (3024)
|
||||
#define YT_AUTH_ERROR_INVALID_DEVICE_INFO (4003)
|
||||
#define YT_AUTH_ERROR_FUNC_NOT_IMPLEMENT (5001)
|
||||
|
||||
#endif // __YT_AUTH_ERRORCODE_H__
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifndef _YT_DEFINES_H_
|
||||
#define _YT_DEFINES_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu for cross platform defines export c api.
|
||||
// windows @see: http://geoffair.net/ms/declspec.htm
|
||||
// ----------------------------------------------------------------------------
|
||||
#if (defined(WIN32) || defined(WIN64))
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __declspec(dllexport)
|
||||
#else
|
||||
#define YT_PUBLIC_ __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __attribute__((visibility("default")))
|
||||
#else
|
||||
#define YT_PUBLIC_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define YT_PUBLIC extern "C" YT_PUBLIC_
|
||||
#else
|
||||
#define YT_PUBLIC YT_PUBLIC_
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu error code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_SUCCESS 0
|
||||
#define YT_ERROR -1
|
||||
|
||||
// init error code: [-10, -99]
|
||||
#define YT_ERROR_OPEN_FILE -10
|
||||
#define YT_ERROR_READ_FILE -11
|
||||
#define YT_ERROR_FILE_EMPTY -12
|
||||
|
||||
#define YT_ERROR_RPN_NET_INIT -20
|
||||
#define YT_ERROR_RPN_NET_NOT_INIT -21
|
||||
#define YT_ERROR_RPN_INST_INIT -22
|
||||
#define YT_ERROR_RPN_INST_NOT_INIT -23
|
||||
#define YT_ERROR_RPN_FORWARD -24
|
||||
|
||||
#define YT_ERROR_INVALID_INSTANCE -99
|
||||
|
||||
// arguments error code: [-100, -999]
|
||||
#define YT_ERROR_MUST_NOT_NULL -100
|
||||
|
||||
#define YT_ERROR_IMAGE_TYPE -110
|
||||
|
||||
#define YT_ERROR_FACE_POINTS -120
|
||||
#define YT_ERROR_FACE_FIVE_POINTS -121
|
||||
#define YT_ERROR_FACE_NINETY_POINTS -122
|
||||
#define YT_ERROR_FACE_RECT -123
|
||||
|
||||
#define YT_ERROR_INVALID_MODEL_VERSION -130
|
||||
#define YT_ERROR_MODEL_THRESHOLDS_SIZE -131
|
||||
|
||||
// auth error code
|
||||
#define YT_ERROR_AUTH_FAILED -1024
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu common code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_FACE_FEATURE_SIZE_512 512
|
||||
#define YT_FACE_FEATURE_SIZE_1024 1024
|
||||
|
||||
#define YT_FACE_FIVE_POINTS_SIZE 5
|
||||
#define YT_FACE_NINETY_POINTS_SIZE 90
|
||||
|
||||
#endif // _YT_DEFINES_H_
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>YTCommonLiveness</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.youtu</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>v2.3.5-liveness.21</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v2.3.5-liveness.21</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,217 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_NARY_MAT_ITERATOR_HPP_
|
||||
#define FBC_CV_CORE_NARY_MAT_ITERATOR_HPP_
|
||||
|
||||
/* reference: include/opencv2/core/map.hpp
|
||||
modules/core/src/matrix.cpp
|
||||
*/
|
||||
|
||||
#include "mat.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
// n-ary multi-dimensional array iterator
|
||||
// Use the class to implement unary, binary, and, generally, n-ary element-wise operations on multi - dimensional arrays.
|
||||
template<typename _Tp, int chs> class NAryMatIterator {
|
||||
public:
|
||||
// the default constructor
|
||||
NAryMatIterator();
|
||||
// the full constructor taking arbitrary number of n-dim matrices
|
||||
NAryMatIterator(const Mat_<_Tp, chs>** arrays, uchar** ptrs, int narrays = -1);
|
||||
// the full constructor taking arbitrary number of n-dim matrices
|
||||
NAryMatIterator(const Mat_<_Tp, chs>** arrays, Mat_<_Tp, chs>* planes, int narrays = -1);
|
||||
// the separate iterator initialization method
|
||||
void init(const Mat_<_Tp, chs>** arrays, Mat_<_Tp, chs>* planes, uchar** ptrs, int narrays = -1);
|
||||
|
||||
// proceeds to the next plane of every iterated matrix
|
||||
NAryMatIterator& operator ++();
|
||||
// proceeds to the next plane of every iterated matrix (postfix increment operator)
|
||||
NAryMatIterator operator ++(int);
|
||||
|
||||
// the iterated arrays
|
||||
const Mat_<_Tp, chs>** arrays;
|
||||
// the current planes
|
||||
Mat_<_Tp, chs>* planes;
|
||||
// data pointers
|
||||
uchar** ptrs;
|
||||
// the number of arrays
|
||||
int narrays;
|
||||
// the number of hyper-planes that the iterator steps through
|
||||
size_t nplanes;
|
||||
// the size of each segment (in elements)
|
||||
size_t size;
|
||||
protected:
|
||||
int iterdepth;
|
||||
size_t idx;
|
||||
};
|
||||
|
||||
template<typename _Tp, int chs> inline
|
||||
NAryMatIterator<_Tp, chs>::NAryMatIterator()
|
||||
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
NAryMatIterator<_Tp, chs>::NAryMatIterator(const Mat_<_Tp, chs>** _arrays, Mat_<_Tp, chs>* _planes, int _narrays)
|
||||
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
|
||||
{
|
||||
init(_arrays, _planes, 0, _narrays);
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
NAryMatIterator<_Tp, chs>::NAryMatIterator(const Mat_<_Tp, chs>** _arrays, uchar** _ptrs, int _narrays)
|
||||
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
|
||||
{
|
||||
init(_arrays, 0, _ptrs, _narrays);
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void NAryMatIterator<_Tp, chs>::init(const Mat_<_Tp, chs>** _arrays, Mat_<_Tp, chs>* _planes, uchar** _ptrs, int _narrays)
|
||||
{
|
||||
fprintf(stderr, "NAryMatIterator no impl\n");
|
||||
FBC_Error("null"); // TODO
|
||||
/*FBC_Assert(_arrays && (_ptrs || _planes));
|
||||
int i, j, d1 = 0, i0 = -1, d = -1;
|
||||
|
||||
arrays = _arrays;
|
||||
ptrs = _ptrs;
|
||||
planes = _planes;
|
||||
narrays = _narrays;
|
||||
nplanes = 0;
|
||||
size = 0;
|
||||
|
||||
if (narrays < 0) {
|
||||
for (i = 0; _arrays[i] != 0; i++)
|
||||
;
|
||||
narrays = i;
|
||||
FBC_Assert(narrays <= 1000);
|
||||
}
|
||||
|
||||
iterdepth = 0;
|
||||
|
||||
for (i = 0; i < narrays; i++) {
|
||||
FBC_Assert(arrays[i] != 0);
|
||||
const Mat_<_Tp, chs>& A = *arrays[i];
|
||||
if (ptrs)
|
||||
ptrs[i] = A.data;
|
||||
|
||||
if (!A.data)
|
||||
continue;
|
||||
|
||||
if (i0 < 0) {
|
||||
i0 = i;
|
||||
d = 2; // A.dims;
|
||||
|
||||
// find the first dimensionality which is different from 1;
|
||||
// in any of the arrays the first "d1" step do not affect the continuity
|
||||
for (d1 = 0; d1 < d; d1++)
|
||||
if (A.size[d1] > 1)
|
||||
break;
|
||||
} else {
|
||||
FBC_Assert(A.size == arrays[i0]->size);
|
||||
}
|
||||
|
||||
if (!A.isContinuous()) {
|
||||
FBC_Assert(A.step[d - 1] == A.elemSize());
|
||||
for (j = d - 1; j > d1; j--)
|
||||
if (A.step[j] * A.size[j] < A.step[j - 1])
|
||||
break;
|
||||
iterdepth = std::max(iterdepth, j);
|
||||
}
|
||||
}
|
||||
|
||||
if (i0 >= 0) {
|
||||
size = arrays[i0]->size[d - 1];
|
||||
for (j = d - 1; j > iterdepth; j--) {
|
||||
int64 total1 = (int64)size*arrays[i0]->size[j - 1];
|
||||
if (total1 != (int)total1)
|
||||
break;
|
||||
size = (int)total1;
|
||||
}
|
||||
|
||||
iterdepth = j;
|
||||
if (iterdepth == d1)
|
||||
iterdepth = 0;
|
||||
|
||||
nplanes = 1;
|
||||
for (j = iterdepth - 1; j >= 0; j--)
|
||||
nplanes *= arrays[i0]->size[j];
|
||||
} else {
|
||||
iterdepth = 0;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
|
||||
if (!planes)
|
||||
return;
|
||||
|
||||
for (i = 0; i < narrays; i++) {
|
||||
FBC_Assert(arrays[i] != 0);
|
||||
const Mat_<_Tp, chs>& A = *arrays[i];
|
||||
|
||||
if (!A.data) {
|
||||
planes[i] = Mat_<_Tp, chs>();
|
||||
continue;
|
||||
}
|
||||
|
||||
planes[i] = Mat_<_Tp, chs>(1, (int)size, A.data);
|
||||
}*/
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
NAryMatIterator<_Tp, chs>& NAryMatIterator<_Tp, chs>::operator ++()
|
||||
{
|
||||
fprintf(stderr, "NAryMatIterator no impl\n");
|
||||
/*if (idx >= nplanes - 1)
|
||||
return *this;
|
||||
++idx;
|
||||
|
||||
if (iterdepth == 1) {
|
||||
if (ptrs) {
|
||||
for (int i = 0; i < narrays; i++) {
|
||||
if (!ptrs[i])
|
||||
continue;
|
||||
ptrs[i] = arrays[i]->data + arrays[i]->step[0] * idx;
|
||||
}
|
||||
}
|
||||
if (planes) {
|
||||
for (int i = 0; i < narrays; i++) {
|
||||
if (!planes[i].data)
|
||||
continue;
|
||||
planes[i].data = arrays[i]->data + arrays[i]->step[0] * idx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < narrays; i++) {
|
||||
const Mat_<_Tp, chs>& A = *arrays[i];
|
||||
if (!A.data)
|
||||
continue;
|
||||
int _idx = (int)idx;
|
||||
uchar* data = A.data;
|
||||
for (int j = iterdepth - 1; j >= 0 && _idx > 0; j--) {
|
||||
int szi = A.size[j], t = _idx / szi;
|
||||
data += (_idx - t * szi)*A.step[j];
|
||||
_idx = t;
|
||||
}
|
||||
if (ptrs)
|
||||
ptrs[i] = data;
|
||||
if (planes)
|
||||
planes[i].data = data;
|
||||
}
|
||||
}*/
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
NAryMatIterator<_Tp, chs> NAryMatIterator<_Tp, chs>::operator ++(int)
|
||||
{
|
||||
NAryMatIterator<_Tp, chs> it = *this;
|
||||
++*this;
|
||||
return it;
|
||||
}
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_NARY_MAT_ITERATOR_HPP_
|
||||
@@ -0,0 +1,285 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_BASE_HPP_
|
||||
#define FBC_CV_CORE_BASE_HPP_
|
||||
|
||||
// reference: include/opencv2/core/base.hpp
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error base.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
#include "interface.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
#define FBC_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
|
||||
#define FBC_Assert(expr) assert(expr)
|
||||
#define FBC_Error(msg) \
|
||||
fprintf(stderr, "Error: "#msg", file: %s, func: %s, line: %d \n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
assert(0);
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normL2Sqr(const _Tp* a, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
int i = 0;
|
||||
|
||||
for (; i <= n - 4; i += 4) {
|
||||
_AccTp v0 = a[i], v1 = a[i + 1], v2 = a[i + 2], v3 = a[i + 3];
|
||||
s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
|
||||
}
|
||||
|
||||
for (; i < n; i++) {
|
||||
_AccTp v = a[i];
|
||||
s += v*v;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normL1(const _Tp* a, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
int i = 0;
|
||||
|
||||
for (; i <= n - 4; i += 4) {
|
||||
s += (_AccTp)cv_abs(a[i]) + (_AccTp)cv_abs(a[i + 1]) +
|
||||
(_AccTp)cv_abs(a[i + 2]) + (_AccTp)cv_abs(a[i + 3]);
|
||||
}
|
||||
|
||||
for (; i < n; i++)
|
||||
s += cv_abs(a[i]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normInf(const _Tp* a, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
s = std::max(s, (_AccTp)cv_abs(a[i]));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
int i = 0;
|
||||
|
||||
for (; i <= n - 4; i += 4) {
|
||||
_AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i + 1] - b[i + 1]), v2 = _AccTp(a[i + 2] - b[i + 2]), v3 = _AccTp(a[i + 3] - b[i + 3]);
|
||||
s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
|
||||
}
|
||||
|
||||
for (; i < n; i++) {
|
||||
_AccTp v = _AccTp(a[i] - b[i]);
|
||||
s += v*v;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline float normL2Sqr(const float* a, const float* b, int n)
|
||||
{
|
||||
float s = 0.f;
|
||||
for (int i = 0; i < n; i++) {
|
||||
float v = a[i] - b[i];
|
||||
s += v*v;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normL1(const _Tp* a, const _Tp* b, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
int i = 0;
|
||||
|
||||
for (; i <= n - 4; i += 4) {
|
||||
_AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i + 1] - b[i + 1]), v2 = _AccTp(a[i + 2] - b[i + 2]), v3 = _AccTp(a[i + 3] - b[i + 3]);
|
||||
s += std::abs(v0) + std::abs(v1) + std::abs(v2) + std::abs(v3);
|
||||
}
|
||||
|
||||
for (; i < n; i++) {
|
||||
_AccTp v = _AccTp(a[i] - b[i]);
|
||||
s += std::abs(v);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
inline float normL1(const float* a, const float* b, int n)
|
||||
{
|
||||
float s = 0.f;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s += std::abs(a[i] - b[i]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
inline int normL1(const uchar* a, const uchar* b, int n)
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s += std::abs(a[i] - b[i]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normInf(const _Tp* a, const _Tp* b, int n)
|
||||
{
|
||||
_AccTp s = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
_AccTp v0 = a[i] - b[i];
|
||||
s = std::max(s, std::abs(v0));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//! comparison types
|
||||
enum CmpTypes {
|
||||
CMP_EQ = 0, //!< src1 is equal to src2.
|
||||
CMP_GT = 1, //!< src1 is greater than src2.
|
||||
CMP_GE = 2, //!< src1 is greater than or equal to src2.
|
||||
CMP_LT = 3, //!< src1 is less than src2.
|
||||
CMP_LE = 4, //!< src1 is less than or equal to src2.
|
||||
CMP_NE = 5 //!< src1 is unequal to src2.
|
||||
};
|
||||
|
||||
//! matrix decomposition types
|
||||
enum DecompTypes {
|
||||
/** Gaussian elimination with the optimal pivot element chosen. */
|
||||
DECOMP_LU = 0,
|
||||
/** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix
|
||||
src1 can be singular */
|
||||
DECOMP_SVD = 1,
|
||||
/** eigenvalue decomposition; the matrix src1 must be symmetrical */
|
||||
DECOMP_EIG = 2,
|
||||
/** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively
|
||||
defined */
|
||||
DECOMP_CHOLESKY = 3,
|
||||
/** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */
|
||||
DECOMP_QR = 4,
|
||||
/** while all the previous flags are mutually exclusive, this flag can be used together with
|
||||
any of the previous; it means that the normal equations
|
||||
\f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are
|
||||
solved instead of the original system
|
||||
\f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */
|
||||
DECOMP_NORMAL = 16
|
||||
};
|
||||
|
||||
/** norm types
|
||||
- For one array:
|
||||
\f[norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
|
||||
{ \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
|
||||
{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
|
||||
|
||||
- Absolute norm for two arrays
|
||||
\f[norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
|
||||
{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
|
||||
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
|
||||
|
||||
- Relative norm for two arrays
|
||||
\f[norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE_INF}\) }
|
||||
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L1}\) }
|
||||
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L2}\) }\f]
|
||||
|
||||
As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$.
|
||||
The \f$ L_{1}, L_{2} \f$ and \f$ L_{\infty} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$
|
||||
is calculated as follows
|
||||
\f{align*}
|
||||
\| r(-1) \|_{L_1} &= |-1| + |2| = 3 \\
|
||||
\| r(-1) \|_{L_2} &= \sqrt{(-1)^{2} + (2)^{2}} = \sqrt{5} \\
|
||||
\| r(-1) \|_{L_\infty} &= \max(|-1|,|2|) = 2
|
||||
\f}
|
||||
and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is
|
||||
\f{align*}
|
||||
\| r(0.5) \|_{L_1} &= |0.5| + |0.5| = 1 \\
|
||||
\| r(0.5) \|_{L_2} &= \sqrt{(0.5)^{2} + (0.5)^{2}} = \sqrt{0.5} \\
|
||||
\| r(0.5) \|_{L_\infty} &= \max(|0.5|,|0.5|) = 0.5.
|
||||
\f}
|
||||
The following graphic shows all values for the three norm functions \f$\| r(x) \|_{L_1}, \| r(x) \|_{L_2}\f$ and \f$\| r(x) \|_{L_\infty}\f$.
|
||||
It is notable that the \f$ L_{1} \f$ norm forms the upper and the \f$ L_{\infty} \f$ norm forms the lower border for the example function \f$ r(x) \f$.
|
||||

|
||||
*/
|
||||
enum NormTypes {
|
||||
NORM_INF = 1,
|
||||
NORM_L1 = 2,
|
||||
NORM_L2 = 4,
|
||||
NORM_L2SQR = 5,
|
||||
NORM_HAMMING = 6,
|
||||
NORM_HAMMING2 = 7,
|
||||
NORM_TYPE_MASK = 7,
|
||||
NORM_RELATIVE = 8, // flag
|
||||
NORM_MINMAX = 32 // flag
|
||||
};
|
||||
|
||||
//! Various border types, image boundaries are denoted with `|`
|
||||
enum BorderTypes {
|
||||
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
|
||||
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
|
||||
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
|
||||
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
|
||||
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
|
||||
BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`
|
||||
|
||||
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
|
||||
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
|
||||
BORDER_ISOLATED = 16 //!< do not look outside of ROI
|
||||
};
|
||||
|
||||
enum DftFlags {
|
||||
/** performs an inverse 1D or 2D transform instead of the default forward transform. */
|
||||
DFT_INVERSE = 1,
|
||||
/** scales the result: divide it by the number of array elements. Normally, it is
|
||||
combined with DFT_INVERSE. */
|
||||
DFT_SCALE = 2,
|
||||
/** performs a forward or inverse transform of every individual row of the input
|
||||
matrix; this flag enables you to transform multiple vectors simultaneously and can be used to
|
||||
decrease the overhead (which is sometimes several times larger than the processing itself) to
|
||||
perform 3D and higher-dimensional transformations and so forth.*/
|
||||
DFT_ROWS = 4,
|
||||
/** performs a forward transformation of 1D or 2D real array; the result,
|
||||
though being a complex array, has complex-conjugate symmetry (*CCS*, see the function
|
||||
description below for details), and such an array can be packed into a real array of the same
|
||||
size as input, which is the fastest option and which is what the function does by default;
|
||||
however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) -
|
||||
pass the flag to enable the function to produce a full-size complex output array. */
|
||||
DFT_COMPLEX_OUTPUT = 16,
|
||||
/** performs an inverse transformation of a 1D or 2D complex array; the
|
||||
result is normally a complex array of the same size, however, if the input array has
|
||||
conjugate-complex symmetry (for example, it is a result of forward transformation with
|
||||
DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not
|
||||
check whether the input is symmetrical or not, you can pass the flag and then the function
|
||||
will assume the symmetry and produce the real output array (note that when the input is packed
|
||||
into a real array and inverse transformation is executed, the function treats the input as a
|
||||
packed complex-conjugate symmetrical array, and the output will also be a real array). */
|
||||
DFT_REAL_OUTPUT = 32,
|
||||
/** performs an inverse 1D or 2D transform instead of the default forward transform. */
|
||||
DCT_INVERSE = DFT_INVERSE,
|
||||
/** performs a forward or inverse transform of every individual row of the input
|
||||
matrix. This flag enables you to transform multiple vectors simultaneously and can be used to
|
||||
decrease the overhead (which is sometimes several times larger than the processing itself) to
|
||||
perform 3D and higher-dimensional transforms and so forth.*/
|
||||
DCT_ROWS = DFT_ROWS
|
||||
};
|
||||
|
||||
} //yt_tinycv
|
||||
|
||||
#endif //FBC_CV_CORE_BASE_HPP_
|
||||
@@ -0,0 +1,313 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_CORE_HPP_
|
||||
#define FBC_CV_CORE_CORE_HPP_
|
||||
|
||||
/* reference: include/opencv2/core/core_c.h
|
||||
include/opencv2/core.hpp
|
||||
modules/core/src/stat.cpp
|
||||
modules/core/include/opencv2/core/private.hpp
|
||||
modules/core/src/matrix.cpp
|
||||
modules/core/src/arithm.cpp
|
||||
*/
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error core.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include "fbcdef.hpp"
|
||||
#include "mat.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
// NormFlags
|
||||
#define FBC_C 1
|
||||
#define FBC_L1 2
|
||||
#define FBC_L2 4
|
||||
#define FBC_NORM_MASK 7
|
||||
#define FBC_RELATIVE 8
|
||||
#define FBC_DIFF 16
|
||||
#define FBC_MINMAX 32
|
||||
|
||||
#define FBC_DIFF_C (FBC_DIFF | FBC_C)
|
||||
#define FBC_DIFF_L1 (FBC_DIFF | FBC_L1)
|
||||
#define FBC_DIFF_L2 (FBC_DIFF | FBC_L2)
|
||||
#define FBC_RELATIVE_C (FBC_RELATIVE | FBC_C)
|
||||
#define FBC_RELATIVE_L1 (FBC_RELATIVE | FBC_L1)
|
||||
#define FBC_RELATIVE_L2 (FBC_RELATIVE | FBC_L2)
|
||||
|
||||
// Discrete Linear Transforms and Related Functions
|
||||
#define FBC_DXT_SCALE 2 // divide result by size of array
|
||||
|
||||
// Fast cubic root calculation
|
||||
FBC_EXPORTS float fbcCbrt(float value);
|
||||
|
||||
template<typename dump>
|
||||
static inline void* fbcAlignPtr(const void* ptr, int align = 32)
|
||||
{
|
||||
FBC_Assert((align & (align - 1)) == 0);
|
||||
return (void*)(((size_t)ptr + align - 1) & ~(size_t)(align - 1));
|
||||
}
|
||||
|
||||
template<typename dump>
|
||||
static inline int fbcAlign(int size, int align)
|
||||
{
|
||||
FBC_Assert((align & (align - 1)) == 0 && size < INT_MAX);
|
||||
return (size + align - 1) & -align;
|
||||
}
|
||||
|
||||
// Computes the source location of an extrapolated pixel
|
||||
/* Various border types, image boundaries are denoted with '|'
|
||||
|
||||
* BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
|
||||
* BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
|
||||
* BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
|
||||
* BORDER_WRAP: cdefgh|abcdefgh|abcdefg
|
||||
* BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
|
||||
*/
|
||||
template<typename _Tp>
|
||||
int borderInterpolate(int p, int len, int borderType)
|
||||
{
|
||||
if ((unsigned)p < (unsigned)len) {
|
||||
;
|
||||
} else if (borderType == BORDER_REPLICATE) {
|
||||
p = p < 0 ? 0 : len - 1;
|
||||
} else if (borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101) {
|
||||
int delta = borderType == BORDER_REFLECT_101;
|
||||
if (len == 1)
|
||||
return 0;
|
||||
do {
|
||||
if (p < 0)
|
||||
p = -p - 1 + delta;
|
||||
else
|
||||
p = len - 1 - (p - len) - delta;
|
||||
} while ((unsigned)p >= (unsigned)len);
|
||||
} else if (borderType == BORDER_WRAP) {
|
||||
FBC_Assert(len > 0);
|
||||
if (p < 0)
|
||||
p -= ((p - len + 1) / len)*len;
|
||||
if (p >= len)
|
||||
p %= len;
|
||||
} else if (borderType == BORDER_CONSTANT) {
|
||||
p = -1;
|
||||
} else {
|
||||
FBC_Error("Unknown/unsupported border type");
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Transposes a matrix
|
||||
// \f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
|
||||
template<typename _Tp, int chs>
|
||||
int transpose(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst)
|
||||
{
|
||||
if (src.empty()) {
|
||||
dst.release();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// handle the case of single-column/single-row matrices, stored in STL vectors
|
||||
if (src.rows != dst.cols || src.cols != dst.rows) {
|
||||
FBC_Assert(src.size() == dst.size() && (src.cols == 1 || src.rows == 1));
|
||||
src.copyTo(dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dst.data == src.data) {
|
||||
FBC_Assert(0); // TODO
|
||||
} else {
|
||||
Size sz = src.size();
|
||||
int i = 0, j, m = sz.width, n = sz.height;
|
||||
int sstep = src.step;
|
||||
int dstep = dst.step;
|
||||
|
||||
for (; i <= m - 4; i += 4) {
|
||||
_Tp* d0 = (_Tp*)(dst.data + dstep*i);
|
||||
_Tp* d1 = (_Tp*)(dst.data + dstep*(i + 1));
|
||||
_Tp* d2 = (_Tp*)(dst.data + dstep*(i + 2));
|
||||
_Tp* d3 = (_Tp*)(dst.data + dstep*(i + 3));
|
||||
|
||||
for (j = 0; j <= n - 4; j += 4) {
|
||||
const _Tp* s0 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*j);
|
||||
const _Tp* s1 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 1));
|
||||
const _Tp* s2 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 2));
|
||||
const _Tp* s3 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 3));
|
||||
|
||||
d0[j] = s0[0]; d0[j + 1] = s1[0]; d0[j + 2] = s2[0]; d0[j + 3] = s3[0];
|
||||
d1[j] = s0[1]; d1[j + 1] = s1[1]; d1[j + 2] = s2[1]; d1[j + 3] = s3[1];
|
||||
d2[j] = s0[2]; d2[j + 1] = s1[2]; d2[j + 2] = s2[2]; d2[j + 3] = s3[2];
|
||||
d3[j] = s0[3]; d3[j + 1] = s1[3]; d3[j + 2] = s2[3]; d3[j + 3] = s3[3];
|
||||
}
|
||||
|
||||
for (; j < n; j++) {
|
||||
const _Tp* s0 = (const _Tp*)(src.data + i*sizeof(_Tp) + j*sstep);
|
||||
d0[j] = s0[0]; d1[j] = s0[1]; d2[j] = s0[2]; d3[j] = s0[3];
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < m; i++) {
|
||||
_Tp* d0 = (_Tp*)(dst.data + dstep*i);
|
||||
j = 0;
|
||||
|
||||
for (; j <= n - 4; j += 4) {
|
||||
const _Tp* s0 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*j);
|
||||
const _Tp* s1 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 1));
|
||||
const _Tp* s2 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 2));
|
||||
const _Tp* s3 = (const _Tp*)(src.data + i*sizeof(_Tp) + sstep*(j + 3));
|
||||
|
||||
d0[j] = s0[0]; d0[j + 1] = s1[0]; d0[j + 2] = s2[0]; d0[j + 3] = s3[0];
|
||||
}
|
||||
|
||||
for (; j < n; j++) {
|
||||
const _Tp* s0 = (const _Tp*)(src.data + i*sizeof(_Tp) + j*sstep);
|
||||
d0[j] = s0[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Counts non-zero array elements
|
||||
// \f[\sum _{ I: \; \texttt{ src } (I) \ne0 } 1\f]
|
||||
template<typename _Tp, int chs>
|
||||
int countNonZero(const Mat_<_Tp, chs>& src)
|
||||
{
|
||||
FBC_Assert(chs == 1);
|
||||
|
||||
int len = src.rows * src.cols;
|
||||
const _Tp* p = (_Tp*)src.data;
|
||||
|
||||
int nz = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
nz += (p[i] != 0);
|
||||
}
|
||||
|
||||
return nz;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void scalarToRawData(const yt_tinycv::Scalar& s, void* _buf, int unroll_to = 0)
|
||||
{
|
||||
FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() || typeid(float).name() == typeid(_Tp).name()); // uchar || float
|
||||
|
||||
int i, cn = chs;
|
||||
FBC_Assert(chs <= 4);
|
||||
int depth = sizeof(_Tp);
|
||||
switch (depth) {
|
||||
case 1: {
|
||||
uchar* buf = (uchar*)_buf;
|
||||
for (i = 0; i < cn; i++)
|
||||
buf[i] = saturate_cast<uchar>(s.val[i]);
|
||||
for (; i < unroll_to; i++)
|
||||
buf[i] = buf[i - cn];
|
||||
}
|
||||
break;
|
||||
case 4: {
|
||||
float* buf = (float*)_buf;
|
||||
for (i = 0; i < cn; i++)
|
||||
buf[i] = saturate_cast<float>(s.val[i]);
|
||||
for (; i < unroll_to; i++)
|
||||
buf[i] = buf[i - cn];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FBC_Error("UnsupportedFormat");
|
||||
}
|
||||
}
|
||||
|
||||
// calculates the per - element bit - wise logical conjunction
|
||||
// \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
|
||||
// mask optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed
|
||||
template<typename _Tp, int chs>
|
||||
int bitwise_and(const Mat_<_Tp, chs>& src1, const Mat_<_Tp, chs>& src2, Mat_<_Tp, chs>& dst, const Mat_<uchar, 1>& mask = Mat_<uchar, 1>())
|
||||
{
|
||||
FBC_Assert(src1.rows == src2.rows && src1.cols == src2.cols);
|
||||
if (dst.empty()) {
|
||||
dst = Mat_<_Tp, chs>(src1.rows, src1.cols);
|
||||
} else {
|
||||
FBC_Assert(src1.rows == dst.rows && src1.cols == dst.cols);
|
||||
}
|
||||
|
||||
if (!mask.empty()) {
|
||||
FBC_Assert(src1.rows == mask.rows && src1.cols == mask.cols);
|
||||
}
|
||||
|
||||
int bytePerRow = src1.cols * chs * sizeof(_Tp);
|
||||
int bypePerPixel = chs * sizeof(_Tp);
|
||||
for (int y = 0; y < src1.rows; y++) {
|
||||
const uchar* pSrc1 = src1.ptr(y);
|
||||
const uchar* pSrc2 = src2.ptr(y);
|
||||
uchar* pDst = dst.ptr(y);
|
||||
const uchar* pMask = NULL;
|
||||
if (!mask.empty()) {
|
||||
pMask = mask.ptr(y);
|
||||
|
||||
for (int x = 0; x < src1.cols; x++) {
|
||||
if (pMask[x] == 1) {
|
||||
int addr = x * bypePerPixel;
|
||||
for (int t = 0; t < bypePerPixel; t++) {
|
||||
pDst[addr + t] = pSrc1[addr + t] & pSrc2[addr + t];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int x = 0; x < bytePerRow; x++) {
|
||||
pDst[x] = pSrc1[x] & pSrc2[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Inverts every bit of an array
|
||||
// \f[\texttt{dst} (I) = \neg \texttt{src} (I)\f]
|
||||
// mask optional operation mask, 8-bit single channel array, that specifies elements of the output array to be changed
|
||||
template<typename _Tp, int chs>
|
||||
int bitwise_not(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, const Mat_<uchar, 1>& mask = Mat_<uchar, 1>())
|
||||
{
|
||||
if (dst.empty()) {
|
||||
dst = Mat_<_Tp, chs>(src.rows, src.cols);
|
||||
} else {
|
||||
FBC_Assert(src.rows == dst.rows && src.cols == dst.cols);
|
||||
}
|
||||
|
||||
if (!mask.empty()) {
|
||||
FBC_Assert(src.rows == mask.rows && src.cols == mask.cols);
|
||||
}
|
||||
|
||||
int bytePerRow = src.cols * chs * sizeof(_Tp);
|
||||
int bypePerPixel = chs * sizeof(_Tp);
|
||||
for (int y = 0; y < src.rows; y++) {
|
||||
const uchar* pSrc = src.ptr(y);
|
||||
uchar* pDst = dst.ptr(y);
|
||||
const uchar* pMask = NULL;
|
||||
if (!mask.empty()) {
|
||||
pMask = mask.ptr(y);
|
||||
|
||||
for (int x = 0; x < src.cols; x++) {
|
||||
if (pMask[x] == 1) {
|
||||
int addr = x * bypePerPixel;
|
||||
for (int t = 0; t < bypePerPixel; t++) {
|
||||
pDst[addr + t] = ~pSrc[addr + t];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int x = 0; x < bytePerRow; x++) {
|
||||
pDst[x] = ~pSrc[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_CORE_HPP_
|
||||
@@ -0,0 +1,543 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
// from: https://github.com/fengbingchun/OpenCV_Test/blob/master/src/fbc_cv/include/cvtColor.hpp
|
||||
// commitID: 7c0eccf85e31c456256cc4c87d4ba752a56a18dc
|
||||
#ifndef FBC_CV_CVTCOLOR_HPP_
|
||||
#define FBC_CV_CVTCOLOR_HPP_
|
||||
|
||||
/* reference: include/opencv2/imgproc.hpp
|
||||
imgproc/src/color.cpp
|
||||
*/
|
||||
|
||||
#include <typeinfo>
|
||||
#include "mat.hpp"
|
||||
#include "saturate.hpp"
|
||||
#include "imgproc.hpp"
|
||||
#include "core.hpp"
|
||||
#ifdef __ARM_NEON__
|
||||
#include "arm_neon.h"
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace yt_tinycv {
|
||||
#define FBC_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
// neon intrinsic
|
||||
static void NeonCvtColorRGBA2BGR(unsigned char *rgba, unsigned char *bgr, int rows, int cols) {
|
||||
int len_color = rows * cols;
|
||||
int num8x16 = len_color / 16;
|
||||
int num8len = num8x16 * 16;
|
||||
uint8x16x4_t intlv_rgba;
|
||||
uint8x16x3_t intlv_bgr;
|
||||
for (int i=0; i < num8x16; i++) {
|
||||
intlv_rgba = vld4q_u8(rgba);
|
||||
intlv_bgr.val[0] = intlv_rgba.val[2];
|
||||
intlv_bgr.val[1] = intlv_rgba.val[1];
|
||||
intlv_bgr.val[2] = intlv_rgba.val[0];
|
||||
vst3q_u8(bgr, intlv_bgr);
|
||||
rgba += 64;
|
||||
bgr += 48;
|
||||
}
|
||||
for (; num8len < len_color; num8len++) {
|
||||
bgr[0] = rgba[2];
|
||||
bgr[1] = rgba[1];
|
||||
bgr[2] = rgba[0];
|
||||
rgba += 4;
|
||||
bgr += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void NeonCvtColorRGBA2RGB(unsigned char *rgba, unsigned char *bgr, int rows, int cols) {
|
||||
int len_color = rows * cols;
|
||||
int num8x16 = len_color / 16;
|
||||
int num8len = num8x16 * 16;
|
||||
uint8x16x4_t intlv_rgba;
|
||||
uint8x16x3_t intlv_bgr;
|
||||
for (int i=0; i < num8x16; i++) {
|
||||
intlv_rgba = vld4q_u8(rgba);
|
||||
intlv_bgr.val[0] = intlv_rgba.val[0];
|
||||
intlv_bgr.val[1] = intlv_rgba.val[1];
|
||||
intlv_bgr.val[2] = intlv_rgba.val[2];
|
||||
vst3q_u8(bgr, intlv_bgr);
|
||||
rgba += 64;
|
||||
bgr += 48;
|
||||
}
|
||||
for (; num8len < len_color; num8len++) {
|
||||
bgr[0] = rgba[0];
|
||||
bgr[1] = rgba[1];
|
||||
bgr[2] = rgba[2];
|
||||
rgba += 4;
|
||||
bgr += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void NeonCvtColorRGB2BGR(unsigned char *rgb, unsigned char *bgr, int rows, int cols) {
|
||||
int len_color = rows * cols;
|
||||
int num8x16 = len_color / 16;
|
||||
int num8len = num8x16 * 16;
|
||||
uint8x16x3_t intlv_rgb;
|
||||
uint8x16x3_t intlv_bgr;
|
||||
for (int i=0; i < num8x16; i++) {
|
||||
intlv_rgb = vld3q_u8(rgb);
|
||||
intlv_bgr.val[0] = intlv_rgb.val[2];
|
||||
intlv_bgr.val[1] = intlv_rgb.val[1];
|
||||
intlv_bgr.val[2] = intlv_rgb.val[0];
|
||||
vst3q_u8(bgr, intlv_bgr);
|
||||
rgb += 48;
|
||||
bgr += 48;
|
||||
}
|
||||
for (; num8len < len_color; num8len++) {
|
||||
bgr[0] = rgb[2];
|
||||
bgr[1] = rgb[1];
|
||||
bgr[2] = rgb[0];
|
||||
rgb += 3;
|
||||
bgr += 3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);
|
||||
template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2Gray(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);
|
||||
template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2YCrCb(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs_f, const int* coeffs_i);
|
||||
template<typename _Tp, int chs1, int chs2, int bIdx, int uIdx> static void cvtRGBtoYUV420p(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst);
|
||||
|
||||
#undef R2Y
|
||||
#undef G2Y
|
||||
#undef B2Y
|
||||
|
||||
enum {
|
||||
yuv_shift = 14,
|
||||
xyz_shift = 12,
|
||||
R2Y = 4899,
|
||||
G2Y = 9617,
|
||||
B2Y = 1868,
|
||||
BLOCK_SIZE = 256
|
||||
};
|
||||
|
||||
// Converts an image from one color space to another
|
||||
// support type: uchar/ushort/float
|
||||
template<typename _Tp, int chs1, int chs2>
|
||||
int cvtColor(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int code)
|
||||
{
|
||||
FBC_Assert(src.cols > 0 && src.rows > 0 && dst.cols > 0 && dst.rows > 0);
|
||||
FBC_Assert(src.cols == dst.cols);
|
||||
FBC_Assert(src.data != NULL && dst.data != NULL);
|
||||
FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() ||
|
||||
typeid(ushort).name() == typeid(_Tp).name() ||
|
||||
typeid(float).name() == typeid(_Tp).name());
|
||||
FBC_Assert((sizeof(_Tp) == 1) || sizeof(_Tp) == 2 || sizeof(_Tp) == 4); // uchar || ushort || float
|
||||
|
||||
int scn = src.channels;
|
||||
int dcn = dst.channels; // number of channels in the destination image
|
||||
Size sz = src.size();
|
||||
Size dz = dst.size();
|
||||
int bidx;
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
if (CV_RGBA2BGR == code || CV_BGRA2RGB == code) {
|
||||
// timeval tv_begin, tv_end;
|
||||
// gettimeofday(&tv_begin, NULL);
|
||||
NeonCvtColorRGBA2BGR(src.data, dst.data, dst.rows, dst.cols);
|
||||
// gettimeofday(&tv_end, NULL);
|
||||
// float elapsed = ((tv_end.tv_sec - tv_begin.tv_sec) * 1000000.0f + tv_end.tv_usec - tv_begin.tv_usec) / 1000.0f;
|
||||
// printf("lgy neon NeonCvtColorRGBA2BGR code : %d, %f ms\n", code, elapsed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CV_RGBA2RGB == code || CV_BGRA2BGR == code) {
|
||||
NeonCvtColorRGBA2RGB(src.data, dst.data, dst.rows, dst.cols);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CV_BGR2RGB == code || CV_RGB2BGR == code) {
|
||||
NeonCvtColorRGB2BGR(src.data, dst.data, dst.rows, dst.cols);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (code) {
|
||||
case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:
|
||||
case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: {
|
||||
FBC_Assert(scn == 3 || scn == 4);
|
||||
dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3;
|
||||
FBC_Assert(dst.channels == dcn);
|
||||
bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2;
|
||||
|
||||
CvtColorLoop_RGB2RGB(src, dst, bidx); // uchar/ushort/float
|
||||
break;
|
||||
}
|
||||
case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: {
|
||||
FBC_Assert(scn == 3 || scn == 4);
|
||||
FBC_Assert(dst.channels == 1);
|
||||
bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
|
||||
|
||||
CvtColorLoop_RGB2Gray(src, dst, bidx);
|
||||
break;
|
||||
}
|
||||
case CV_BGR2YUV: case CV_RGB2YUV:{
|
||||
FBC_Assert(scn == 3 || scn == 4);
|
||||
bidx = code == CV_BGR2YUV ? 0 : 2;
|
||||
static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
|
||||
static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
|
||||
CvtColorLoop_RGB2YCrCb(src, dst, bidx, yuv_f, yuv_i);
|
||||
break;
|
||||
}
|
||||
case CV_RGB2YUV_YV12: case CV_BGR2YUV_YV12: case CV_RGBA2YUV_YV12: case CV_BGRA2YUV_YV12:
|
||||
case CV_RGB2YUV_IYUV: case CV_BGR2YUV_IYUV: case CV_RGBA2YUV_IYUV: case CV_BGRA2YUV_IYUV: {
|
||||
const int bIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_BGR2YUV_YV12 || code == CV_BGRA2YUV_YV12) ? 0 : 2;
|
||||
const int uIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_RGB2YUV_IYUV || code == CV_RGBA2YUV_IYUV) ? 1 : 2;
|
||||
|
||||
FBC_Assert(scn == 3 || scn == 4);
|
||||
FBC_Assert(sizeof(_Tp) == 1);
|
||||
FBC_Assert(dcn == 1);
|
||||
FBC_Assert(sz.width % 2 == 0 && sz.height % 2 == 0);
|
||||
|
||||
//Size dstSz(sz.width, sz.height / 2 * 3);
|
||||
FBC_Assert((dz.width == sz.width) && (sz.height / 2 * 3 == dz.height));
|
||||
|
||||
switch (bIdx + uIdx * 10) {
|
||||
case 10: cvtRGBtoYUV420p<_Tp, chs1, chs2, 0, 1>(src, dst); break;
|
||||
case 12: cvtRGBtoYUV420p<_Tp, chs1, chs2, 2, 1>(src, dst); break;
|
||||
case 20: cvtRGBtoYUV420p<_Tp, chs1, chs2, 0, 2>(src, dst); break;
|
||||
case 22: cvtRGBtoYUV420p<_Tp, chs1, chs2, 2, 2>(src, dst); break;
|
||||
default: FBC_Error("Unknown/unsupported color conversion code"); break;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FBC_Error("Unknown/unsupported color conversion code");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// computes cubic spline coefficients for a function: (xi=i, yi=f[i]), i=0..n
|
||||
template<typename _Tp> static void splineBuild(const _Tp* f, int n, _Tp* tab)
|
||||
{
|
||||
_Tp cn = 0;
|
||||
int i;
|
||||
tab[0] = tab[1] = (_Tp)0;
|
||||
|
||||
for (i = 1; i < n - 1; i++) {
|
||||
_Tp t = 3 * (f[i + 1] - 2 * f[i] + f[i - 1]);
|
||||
_Tp l = 1 / (4 - tab[(i - 1) * 4]);
|
||||
tab[i * 4] = l; tab[i * 4 + 1] = (t - tab[(i - 1) * 4 + 1])*l;
|
||||
}
|
||||
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
_Tp c = tab[i * 4 + 1] - tab[i * 4] * cn;
|
||||
_Tp b = f[i + 1] - f[i] - (cn + c * 2)*(_Tp)0.3333333333333333;
|
||||
_Tp d = (cn - c)*(_Tp)0.3333333333333333;
|
||||
tab[i * 4] = f[i]; tab[i * 4 + 1] = b;
|
||||
tab[i * 4 + 2] = c; tab[i * 4 + 3] = d;
|
||||
cn = c;
|
||||
}
|
||||
}
|
||||
|
||||
// interpolates value of a function at x, 0 <= x <= n using a cubic spline.
|
||||
template<typename _Tp> static inline _Tp splineInterpolate(_Tp x, const _Tp* tab, int n)
|
||||
{
|
||||
// don't touch this function without urgent need - some versions of gcc fail to inline it correctly
|
||||
int ix = std::min(std::max(int(x), 0), n - 1);
|
||||
x -= ix;
|
||||
tab += ix * 4;
|
||||
return ((tab[3] * x + tab[2])*x + tab[1])*x + tab[0];
|
||||
}
|
||||
|
||||
template<typename _Tp> struct ColorChannel
|
||||
{
|
||||
typedef float worktype_f;
|
||||
static _Tp max() { return std::numeric_limits<_Tp>::max(); }
|
||||
static _Tp half() { return (_Tp)(max() / 2 + 1); }
|
||||
};
|
||||
|
||||
template<> struct ColorChannel<float>
|
||||
{
|
||||
typedef float worktype_f;
|
||||
static float max() { return 1.f; }
|
||||
static float half() { return 0.5f; }
|
||||
};
|
||||
|
||||
template<typename _Tp> struct RGB2Gray
|
||||
{
|
||||
typedef _Tp channel_type;
|
||||
|
||||
RGB2Gray(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn)
|
||||
{
|
||||
static const float coeffs0[] = { 0.299f, 0.587f, 0.114f };
|
||||
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 3 * sizeof(coeffs[0]));
|
||||
if (blueIdx == 0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
int scn = srccn;
|
||||
float cb = coeffs[0], cg = coeffs[1], cr = coeffs[2];
|
||||
for (int i = 0; i < n; i++, src += scn)
|
||||
dst[i] = saturate_cast<_Tp>(src[0] * cb + src[1] * cg + src[2] * cr);
|
||||
}
|
||||
int srccn;
|
||||
float coeffs[3];
|
||||
};
|
||||
|
||||
template<> struct RGB2Gray<uchar>
|
||||
{
|
||||
typedef uchar channel_type;
|
||||
|
||||
RGB2Gray(int _srccn, int blueIdx, const int* coeffs) : srccn(_srccn)
|
||||
{
|
||||
const int coeffs0[] = { R2Y, G2Y, B2Y };
|
||||
if (!coeffs) coeffs = coeffs0;
|
||||
|
||||
int b = 0, g = 0, r = (1 << (yuv_shift - 1));
|
||||
int db = coeffs[blueIdx ^ 2], dg = coeffs[1], dr = coeffs[blueIdx];
|
||||
|
||||
for (int i = 0; i < 256; i++, b += db, g += dg, r += dr) {
|
||||
tab[i] = b;
|
||||
tab[i + 256] = g;
|
||||
tab[i + 512] = r;
|
||||
}
|
||||
}
|
||||
void operator()(const uchar* src, uchar* dst, int n) const
|
||||
{
|
||||
int scn = srccn;
|
||||
const int* _tab = tab;
|
||||
for (int i = 0; i < n; i++, src += scn)
|
||||
dst[i] = (uchar)((_tab[src[0]] + _tab[src[1] + 256] + _tab[src[2] + 512]) >> yuv_shift);
|
||||
}
|
||||
int srccn;
|
||||
int tab[256 * 3];
|
||||
};
|
||||
|
||||
template<> struct RGB2Gray<ushort>
|
||||
{
|
||||
typedef ushort channel_type;
|
||||
|
||||
RGB2Gray(int _srccn, int blueIdx, const int* _coeffs) : srccn(_srccn)
|
||||
{
|
||||
static const int coeffs0[] = { R2Y, G2Y, B2Y };
|
||||
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 3 * sizeof(coeffs[0]));
|
||||
if (blueIdx == 0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
|
||||
void operator()(const ushort* src, ushort* dst, int n) const
|
||||
{
|
||||
int scn = srccn, cb = coeffs[0], cg = coeffs[1], cr = coeffs[2];
|
||||
for (int i = 0; i < n; i++, src += scn)
|
||||
dst[i] = (ushort)FBC_DESCALE((unsigned)(src[0] * cb + src[1] * cg + src[2] * cr), yuv_shift);
|
||||
}
|
||||
int srccn;
|
||||
int coeffs[3];
|
||||
};
|
||||
|
||||
template<typename _Tp> struct RGB2YCrCb_f{
|
||||
typedef _Tp channel_type;
|
||||
RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
|
||||
{
|
||||
static const float coeffs0[] = { 0.299f, 0.587f, 0.114f, 0.713f, 0.564f };
|
||||
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5 * sizeof(coeffs[0]));
|
||||
if (blueIdx == 0) std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
int scn = srccn, bidx = blueIdx;
|
||||
const _Tp delta = ColorChannel<_Tp>::half();
|
||||
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
|
||||
n *= 3;
|
||||
for (int i = 0; i < n; i += 3, src += scn) {
|
||||
_Tp Y = saturate_cast<_Tp>(src[0] * C0 + src[1] * C1 + src[2] * C2);
|
||||
_Tp Cr = saturate_cast<_Tp>((src[bidx ^ 2] - Y)*C3 + delta);
|
||||
_Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta);
|
||||
dst[i] = Y; dst[i + 1] = Cr; dst[i + 2] = Cb;
|
||||
}
|
||||
}
|
||||
int srccn, blueIdx;
|
||||
float coeffs[5];
|
||||
};
|
||||
template<typename _Tp> struct RGB2YCrCb_i{
|
||||
typedef _Tp channel_type;
|
||||
RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
|
||||
{
|
||||
static const int coeffs0[] = { R2Y, G2Y, B2Y, 11682, 9241 };
|
||||
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5 * sizeof(coeffs[0]));
|
||||
if (blueIdx == 0) std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
int scn = srccn, bidx = blueIdx;
|
||||
int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
|
||||
int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
|
||||
n *= 3;
|
||||
for (int i = 0; i < n; i += 3, src += scn) {
|
||||
int Y = FBC_DESCALE(src[0] * C0 + src[1] * C1 + src[2] * C2, yuv_shift);
|
||||
int Cr = FBC_DESCALE((src[bidx ^ 2] - Y)*C3 + delta, yuv_shift);
|
||||
int Cb = FBC_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift);
|
||||
dst[i] = saturate_cast<_Tp>(Y);
|
||||
dst[i + 1] = saturate_cast<_Tp>(Cr);
|
||||
dst[i + 2] = saturate_cast<_Tp>(Cb);
|
||||
}
|
||||
}
|
||||
int srccn, blueIdx;
|
||||
int coeffs[5];
|
||||
};
|
||||
|
||||
const int ITUR_BT_601_CY = 1220542;
|
||||
const int ITUR_BT_601_CUB = 2116026;
|
||||
const int ITUR_BT_601_CUG = -409993;
|
||||
const int ITUR_BT_601_CVG = -852492;
|
||||
const int ITUR_BT_601_CVR = 1673527;
|
||||
const int ITUR_BT_601_SHIFT = 20;
|
||||
const int ITUR_BT_601_CRY = 269484;
|
||||
const int ITUR_BT_601_CGY = 528482;
|
||||
const int ITUR_BT_601_CBY = 102760;
|
||||
const int ITUR_BT_601_CRU = -155188;
|
||||
const int ITUR_BT_601_CGU = -305135;
|
||||
const int ITUR_BT_601_CBU = 460324;
|
||||
const int ITUR_BT_601_CGV = -385875;
|
||||
const int ITUR_BT_601_CBV = -74448;
|
||||
|
||||
template<typename _Tp, int chs1, int chs2, int bIdx>
|
||||
struct RGB888toYUV420pInvoker{
|
||||
RGB888toYUV420pInvoker(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>* dst, const int uIdx)
|
||||
: src_(src), dst_(dst), uIdx_(uIdx) { }
|
||||
void operator()(const Range& rowRange) const
|
||||
{
|
||||
const int w = src_.cols;
|
||||
const int h = src_.rows;
|
||||
const int cn = src_.channels;
|
||||
for (int i = rowRange.start; i < rowRange.end; i++) {
|
||||
const uchar* row0 = src_.ptr(2 * i);
|
||||
const uchar* row1 = src_.ptr(2 * i + 1);
|
||||
uchar* y = (uchar*)dst_->ptr(2 * i);
|
||||
uchar* u = (uchar*)dst_->ptr(h + i / 2) + (i % 2) * (w / 2);
|
||||
uchar* v = (uchar*)dst_->ptr(h + (i + h / 2) / 2) + ((i + h / 2) % 2) * (w / 2);
|
||||
if (uIdx_ == 2) std::swap(u, v);
|
||||
for (int j = 0, k = 0; j < w * cn; j += 2 * cn, k++) {
|
||||
int r00 = row0[2 - bIdx + j]; int g00 = row0[1 + j]; int b00 = row0[bIdx + j];
|
||||
int r01 = row0[2 - bIdx + cn + j]; int g01 = row0[1 + cn + j]; int b01 = row0[bIdx + cn + j];
|
||||
int r10 = row1[2 - bIdx + j]; int g10 = row1[1 + j]; int b10 = row1[bIdx + j];
|
||||
int r11 = row1[2 - bIdx + cn + j]; int g11 = row1[1 + cn + j]; int b11 = row1[bIdx + cn + j];
|
||||
const int shifted16 = (16 << ITUR_BT_601_SHIFT);
|
||||
const int halfShift = (1 << (ITUR_BT_601_SHIFT - 1));
|
||||
int y00 = ITUR_BT_601_CRY * r00 + ITUR_BT_601_CGY * g00 + ITUR_BT_601_CBY * b00 + halfShift + shifted16;
|
||||
int y01 = ITUR_BT_601_CRY * r01 + ITUR_BT_601_CGY * g01 + ITUR_BT_601_CBY * b01 + halfShift + shifted16;
|
||||
int y10 = ITUR_BT_601_CRY * r10 + ITUR_BT_601_CGY * g10 + ITUR_BT_601_CBY * b10 + halfShift + shifted16;
|
||||
int y11 = ITUR_BT_601_CRY * r11 + ITUR_BT_601_CGY * g11 + ITUR_BT_601_CBY * b11 + halfShift + shifted16;
|
||||
y[2 * k + 0] = saturate_cast<uchar>(y00 >> ITUR_BT_601_SHIFT);
|
||||
y[2 * k + 1] = saturate_cast<uchar>(y01 >> ITUR_BT_601_SHIFT);
|
||||
y[2 * k + dst_->step + 0] = saturate_cast<uchar>(y10 >> ITUR_BT_601_SHIFT);
|
||||
y[2 * k + dst_->step + 1] = saturate_cast<uchar>(y11 >> ITUR_BT_601_SHIFT);
|
||||
const int shifted128 = (128 << ITUR_BT_601_SHIFT);
|
||||
int u00 = ITUR_BT_601_CRU * r00 + ITUR_BT_601_CGU * g00 + ITUR_BT_601_CBU * b00 + halfShift + shifted128;
|
||||
int v00 = ITUR_BT_601_CBU * r00 + ITUR_BT_601_CGV * g00 + ITUR_BT_601_CBV * b00 + halfShift + shifted128;
|
||||
u[k] = saturate_cast<uchar>(u00 >> ITUR_BT_601_SHIFT);
|
||||
v[k] = saturate_cast<uchar>(v00 >> ITUR_BT_601_SHIFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
RGB888toYUV420pInvoker& operator=(const RGB888toYUV420pInvoker&);
|
||||
const Mat_<_Tp, chs1>& src_;
|
||||
Mat_<_Tp, chs2>* const dst_;
|
||||
const int uIdx_;
|
||||
};
|
||||
|
||||
|
||||
template<typename _Tp, int chs1, int chs2>
|
||||
static int CvtColorLoop_RGB2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx)
|
||||
{
|
||||
Range range(0, src.rows);
|
||||
|
||||
const uchar* yS_ = src.ptr(range.start);
|
||||
uchar* yD_ = (uchar*)dst.ptr(range.start);
|
||||
int scn = src.channels, dcn = dst.channels;
|
||||
|
||||
for (int h = range.start; h < range.end; ++h, yS_ += src.step, yD_ += dst.step) {
|
||||
int n = src.cols;
|
||||
const _Tp* yS = (const _Tp*)yS_;
|
||||
_Tp* yD = (_Tp*)yD_;
|
||||
|
||||
if (dcn == 3) {
|
||||
n *= 3;
|
||||
for (int i = 0; i < n; i += 3, yS += scn) {
|
||||
_Tp t0 = yS[bidx], t1 = yS[1], t2 = yS[bidx ^ 2];
|
||||
yD[i] = t0; yD[i + 1] = t1; yD[i + 2] = t2;
|
||||
}
|
||||
} else if (scn == 3) {
|
||||
n *= 3;
|
||||
_Tp alpha = ColorChannel<_Tp>::max(); // Note: _Tp = float: alpha = 1.0f
|
||||
for (int i = 0; i < n; i += 3, yD += 4) {
|
||||
_Tp t0 = yS[i], t1 = yS[i + 1], t2 = yS[i + 2];
|
||||
yD[bidx] = t0; yD[1] = t1; yD[bidx ^ 2] = t2; yD[3] = alpha;
|
||||
}
|
||||
} else {
|
||||
n *= 4;
|
||||
for (int i = 0; i < n; i += 4) {
|
||||
_Tp t0 = yS[i], t1 = yS[i + 1], t2 = yS[i + 2], t3 = yS[i + 3];
|
||||
yD[i] = t2; yD[i + 1] = t1; yD[i + 2] = t0; yD[i + 3] = t3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs1, int chs2>
|
||||
static int CvtColorLoop_RGB2Gray(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx)
|
||||
{
|
||||
Range range(0, src.rows);
|
||||
const uchar* yS = src.ptr(range.start);
|
||||
uchar* yD = (uchar*)dst.ptr(range.start);
|
||||
int scn = src.channels, dcn = dst.channels;
|
||||
|
||||
RGB2Gray<_Tp> rgb2gray(scn, bidx, 0);
|
||||
|
||||
for (int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step) {
|
||||
rgb2gray((const _Tp*)yS, (_Tp*)yD, src.cols);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs1, int chs2>
|
||||
static int CvtColorLoop_RGB2YCrCb(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs_f, const int* coeffs_i)
|
||||
{
|
||||
Range range(0, src.rows);
|
||||
const uchar* yS = src.ptr(range.start);
|
||||
uchar* yD = (uchar*)dst.ptr(range.start);
|
||||
int scn = src.channels, dcn = dst.channels;
|
||||
if (sizeof(_Tp) == 4) {
|
||||
RGB2YCrCb_f<_Tp> rgb2ycrcb(scn, bidx, coeffs_f);
|
||||
for (int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step) {
|
||||
rgb2ycrcb((const _Tp*)yS, (_Tp*)yD, src.cols);
|
||||
}
|
||||
} else {
|
||||
if (sizeof(_Tp) == 1) {
|
||||
RGB2YCrCb_i<uchar> rgb2ycrcb(scn, bidx, coeffs_i);
|
||||
for (int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step) {
|
||||
rgb2ycrcb((const uchar*)yS, (uchar*)yD, src.cols);
|
||||
}
|
||||
} else {
|
||||
RGB2YCrCb_i<ushort> rgb2ycrcb(scn, bidx, coeffs_i);
|
||||
for (int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step) {
|
||||
rgb2ycrcb((const ushort*)yS, (ushort*)yD, src.cols);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs1, int chs2, int bIdx, int uIdx>
|
||||
static void cvtRGBtoYUV420p(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst)
|
||||
{
|
||||
RGB888toYUV420pInvoker<_Tp, chs1, chs2, bIdx> colorConverter(src, &dst, uIdx);
|
||||
colorConverter(Range(0, src.rows / 2));
|
||||
}
|
||||
|
||||
|
||||
} // namespace yt_tinycv
|
||||
#endif // FBC_CV_CVTCOLOR_HPP_
|
||||
@@ -0,0 +1,75 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_FAST_MATH_HPP_
|
||||
#define FBC_CV_CORE_FAST_MATH_HPP_
|
||||
|
||||
// reference: include/opencv2/core/fast_math.hpp
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
// Rounds floating-point number to the nearest integer
|
||||
static inline int fbcRound(double value)
|
||||
{
|
||||
// it's ok if round does not comply with IEEE754 standard;
|
||||
// it should allow +/-1 difference when the other functions use round
|
||||
return (int)(value + (value >= 0 ? 0.5 : -0.5));
|
||||
}
|
||||
|
||||
static inline int fbcRound(float value)
|
||||
{
|
||||
// it's ok if round does not comply with IEEE754 standard;
|
||||
// it should allow +/-1 difference when the other functions use round
|
||||
return (int)(value + (value >= 0 ? 0.5f : -0.5f));
|
||||
}
|
||||
|
||||
static inline int fbcRound(int value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// Rounds floating-point number to the nearest integer not larger than the original
|
||||
static inline int fbcFloor(double value)
|
||||
{
|
||||
int i = fbcRound(value);
|
||||
float diff = (float)(value - i);
|
||||
return i - (diff < 0);
|
||||
}
|
||||
|
||||
static inline int fbcFloor(float value)
|
||||
{
|
||||
int i = fbcRound(value);
|
||||
float diff = (float)(value - i);
|
||||
return i - (diff < 0);
|
||||
}
|
||||
|
||||
static inline int fbcFloor(int value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// Rounds floating-point number to the nearest integer not smaller than the original
|
||||
static inline int fbcCeil(double value)
|
||||
{
|
||||
int i = fbcRound(value);
|
||||
float diff = (float)(i - value);
|
||||
return i + (diff < 0);
|
||||
}
|
||||
|
||||
static inline int fbcCeil(float value)
|
||||
{
|
||||
int i = fbcRound(value);
|
||||
float diff = (float)(i - value);
|
||||
return i + (diff < 0);
|
||||
}
|
||||
|
||||
static inline int fbcCeil(int value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
} // yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_FAST_MATH_HPP_
|
||||
@@ -0,0 +1,67 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_FBCDEF_HPP_
|
||||
#define FBC_CV_CORE_FBCDEF_HPP_
|
||||
|
||||
/* reference: include/opencv2/core/cvdef.h
|
||||
include/opencv2/core/typedef_c.h
|
||||
*/
|
||||
|
||||
#include "interface.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define FBC_EXPORTS __declspec(dllexport)
|
||||
#define FBC_DECL_ALIGNED(x) __declspec(align(x))
|
||||
#else
|
||||
#define FBC_EXPORTS __attribute__((visibility("default")))
|
||||
#define FBC_DECL_ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
#define FBC_CN_MAX 512
|
||||
#define FBC_CN_SHIFT 3
|
||||
#define FBC_DEPTH_MAX (1 << FBC_CN_SHIFT)
|
||||
|
||||
#define FBC_MAT_TYPE_MASK (FBC_DEPTH_MAX*FBC_CN_MAX - 1)
|
||||
#define FBC_MAT_TYPE(flags) ((flags) & FBC_MAT_TYPE_MASK)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) > (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#define FBC_CN_MAX 512
|
||||
|
||||
// Common macros and inline functions
|
||||
#define FBC_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
|
||||
|
||||
/** min & max without jumps */
|
||||
#define FBC_IMIN(a, b) ((a) ^ (((a)^(b)) & (((a) < (b)) - 1)))
|
||||
#define FBC_IMAX(a, b) ((a) ^ (((a)^(b)) & (((a) > (b)) - 1)))
|
||||
|
||||
// fundamental constants
|
||||
#define FBC_PI 3.1415926535897932384626433832795
|
||||
|
||||
// Note: No practical significance
|
||||
class dump {};
|
||||
|
||||
typedef union Cv32suf {
|
||||
int i;
|
||||
unsigned u;
|
||||
float f;
|
||||
} Cv32suf;
|
||||
|
||||
typedef union Cv64suf {
|
||||
int64 i;
|
||||
yt_tinycv::uint64 u;
|
||||
double f;
|
||||
} Cv64suf;
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_FBCDEF_HPP_
|
||||
@@ -0,0 +1,30 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_FBCSTD_HPP_
|
||||
#define FBC_CV_CORE_FBCSTD_HPP_
|
||||
|
||||
// reference: include/opencv2/core/cvstd.hpp
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error fbcstd.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
/* the alignment of all the allocated buffers */
|
||||
#define FBC_MALLOC_ALIGN 16
|
||||
|
||||
// Allocates an aligned memory buffer
|
||||
FBC_EXPORTS void* fastMalloc(size_t size);
|
||||
// Deallocates a memory buffer
|
||||
FBC_EXPORTS void fastFree(void* ptr);
|
||||
void* cvAlloc(size_t size);
|
||||
void cvFree_(void* ptr);
|
||||
#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0)
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_FBCSTD_HPP_
|
||||
@@ -0,0 +1,316 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_IMGPROC_HPP_
|
||||
#define FBC_CV_IMGPROC_HPP_
|
||||
|
||||
// reference: include/opencv2/imgproc.hpp
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "mat.hpp"
|
||||
#include "core.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
// interpolation algorithm
|
||||
enum InterpolationFlags{
|
||||
/** nearest neighbor interpolation */
|
||||
INTER_NEAREST = 0,
|
||||
/** bilinear interpolation */
|
||||
INTER_LINEAR = 1,
|
||||
/** bicubic interpolation */
|
||||
INTER_CUBIC = 2,
|
||||
/** resampling using pixel area relation. It may be a preferred method for image decimation, as
|
||||
it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method. */
|
||||
INTER_AREA = 3,
|
||||
/** Lanczos interpolation over 8x8 neighborhood */
|
||||
INTER_LANCZOS4 = 4,
|
||||
/** mask for interpolation codes */
|
||||
INTER_MAX = 7,
|
||||
/** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
|
||||
source image, they are set to zero */
|
||||
WARP_FILL_OUTLIERS = 8,
|
||||
/** flag, inverse transformation
|
||||
|
||||
For example, polar transforms:
|
||||
- flag is __not__ set: \f$dst( \phi , \rho ) = src(x,y)\f$
|
||||
- flag is set: \f$dst(x,y) = src( \phi , \rho )\f$
|
||||
*/
|
||||
WARP_INVERSE_MAP = 16
|
||||
};
|
||||
|
||||
enum InterpolationMasks {
|
||||
INTER_BITS = 5,
|
||||
INTER_BITS2 = INTER_BITS * 2,
|
||||
INTER_TAB_SIZE = 1 << INTER_BITS,
|
||||
INTER_TAB_SIZE2 = INTER_TAB_SIZE * INTER_TAB_SIZE
|
||||
};
|
||||
|
||||
// Constants for color conversion
|
||||
enum ColorConversionFlags {
|
||||
CV_BGR2BGRA = 0,
|
||||
CV_RGB2RGBA = CV_BGR2BGRA,
|
||||
|
||||
CV_BGRA2BGR = 1,
|
||||
CV_RGBA2RGB = CV_BGRA2BGR,
|
||||
|
||||
CV_BGR2RGBA = 2,
|
||||
CV_RGB2BGRA = CV_BGR2RGBA,
|
||||
|
||||
CV_RGBA2BGR = 3,
|
||||
CV_BGRA2RGB = CV_RGBA2BGR,
|
||||
|
||||
CV_BGR2RGB = 4,
|
||||
CV_RGB2BGR = CV_BGR2RGB,
|
||||
|
||||
CV_BGRA2RGBA = 5,
|
||||
CV_RGBA2BGRA = CV_BGRA2RGBA,
|
||||
|
||||
CV_BGR2GRAY = 6,
|
||||
CV_RGB2GRAY = 7,
|
||||
CV_GRAY2BGR = 8,
|
||||
CV_GRAY2RGB = CV_GRAY2BGR,
|
||||
CV_GRAY2BGRA = 9,
|
||||
CV_GRAY2RGBA = CV_GRAY2BGRA,
|
||||
CV_BGRA2GRAY = 10,
|
||||
CV_RGBA2GRAY = 11,
|
||||
|
||||
// CV_BGR2BGR565 // 12 - 31
|
||||
|
||||
CV_BGR2XYZ = 32,
|
||||
CV_RGB2XYZ = 33,
|
||||
CV_XYZ2BGR = 34,
|
||||
CV_XYZ2RGB = 35,
|
||||
|
||||
CV_BGR2YCrCb = 36,
|
||||
CV_RGB2YCrCb = 37,
|
||||
CV_YCrCb2BGR = 38,
|
||||
CV_YCrCb2RGB = 39,
|
||||
|
||||
CV_BGR2HSV = 40,
|
||||
CV_RGB2HSV = 41,
|
||||
|
||||
CV_BGR2Lab = 44,
|
||||
CV_RGB2Lab = 45,
|
||||
|
||||
// CV_BayerBG2BGR // 46 - 49
|
||||
|
||||
CV_BGR2Luv = 50,
|
||||
CV_RGB2Luv = 51,
|
||||
CV_BGR2HLS = 52,
|
||||
CV_RGB2HLS = 53,
|
||||
|
||||
CV_HSV2BGR = 54,
|
||||
CV_HSV2RGB = 55,
|
||||
|
||||
CV_Lab2BGR = 56,
|
||||
CV_Lab2RGB = 57,
|
||||
CV_Luv2BGR = 58,
|
||||
CV_Luv2RGB = 59,
|
||||
CV_HLS2BGR = 60,
|
||||
CV_HLS2RGB = 61,
|
||||
|
||||
// CV_BayerBG2BGR_VNG // 62 - 65
|
||||
|
||||
CV_BGR2HSV_FULL = 66,
|
||||
CV_RGB2HSV_FULL = 67,
|
||||
CV_BGR2HLS_FULL = 68,
|
||||
CV_RGB2HLS_FULL = 69,
|
||||
|
||||
CV_HSV2BGR_FULL = 70,
|
||||
CV_HSV2RGB_FULL = 71,
|
||||
CV_HLS2BGR_FULL = 72,
|
||||
CV_HLS2RGB_FULL = 73,
|
||||
|
||||
// CV_LBGR2Lab // 74 - 81
|
||||
|
||||
CV_BGR2YUV = 82,
|
||||
CV_RGB2YUV = 83,
|
||||
CV_YUV2BGR = 84,
|
||||
CV_YUV2RGB = 85,
|
||||
|
||||
// CV_BayerBG2GRAY // 86 - 89
|
||||
|
||||
//YUV 4:2:0 formats family
|
||||
CV_YUV2RGB_NV12 = 90,
|
||||
CV_YUV2BGR_NV12 = 91,
|
||||
CV_YUV2RGB_NV21 = 92,
|
||||
CV_YUV2BGR_NV21 = 93,
|
||||
CV_YUV420sp2RGB = CV_YUV2RGB_NV21,
|
||||
CV_YUV420sp2BGR = CV_YUV2BGR_NV21,
|
||||
|
||||
CV_YUV2RGBA_NV12 = 94,
|
||||
CV_YUV2BGRA_NV12 = 95,
|
||||
CV_YUV2RGBA_NV21 = 96,
|
||||
CV_YUV2BGRA_NV21 = 97,
|
||||
CV_YUV420sp2RGBA = CV_YUV2RGBA_NV21,
|
||||
CV_YUV420sp2BGRA = CV_YUV2BGRA_NV21,
|
||||
|
||||
CV_YUV2RGB_YV12 = 98,
|
||||
CV_YUV2BGR_YV12 = 99,
|
||||
CV_YUV2RGB_IYUV = 100,
|
||||
CV_YUV2BGR_IYUV = 101,
|
||||
CV_YUV2RGB_I420 = CV_YUV2RGB_IYUV,
|
||||
CV_YUV2BGR_I420 = CV_YUV2BGR_IYUV,
|
||||
CV_YUV420p2RGB = CV_YUV2RGB_YV12,
|
||||
CV_YUV420p2BGR = CV_YUV2BGR_YV12,
|
||||
|
||||
CV_YUV2RGBA_YV12 = 102,
|
||||
CV_YUV2BGRA_YV12 = 103,
|
||||
CV_YUV2RGBA_IYUV = 104,
|
||||
CV_YUV2BGRA_IYUV = 105,
|
||||
CV_YUV2RGBA_I420 = CV_YUV2RGBA_IYUV,
|
||||
CV_YUV2BGRA_I420 = CV_YUV2BGRA_IYUV,
|
||||
CV_YUV420p2RGBA = CV_YUV2RGBA_YV12,
|
||||
CV_YUV420p2BGRA = CV_YUV2BGRA_YV12,
|
||||
|
||||
CV_YUV2GRAY_420 = 106,
|
||||
CV_YUV2GRAY_NV21 = CV_YUV2GRAY_420,
|
||||
CV_YUV2GRAY_NV12 = CV_YUV2GRAY_420,
|
||||
CV_YUV2GRAY_YV12 = CV_YUV2GRAY_420,
|
||||
CV_YUV2GRAY_IYUV = CV_YUV2GRAY_420,
|
||||
CV_YUV2GRAY_I420 = CV_YUV2GRAY_420,
|
||||
CV_YUV420sp2GRAY = CV_YUV2GRAY_420,
|
||||
CV_YUV420p2GRAY = CV_YUV2GRAY_420,
|
||||
|
||||
// YUV 4:2:2 formats family // 107 - 124
|
||||
|
||||
// alpha premultiplication // 125 - 126
|
||||
|
||||
CV_RGB2YUV_I420 = 127,
|
||||
CV_BGR2YUV_I420 = 128,
|
||||
CV_RGB2YUV_IYUV = CV_RGB2YUV_I420,
|
||||
CV_BGR2YUV_IYUV = CV_BGR2YUV_I420,
|
||||
|
||||
CV_RGBA2YUV_I420 = 129,
|
||||
CV_BGRA2YUV_I420 = 130,
|
||||
CV_RGBA2YUV_IYUV = CV_RGBA2YUV_I420,
|
||||
CV_BGRA2YUV_IYUV = CV_BGRA2YUV_I420,
|
||||
CV_RGB2YUV_YV12 = 131,
|
||||
CV_BGR2YUV_YV12 = 132,
|
||||
CV_RGBA2YUV_YV12 = 133,
|
||||
CV_BGRA2YUV_YV12 = 134
|
||||
|
||||
// Edge-Aware Demosaicing // 135 - 139
|
||||
};
|
||||
|
||||
// type of morphological operation
|
||||
enum MorphTypes{
|
||||
MORPH_ERODE = 0, // see cv::erode
|
||||
MORPH_DILATE = 1, // see cv::dilate
|
||||
MORPH_OPEN = 2, // an opening operation
|
||||
// \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f]
|
||||
MORPH_CLOSE = 3, // a closing operation
|
||||
// \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f]
|
||||
MORPH_GRADIENT = 4, // a morphological gradient
|
||||
// \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f]
|
||||
MORPH_TOPHAT = 5, // "top hat"
|
||||
// \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f]
|
||||
MORPH_BLACKHAT = 6, // "black hat"
|
||||
// \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f]
|
||||
MORPH_HITMISS = 7 // "hit and miss"
|
||||
// Only supported for CV_8UC1 binary images. Tutorial can be found in [this page](http://opencv-code.com/tutorials/hit-or-miss-transform-in-opencv/)
|
||||
};
|
||||
|
||||
// shape of the structuring element
|
||||
enum MorphShapes {
|
||||
MORPH_RECT = 0, // a rectangular structuring element: \f[E_{ij}=1\f]
|
||||
MORPH_CROSS = 1, // a cross-shaped structuring element:
|
||||
//!< \f[E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f]
|
||||
MORPH_ELLIPSE = 2 // an elliptic structuring element, that is, a filled ellipse inscribed
|
||||
// into the rectangle Rect(0, 0, esize.width, 0.esize.height)
|
||||
};
|
||||
|
||||
// type of the threshold operation
|
||||
enum ThresholdTypes {
|
||||
THRESH_BINARY = 0, // \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
|
||||
THRESH_BINARY_INV = 1, // \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
|
||||
THRESH_TRUNC = 2, // \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
|
||||
THRESH_TOZERO = 3, // \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
|
||||
THRESH_TOZERO_INV = 4, // \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
|
||||
THRESH_MASK = 7,
|
||||
THRESH_OTSU = 8, // flag, use Otsu algorithm to choose the optimal threshold value, combine the flag with one of the above THRESH_* values
|
||||
THRESH_TRIANGLE = 16 // flag, use Triangle algorithm to choose the optimal threshold value, combine the flag with one of the above THRESH_* values, but not with THRESH_OTSU
|
||||
};
|
||||
|
||||
// adaptive threshold algorithm
|
||||
enum AdaptiveThresholdTypes {
|
||||
/** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times
|
||||
\texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */
|
||||
ADAPTIVE_THRESH_MEAN_C = 0,
|
||||
/** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian
|
||||
window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$
|
||||
minus C . The default sigma (standard deviation) is used for the specified blockSize . See cv::getGaussianKernel*/
|
||||
ADAPTIVE_THRESH_GAUSSIAN_C = 1
|
||||
};
|
||||
|
||||
// helper tables
|
||||
const uchar icvSaturate8u_cv[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
||||
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255
|
||||
};
|
||||
|
||||
#define FBC_FAST_CAST_8U(t) (assert(-256 <= (t) && (t) <= 512), icvSaturate8u_cv[(t)+256])
|
||||
#define FBC_CALC_MIN_8U(a,b) (a) -= FBC_FAST_CAST_8U((a) - (b))
|
||||
#define FBC_CALC_MAX_8U(a,b) (a) += FBC_FAST_CAST_8U((b) - (a))
|
||||
|
||||
// cal a structuring element of the specified size and shape for morphological operations
|
||||
FBC_EXPORTS int getStructuringElement(Mat_<uchar, 1>& dst, int shape, Size ksize, Point anchor = Point(-1, -1));
|
||||
|
||||
// Returns the optimal DFT size for a given vector size
|
||||
// Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process.
|
||||
// Though, the arrays whose size is a product of 2's, 3's, and 5's are also processed quite efficiently
|
||||
FBC_EXPORTS int getOptimalDFTSize(int vecsize);
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_IMGPROC_HPP_
|
||||
@@ -0,0 +1,38 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_INTERFACE_HPP_
|
||||
#define FBC_CV_CORE_INTERFACE_HPP_
|
||||
|
||||
// reference: include/opencv2/core/hal/interface.h
|
||||
#include <stdint.h>
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
/* primitive types */
|
||||
/*
|
||||
schar - signed 1 byte integer
|
||||
uchar - unsigned 1 byte integer
|
||||
short - signed 2 byte integer
|
||||
ushort - unsigned 2 byte integer
|
||||
int - signed 4 byte integer
|
||||
uint - unsigned 4 byte integer
|
||||
int64 - signed 8 byte integer
|
||||
uint64 - unsigned 8 byte integer
|
||||
*/
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef signed char schar;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#else
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
#endif
|
||||
|
||||
} // yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_INTERFACE_HPP_
|
||||
@@ -0,0 +1,646 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_MAT_HPP_
|
||||
#define FBC_CV_CORE_MAT_HPP_
|
||||
|
||||
/* reference: include/opencv2/core/mat.hpp
|
||||
core/src/alloc.cpp
|
||||
include/opencv2/core/utility.hpp
|
||||
include/opencv2/core/cvstd.hpp
|
||||
include/opencv2/core/mat.inl.hpp
|
||||
*/
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error mat.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include "fbcdef.hpp"
|
||||
#include "types.hpp"
|
||||
#include "base.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "fbcstd.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "saturate.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
// The class Mat_ represents an n-dimensional dense numerical single-channel or multi-channel array
|
||||
template<typename _Tp, int chs> class Mat_ {
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
|
||||
// default constructor
|
||||
Mat_() : rows(0), cols(0), channels(0), data(NULL), step(0), allocated(false), datastart(NULL), dataend(NULL) {}
|
||||
// constructs 2D matrix of the specified size
|
||||
Mat_(int _rows, int _cols);
|
||||
// constucts 2D matrix and fills it with the specified value _s
|
||||
Mat_(int _rows, int _cols, const Scalar& _s);
|
||||
// constructor for matrix headers pointing to user-allocated data, no data is copied
|
||||
Mat_(int _rows, int _cols, void* _data);
|
||||
// copy constructor, NOTE: deep copy
|
||||
Mat_(const Mat_<_Tp, chs>& _m);
|
||||
|
||||
Mat_& operator = (const Mat_& _m);
|
||||
|
||||
Mat_ clone() const;
|
||||
|
||||
// reports whether the matrix is continuous or not
|
||||
bool isContinuous() const;
|
||||
// returns true if the matrix is a submatrix of another matrix
|
||||
bool isSubmatrix() const;
|
||||
|
||||
// copies the matrix content to "_m"
|
||||
void copyTo(Mat_<_Tp, chs>& _m, const Rect& rect = Rect(0, 0, 0, 0)) const;
|
||||
|
||||
// return typed pointer to the specified matrix row,i0, A 0-based row index
|
||||
const uchar* ptr(int i0 = 0) const;
|
||||
uchar* ptr(int i0 = 0);
|
||||
|
||||
// no data is copied, no memory is allocated
|
||||
void getROI(Mat_<_Tp, chs>& _m, const Rect& rect = Rect(0, 0, 0, 0));
|
||||
// Locates the matrix header within a parent matrix
|
||||
void locateROI(Size& wholeSize, Point& ofs) const;
|
||||
// Adjusts a submatrix size and position within the parent matrix
|
||||
void adjustROI(int dtop, int dbottom, int dleft, int dright);
|
||||
|
||||
// value converted to the actual array type
|
||||
void setTo(const Scalar& _value);
|
||||
|
||||
// Converts an array to another data type with optional scaling
|
||||
// the method converts source pixel values to the target data type
|
||||
// if it does not have a proper size before the operation, it is reallocated
|
||||
// \f[m(x,y) = saturate \_ cast<rType>( \alpha (*this)(x,y) + \beta )\f]
|
||||
template<typename _Tp2>
|
||||
void convertTo(Mat_<_Tp2, chs>& _m, double alpha = 1, const Scalar& scalar = Scalar(0, 0, 0, 0)) const;
|
||||
|
||||
Mat_<_Tp, chs>& zeros(int _rows, int _cols);
|
||||
|
||||
// returns the matrix cols and rows
|
||||
Size size() const;
|
||||
// returns true if Mat_::total() is 0 or if Mat_::data is NULL
|
||||
bool empty() const;
|
||||
// returns the matrix element size in bytes: sizeof(_Tp) * channels
|
||||
size_t elemSize() const;
|
||||
// returns the size of each matrix element channel in bytes: sizeof(_Tp)
|
||||
size_t elemSize1() const;
|
||||
// returns the total number of array elements
|
||||
size_t total() const;
|
||||
|
||||
// release memory
|
||||
inline void release();
|
||||
// destructor - calls release()
|
||||
~Mat_() { release(); };
|
||||
|
||||
public:
|
||||
// the number of rows and columns
|
||||
int rows, cols;
|
||||
// channel num
|
||||
int channels;
|
||||
// pointer to the data
|
||||
uchar* data;
|
||||
// bytes per row
|
||||
int step; // stride
|
||||
// memory allocation flag
|
||||
bool allocated;
|
||||
// helper fields used in locateROI and adjustROI
|
||||
const uchar* datastart;
|
||||
const uchar* dataend;
|
||||
}; // Mat_
|
||||
|
||||
typedef Mat_<uchar, 1> Mat1Gray;
|
||||
typedef Mat_<uchar, 3> Mat3BGR;
|
||||
typedef Mat_<uchar, 4> Mat4BGRA;
|
||||
|
||||
template<typename _Tp, int chs> inline
|
||||
void Mat_<_Tp, chs>::release()
|
||||
{
|
||||
if (this->data && this->allocated) {
|
||||
fastFree(this->data);
|
||||
}
|
||||
|
||||
this->data = NULL;
|
||||
this->datastart = NULL;
|
||||
this->dataend = NULL;
|
||||
this->allocated = false;
|
||||
this->rows = this->cols = this->step = this->channels = 0;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>::Mat_(int _rows, int _cols)
|
||||
{
|
||||
FBC_Assert(_rows > 0 && _cols > 0 && chs > 0);
|
||||
|
||||
this->rows = _rows;
|
||||
this->cols = _cols;
|
||||
this->channels = chs;
|
||||
this->step = sizeof(_Tp) * _cols * chs;
|
||||
this->allocated = true;
|
||||
|
||||
size_t size_ = this->rows * this->step;
|
||||
uchar* p = (uchar*)fastMalloc(size_);
|
||||
FBC_Assert(p != NULL);
|
||||
|
||||
this->data = p;
|
||||
this->datastart = this->data;
|
||||
this->dataend = this->data + size_;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>::Mat_(int _rows, int _cols, const Scalar& _s)
|
||||
{
|
||||
FBC_Assert(_rows > 0 && _cols > 0 && chs > 0);
|
||||
|
||||
this->rows = _rows;
|
||||
this->cols = _cols;
|
||||
this->channels = chs;
|
||||
this->step = sizeof(_Tp) * _cols * chs;
|
||||
this->allocated = true;
|
||||
|
||||
size_t size_ = this->rows * this->step;
|
||||
uchar* p = (uchar*)fastMalloc(size_);
|
||||
FBC_Assert(p != NULL);
|
||||
this->data = p;
|
||||
this->datastart = this->data;
|
||||
this->dataend = this->data + size_;
|
||||
|
||||
for (int i = 0; i < _rows; i++) {
|
||||
_Tp* pRow = (_Tp*)this->data + i * _cols * chs;
|
||||
|
||||
for (int j = 0; j < _cols; j++) {
|
||||
_Tp* pPixel = pRow + j * chs;
|
||||
|
||||
for (int m = 0, n = 0; m < chs && n < 4; m++, n++) {
|
||||
pPixel[n] = saturate_cast<_Tp>(_s.val[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>::Mat_(int _rows, int _cols, void* _data)
|
||||
{
|
||||
FBC_Assert(_rows > 0 && _cols > 0 && chs > 0);
|
||||
|
||||
this->rows = _rows;
|
||||
this->cols = _cols;
|
||||
this->channels = chs;
|
||||
this->step = sizeof(_Tp) * _cols * chs;
|
||||
this->allocated = false;
|
||||
this->data = (uchar*)_data;
|
||||
this->datastart = this->data;
|
||||
this->dataend = this->data + this->step * this->rows;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>::Mat_(const Mat_<_Tp, chs>& _m)
|
||||
{
|
||||
this->rows = _m.rows;
|
||||
this->cols = _m.cols;
|
||||
this->channels = _m.channels;
|
||||
this->step = sizeof(_Tp) * this->cols * this->channels;
|
||||
|
||||
size_t size_ = this->rows * this->step;
|
||||
if (size_ > 0) {
|
||||
this->allocated = true;
|
||||
uchar* p = (uchar*)fastMalloc(size_);
|
||||
FBC_Assert(p != NULL);
|
||||
|
||||
memcpy(p, _m.data, size_);
|
||||
this->data = p;
|
||||
} else {
|
||||
this->allocated = false;
|
||||
this->data = NULL;
|
||||
}
|
||||
|
||||
this->datastart = this->data;
|
||||
this->dataend = this->data + size_;
|
||||
}
|
||||
|
||||
|
||||
// template<typename _Tp, int chs>
|
||||
// Mat_<_Tp, chs>& Mat_<_Tp, chs>::operator () (const Rect& roi)
|
||||
// {
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>& Mat_<_Tp, chs>::operator = (const Mat_& _m)
|
||||
{
|
||||
size_t size1 = this->rows * this->step;
|
||||
size_t size2 = _m.rows * _m.step;
|
||||
|
||||
this->rows = _m.rows;
|
||||
this->cols = _m.cols;
|
||||
this->channels = _m.channels;
|
||||
this->step = sizeof(_Tp) * this->cols * this->channels;
|
||||
|
||||
if ((size1 == size2) && (this->allocated == true) && (this->data != _m.data)) {
|
||||
memcpy(this->data, _m.data, size2);
|
||||
} else if (size2 > 0){
|
||||
if (this->allocated == true) {
|
||||
fastFree(this->data);
|
||||
}
|
||||
|
||||
this->allocated = true;
|
||||
uchar* p = (uchar*)fastMalloc(size2);
|
||||
FBC_Assert(p != NULL);
|
||||
memcpy(p, _m.data, size2);
|
||||
this->data = p;
|
||||
} else {
|
||||
this->allocated = false;
|
||||
this->data = NULL;
|
||||
}
|
||||
|
||||
this->datastart = this->data;
|
||||
this->dataend = this->data + size2;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs> Mat_<_Tp, chs>::clone() const
|
||||
{
|
||||
Mat_ m;
|
||||
Rect rect(0, 0, this->cols, this->rows);
|
||||
copyTo(m, rect);
|
||||
return m;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
bool Mat_<_Tp, chs>::isContinuous() const
|
||||
{
|
||||
return this->rows == 1 || this->step == this->cols * this->elemSize();
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
bool Mat_<_Tp, chs>::isSubmatrix() const
|
||||
{
|
||||
if ((this->datastart < this->data) || ((this->data + this->step * this->rows) < this->dataend))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void Mat_<_Tp, chs>::copyTo(Mat_<_Tp, chs>& _m, const Rect& rect) const
|
||||
{
|
||||
FBC_Assert((this->rows >= rect.y + rect.height) && (this->cols >= rect.x + rect.width));
|
||||
|
||||
if (this->data != NULL) {
|
||||
if ((rect.width > 0) && (rect.height > 0)) {
|
||||
size_t size1 = sizeof(_Tp) * this->channels * rect.width * rect.height;
|
||||
int step_ = sizeof(_Tp) * this->channels * rect.width;
|
||||
size_t size2 = _m.rows * _m.step;
|
||||
|
||||
if (size1 == size2) {
|
||||
uchar* p1 = _m.data;
|
||||
uchar* p2 = this->data;
|
||||
|
||||
for (int i = 0; i < rect.height; i++) {
|
||||
uchar* p1_ = p1 + i * sizeof(_Tp) * this->channels * rect.width;
|
||||
uchar* p2_ = p2 + (rect.y + i) * this->step + rect.x * this->channels * sizeof(_Tp);
|
||||
|
||||
memcpy(p1_, p2_, step_);
|
||||
}
|
||||
} else {
|
||||
if (_m.allocated == true)
|
||||
fastFree(_m.data);
|
||||
|
||||
uchar* p1 = (uchar*)fastMalloc(size1);
|
||||
FBC_Assert(p1 != NULL);
|
||||
uchar* p2 = this->data;
|
||||
|
||||
for (int i = 0; i < rect.height; i++) {
|
||||
uchar* p1_ = p1 + i * sizeof(_Tp) * this->channels * rect.width;
|
||||
uchar* p2_ = p2 + (rect.y + i) * this->step + rect.x * this->channels * sizeof(_Tp);
|
||||
|
||||
memcpy(p1_, p2_, step_);
|
||||
}
|
||||
_m.data = p1;
|
||||
_m.allocated = true;
|
||||
}
|
||||
|
||||
_m.rows = rect.height;
|
||||
_m.cols = rect.width;
|
||||
_m.step = step_;
|
||||
} else {
|
||||
size_t size1 = this->rows * this->step;
|
||||
size_t size2 = _m.step * _m.rows;
|
||||
|
||||
if (size1 == size2) {
|
||||
memcpy(_m.data, this->data, size1);
|
||||
} else {
|
||||
if (_m.allocated == true)
|
||||
fastFree(_m.data);
|
||||
|
||||
uchar* p = (uchar*)fastMalloc(size1);
|
||||
FBC_Assert(p != NULL);
|
||||
memcpy(p, this->data, size1);
|
||||
_m.data = p;
|
||||
_m.allocated = true;
|
||||
}
|
||||
|
||||
_m.rows = this->rows;
|
||||
_m.cols = this->cols;
|
||||
_m.step = this->step;
|
||||
}
|
||||
_m.channels = this->channels;
|
||||
|
||||
} else {
|
||||
if ((_m.data != NULL) && (_m.allocated == true)) {
|
||||
fastFree(_m.data);
|
||||
}
|
||||
|
||||
_m.data = NULL;
|
||||
_m.allocated = false;
|
||||
_m.rows = 0;
|
||||
_m.cols = 0;
|
||||
_m.step = 0;
|
||||
_m.channels = 0;
|
||||
}
|
||||
|
||||
_m.datastart = _m.data;
|
||||
_m.dataend = _m.data + _m.step * _m.rows;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
const uchar* Mat_<_Tp, chs>::ptr(int i0) const
|
||||
{
|
||||
FBC_Assert(i0 < this->rows);
|
||||
|
||||
return this->data + i0 * this->step;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
uchar* Mat_<_Tp, chs>::ptr(int i0)
|
||||
{
|
||||
FBC_Assert(i0 < this->rows);
|
||||
|
||||
return this->data + i0 * this->step;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void Mat_<_Tp, chs>::getROI(Mat_<_Tp, chs>& _m, const Rect& rect)
|
||||
{
|
||||
FBC_Assert((rect.x >= 0) && (rect.y >= 0) && (rect.width > 0) && (rect.height > 0) &&
|
||||
(this->rows >= rect.y + rect.height) && (this->cols >= rect.x + rect.width));
|
||||
|
||||
if (_m.allocated == true) {
|
||||
fastFree(_m.data);
|
||||
}
|
||||
|
||||
_m.rows = rect.height;
|
||||
_m.cols = rect.width;
|
||||
_m.channels = this->channels;
|
||||
_m.allocated = false;
|
||||
_m.step = this->step;
|
||||
_m.data = this->data + rect.y * this->step + rect.x * sizeof(_Tp) * this->channels;
|
||||
_m.datastart = this->datastart;
|
||||
_m.dataend = this->dataend;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void Mat_<_Tp, chs>::locateROI(Size& wholeSize, Point& ofs) const
|
||||
{
|
||||
wholeSize.width = this->step / (sizeof(_Tp) * chs);
|
||||
wholeSize.height = (this->dataend - this->datastart) / this->step;
|
||||
|
||||
ofs.y = (this->data - this->datastart) / this->step;
|
||||
ofs.x = ((this->data - this->datastart) - ((this->data - this->datastart) / this->step * this->step)) / (sizeof(_Tp) * chs);
|
||||
FBC_Assert(wholeSize.width >= 0 && wholeSize.height >= 0 && ofs.x >= 0 && ofs.y >= 0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void Mat_<_Tp, chs>::adjustROI(int dtop, int dbottom, int dleft, int dright)
|
||||
{
|
||||
Size wholeSize; Point ofs;
|
||||
size_t esz = elemSize();
|
||||
locateROI(wholeSize, ofs);
|
||||
|
||||
int row1 = std::max(ofs.y - dtop, 0);
|
||||
int row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
|
||||
int col1 = std::max(ofs.x - dleft, 0);
|
||||
int col2 = std::min(ofs.x + cols + dright, wholeSize.width);
|
||||
this->data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
|
||||
this->rows = row2 - row1;
|
||||
this->cols = col2 - col1;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
void Mat_<_Tp, chs>::setTo(const Scalar& _value)
|
||||
{
|
||||
for (int i = 0; i < this->rows; i++) {
|
||||
uchar* pRow = this->data + i * this->step;
|
||||
|
||||
for (int j = 0; j < this->cols; j++) {
|
||||
_Tp* pPixel = (_Tp*)pRow + j * chs;
|
||||
|
||||
for (int m = 0, n = 0; m < chs && n < 4; m++, n++) {
|
||||
pPixel[n] = saturate_cast<_Tp>(_value.val[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs> template<typename _Tp2>
|
||||
void Mat_<_Tp, chs>::convertTo(Mat_<_Tp2, chs>& _m, double alpha, const Scalar& scalar) const
|
||||
{
|
||||
FBC_Assert(this->channels <= 4);
|
||||
|
||||
bool noScale = fabs(alpha - 1) < DBL_EPSILON && fabs(scalar[0]) < DBL_EPSILON && fabs(scalar[1]) < DBL_EPSILON &&
|
||||
fabs(scalar[2]) < DBL_EPSILON && fabs(scalar[3]) < DBL_EPSILON;
|
||||
/*if ((typeid(_Tp).name() == typeid(_Tp2).name()) && noScale) {
|
||||
this->copyTo(_m);
|
||||
return;
|
||||
}*/
|
||||
|
||||
size_t size = this->rows * this->cols * this->channels * sizeof(_Tp2);
|
||||
|
||||
if (this->rows * this->cols != _m.rows * _m.cols) {
|
||||
if (_m.allocated == true) {
|
||||
fastFree(_m.data);
|
||||
}
|
||||
|
||||
uchar* p = (uchar*)fastMalloc(size);
|
||||
FBC_Assert(p != NULL);
|
||||
_m.data = p;
|
||||
_m.allocated = true;
|
||||
}
|
||||
|
||||
_m.channels = this->channels;
|
||||
_m.rows = this->rows;
|
||||
_m.cols = this->cols;
|
||||
_m.step = _m.cols * sizeof(_Tp2) * _m.channels;
|
||||
_m.datastart = _m.data;
|
||||
_m.dataend = _m.data + _m.step * _m.rows;
|
||||
|
||||
_Tp2 alpha_ = (_Tp2)alpha;
|
||||
Scalar_<_Tp2> scalar_;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
scalar_.val[i]= (_Tp2)scalar.val[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->rows; i++) {
|
||||
uchar* p1 = this->data + i * this->step;
|
||||
uchar* p2 = _m.data + i * _m.step;
|
||||
|
||||
for (int j = 0; j < this->cols; j++) {
|
||||
_Tp* p1_ = (_Tp*)p1 + j * chs;
|
||||
_Tp2* p2_ = (_Tp2*)p2 + j * chs;
|
||||
|
||||
for (int ch = 0; ch < chs; ch++) {
|
||||
p2_[ch] = saturate_cast<_Tp2>(p1_[ch] * alpha_ + scalar_.val[ch]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Mat_<_Tp, chs>& Mat_<_Tp, chs>::zeros(int _rows, int _cols)
|
||||
{
|
||||
this->rows = _rows;
|
||||
this->cols = _cols;
|
||||
this->channels = chs;
|
||||
this->step = sizeof(_Tp) * _cols * chs;
|
||||
this->allocated = true;
|
||||
|
||||
size_t size_ = this->rows * this->step;
|
||||
uchar* p = (uchar*)fastMalloc(size_);
|
||||
FBC_Assert(p != NULL);
|
||||
this->data = p;
|
||||
|
||||
memset(this->data, 0, size_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
Size Mat_<_Tp, chs>::size() const
|
||||
{
|
||||
return Size(this->cols, this->rows);
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
size_t Mat_<_Tp, chs>::elemSize() const
|
||||
{
|
||||
return (this->channels * sizeof(_Tp));
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
size_t Mat_<_Tp, chs>::elemSize1() const
|
||||
{
|
||||
return sizeof(_Tp);
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
size_t Mat_<_Tp, chs>::total() const
|
||||
{
|
||||
return (size_t)rows * cols;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
bool Mat_<_Tp, chs>::empty() const
|
||||
{
|
||||
return total() == 0 || this->data == NULL;
|
||||
}
|
||||
|
||||
/////////////////////////// Mat_ out-of-class operators ///////////////////////////
|
||||
template<typename _Tp1, typename _Tp2, int chs> static inline
|
||||
Mat_<_Tp1, chs>& operator -= (Mat_<_Tp1, chs>& a, const Mat_<_Tp2, chs>& b)
|
||||
{
|
||||
FBC_Assert(a.rows == b.rows && a.cols == b.cols);
|
||||
|
||||
for (int y = 0; y < a.rows; y++) {
|
||||
_Tp1* pa = (_Tp1*)a.ptr(y);
|
||||
_Tp2* pb = (_Tp2*)b.ptr(y);
|
||||
|
||||
for (int x = 0; x < a.cols * chs; x++) {
|
||||
pa[x] = saturate_cast<_Tp1>(pa[x] - pb[x]);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int chs> static inline
|
||||
Mat_<_Tp1, chs>& operator += (Mat_<_Tp1, chs>& a, const Mat_<_Tp2, chs>& b)
|
||||
{
|
||||
FBC_Assert(a.rows == b.rows && a.cols == b.cols);
|
||||
|
||||
for (int y = 0; y < a.rows; y++) {
|
||||
_Tp1* pa = (_Tp1*)a.ptr(y);
|
||||
_Tp2* pb = (_Tp2*)b.ptr(y);
|
||||
|
||||
for (int x = 0; x < a.cols * chs; x++) {
|
||||
pa[x] = saturate_cast<_Tp1>(pa[x] + pb[x]);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int chs> static inline
|
||||
Mat_<_Tp1, chs> operator - (const Mat_<_Tp1, chs>& a, const Mat_<_Tp2, chs>& b)
|
||||
{
|
||||
FBC_Assert(a.rows == b.rows && a.cols == b.cols);
|
||||
Mat_<_Tp1, chs> c(a.rows, a.cols);
|
||||
|
||||
for (int y = 0; y < a.rows; y++) {
|
||||
_Tp1* pa = (_Tp1*)a.ptr(y);
|
||||
_Tp2* pb = (_Tp2*)b.ptr(y);
|
||||
_Tp1* pc = (_Tp1*)c.ptr(y);
|
||||
|
||||
for (int x = 0; x < a.cols * chs; x++) {
|
||||
pc[x] = saturate_cast<_Tp1>(pa[x] - pb[x]);
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int chs> static inline
|
||||
Mat_<_Tp1, chs> operator == (const Mat_<_Tp1, chs>& a, const Mat_<_Tp2, chs>& b)
|
||||
{
|
||||
FBC_Assert(a.rows == b.rows && a.cols == b.cols);
|
||||
Mat_<_Tp1, chs> c(a.rows, a.cols);
|
||||
|
||||
for (int y = 0; y < a.rows; y++) {
|
||||
_Tp1* pa = (_Tp1*)a.ptr(y);
|
||||
_Tp2* pb = (_Tp2*)b.ptr(y);
|
||||
_Tp1* pc = (_Tp1*)c.ptr(y);
|
||||
|
||||
for (int x = 0; x < a.cols * chs; x++) {
|
||||
pc[x] = pa[x] != pb[x] ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs> static inline
|
||||
Mat_<_Tp, chs> operator & (const Mat_<_Tp, chs>& a, const Mat_<_Tp, chs>& b)
|
||||
{
|
||||
FBC_Assert(a.rows == b.rows && a.cols == b.cols);
|
||||
Mat_<_Tp, chs> c(a.rows, a.cols);
|
||||
|
||||
for (int y = 0; y < a.rows; y++) {
|
||||
_Tp* pa = (_Tp*)a.ptr(y);
|
||||
_Tp* pb = (_Tp*)b.ptr(y);
|
||||
_Tp* pc = (_Tp*)c.ptr(y);
|
||||
|
||||
for (int x = 0; x < a.cols * chs; x++) {
|
||||
pc[x] = pa[x] & pb[x];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
} // yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_MAT_HPP_
|
||||
@@ -0,0 +1,667 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_MATHFUNCS_HPP_
|
||||
#define FBC_CV_CORE_MATHFUNCS_HPP_
|
||||
|
||||
/* reference: include/opencv2/core.hpp
|
||||
modules/core/src/mathfuncs.cpp
|
||||
modules/core/src/mathfuncs_core.cpp
|
||||
*/
|
||||
|
||||
#include "mat.hpp"
|
||||
#include "NAryMatIterator.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
// calculates the magnitude of 2D vectors formed from the corresponding elements of x and y arrays
|
||||
// \f[\texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2}\f]
|
||||
// support type: float/double, multi-channels
|
||||
// template <typename _Tp, int chs>
|
||||
// int magnitude(const Mat_<_Tp, chs>& src1, const Mat_<_Tp, chs>& src2, Mat_<_Tp, chs>& dst)
|
||||
// {
|
||||
// FBC_Assert(typeid(float).name() == typeid(_Tp).name() || typeid(double).name() == typeid(_Tp).name());
|
||||
// FBC_Assert(src1.size() == src2.size());
|
||||
|
||||
// if (dst.empty()) {
|
||||
// dst = Mat_<_Tp, chs>(src1.rows, src1.cols);
|
||||
// } else {
|
||||
// FBC_Assert(src1.size() == dst.size());
|
||||
// }
|
||||
|
||||
// for (int y = 0; y < src1.rows; y++) {
|
||||
// const _Tp* pRowSrc1 = (const _Tp*)src1.ptr(y);
|
||||
// const _Tp* pRowSrc2 = (const _Tp*)src2.ptr(y);
|
||||
// _Tp* pRowDst = (_Tp*)dst.ptr(y);
|
||||
|
||||
// for (int x = 0; x < src1.cols; x++) {
|
||||
// pRowDst[x] = std::sqrt(pRowSrc1[x] * pRowSrc1[x] + pRowSrc2[x] * pRowSrc2[x]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
/////////////////////////////////////////// LOG ///////////////////////////////////////
|
||||
// #define LOGTAB_SCALE 8
|
||||
// #define LOGTAB_MASK ((1 << LOGTAB_SCALE) - 1)
|
||||
// #define LOGTAB_MASK2 ((1 << (20 - LOGTAB_SCALE)) - 1)
|
||||
// #define LOGTAB_MASK2_32F ((1 << (23 - LOGTAB_SCALE)) - 1)
|
||||
|
||||
// static const double FBC_DECL_ALIGNED(16) ifbcLogTab[] = {
|
||||
// 0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000,
|
||||
// .00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420,
|
||||
// .00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760,
|
||||
// .01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884,
|
||||
// .01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846,
|
||||
// .01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877,
|
||||
// .02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084,
|
||||
// .02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498,
|
||||
// .03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697,
|
||||
// .03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906,
|
||||
// .03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624,
|
||||
// .04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509,
|
||||
// .04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239,
|
||||
// .04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234,
|
||||
// .05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481,
|
||||
// .05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465,
|
||||
// .06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647,
|
||||
// .06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377,
|
||||
// .06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657,
|
||||
// .07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909,
|
||||
// .07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971,
|
||||
// .07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856,
|
||||
// .08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201,
|
||||
// .08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240,
|
||||
// .08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143,
|
||||
// .09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470,
|
||||
// .09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035,
|
||||
// .10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484,
|
||||
// .10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141,
|
||||
// .10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982,
|
||||
// .11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951,
|
||||
// .11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627,
|
||||
// .11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889,
|
||||
// .12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962,
|
||||
// .12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690,
|
||||
// .12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024,
|
||||
// .13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233,
|
||||
// .13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031,
|
||||
// .13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422,
|
||||
// .14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983,
|
||||
// .14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649,
|
||||
// .14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620,
|
||||
// .15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201,
|
||||
// .15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127,
|
||||
// .15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333,
|
||||
// .16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365,
|
||||
// .16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536,
|
||||
// .16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449,
|
||||
// .17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421,
|
||||
// .17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377,
|
||||
// .17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131,
|
||||
// .18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440,
|
||||
// .18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312,
|
||||
// .18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479,
|
||||
// .19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516,
|
||||
// .19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087,
|
||||
// .19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205,
|
||||
// .20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441,
|
||||
// .20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032,
|
||||
// .20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127,
|
||||
// .21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848,
|
||||
// .21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817,
|
||||
// .21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088,
|
||||
// .22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991,
|
||||
// .22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000,
|
||||
// .22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611,
|
||||
// .22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689,
|
||||
// .23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808,
|
||||
// .23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901,
|
||||
// .23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077,
|
||||
// .24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387,
|
||||
// .24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544,
|
||||
// .24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049,
|
||||
// .25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888,
|
||||
// .25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758,
|
||||
// .25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106,
|
||||
// .25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819,
|
||||
// .26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688,
|
||||
// .26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491,
|
||||
// .26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791,
|
||||
// .27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619,
|
||||
// .27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196,
|
||||
// .27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112,
|
||||
// .28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985,
|
||||
// .28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118,
|
||||
// .28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378,
|
||||
// .28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485,
|
||||
// .29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504,
|
||||
// .29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070,
|
||||
// .29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377,
|
||||
// .30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746,
|
||||
// .30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308,
|
||||
// .30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908,
|
||||
// .30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908,
|
||||
// .31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714,
|
||||
// .31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293,
|
||||
// .31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273,
|
||||
// .32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246,
|
||||
// .32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486,
|
||||
// .32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113,
|
||||
// .32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382,
|
||||
// .33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112,
|
||||
// .33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095,
|
||||
// .33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412,
|
||||
// .34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111,
|
||||
// .34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197,
|
||||
// .34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017,
|
||||
// .34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325,
|
||||
// .35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033,
|
||||
// .35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986,
|
||||
// .35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814,
|
||||
// .36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978,
|
||||
// .36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478,
|
||||
// .36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377,
|
||||
// .36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919,
|
||||
// .37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504,
|
||||
// .37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430,
|
||||
// .37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158,
|
||||
// .37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198,
|
||||
// .38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667,
|
||||
// .38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277,
|
||||
// .38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377,
|
||||
// .38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772,
|
||||
// .39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686,
|
||||
// .39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737,
|
||||
// .39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026,
|
||||
// .40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084,
|
||||
// .40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230,
|
||||
// .40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667,
|
||||
// .40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649,
|
||||
// .41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544,
|
||||
// .41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173,
|
||||
// .41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268,
|
||||
// .41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298,
|
||||
// .42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564,
|
||||
// .42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450,
|
||||
// .42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816,
|
||||
// .42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056,
|
||||
// .43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162,
|
||||
// .43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278,
|
||||
// .43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465,
|
||||
// .43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305,
|
||||
// .44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794,
|
||||
// .44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416,
|
||||
// .44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000,
|
||||
// .44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805,
|
||||
// .45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159,
|
||||
// .45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320,
|
||||
// .45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337,
|
||||
// .45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321,
|
||||
// .46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064,
|
||||
// .46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290,
|
||||
// .46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098,
|
||||
// .46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511,
|
||||
// .47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439,
|
||||
// .47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105,
|
||||
// .47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359,
|
||||
// .47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131,
|
||||
// .48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314,
|
||||
// .48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855,
|
||||
// .48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154,
|
||||
// .48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801,
|
||||
// .49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124,
|
||||
// .49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487,
|
||||
// .49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095,
|
||||
// .49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420,
|
||||
// .49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711,
|
||||
// .50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690,
|
||||
// .50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566,
|
||||
// .50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294,
|
||||
// .50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094,
|
||||
// .51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126,
|
||||
// .51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458,
|
||||
// .51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967,
|
||||
// .51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256,
|
||||
// .52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705,
|
||||
// .52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926,
|
||||
// .52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617,
|
||||
// .52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512,
|
||||
// .53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126,
|
||||
// .53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908,
|
||||
// .53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771,
|
||||
// .53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489,
|
||||
// .53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695,
|
||||
// .54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818,
|
||||
// .54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948,
|
||||
// .54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321,
|
||||
// .54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084,
|
||||
// .55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766,
|
||||
// .55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506,
|
||||
// .55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960,
|
||||
// .55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801,
|
||||
// .55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714,
|
||||
// .56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590,
|
||||
// .56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889,
|
||||
// .56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945,
|
||||
// .56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239,
|
||||
// .57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691,
|
||||
// .57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502,
|
||||
// .57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626,
|
||||
// .57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614,
|
||||
// .57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094,
|
||||
// .58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310,
|
||||
// .58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754,
|
||||
// .58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783,
|
||||
// .58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397,
|
||||
// .59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541,
|
||||
// .59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395,
|
||||
// .59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931,
|
||||
// .59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344,
|
||||
// .59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811,
|
||||
// .60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338,
|
||||
// .60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470,
|
||||
// .60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279,
|
||||
// .60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021,
|
||||
// .60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021,
|
||||
// .61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864,
|
||||
// .61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505,
|
||||
// .61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565,
|
||||
// .61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789,
|
||||
// .62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084,
|
||||
// .62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725,
|
||||
// .62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556,
|
||||
// .62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234,
|
||||
// .62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333,
|
||||
// .63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322,
|
||||
// .63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320,
|
||||
// .63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126,
|
||||
// .63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744,
|
||||
// .63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814,
|
||||
// .64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934,
|
||||
// .64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961,
|
||||
// .64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361,
|
||||
// .64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591,
|
||||
// .64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653,
|
||||
// .65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762,
|
||||
// .65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033,
|
||||
// .65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288,
|
||||
// .65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182,
|
||||
// .65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172,
|
||||
// .66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323,
|
||||
// .66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080,
|
||||
// .66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213,
|
||||
// .66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547,
|
||||
// .66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000,
|
||||
// .67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661,
|
||||
// .67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450,
|
||||
// .67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489,
|
||||
// .67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079,
|
||||
// .67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069,
|
||||
// .68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711,
|
||||
// .68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742,
|
||||
// .68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520,
|
||||
// .68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220,
|
||||
// .68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078,
|
||||
// .69314718055994530941723212145818, 5.0e-01,
|
||||
// };
|
||||
|
||||
// #define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*ifbcLogTab[(h)+1])
|
||||
// static const double ln_2 = 0.69314718055994530941723212145818;
|
||||
|
||||
// typedef union
|
||||
// {
|
||||
// struct {
|
||||
// int lo;
|
||||
// int hi;
|
||||
// } i;
|
||||
// double d;
|
||||
// } DBLINT;
|
||||
|
||||
// template<typename dump> static void Log_32f(const float *_x, float *y, int n)
|
||||
// {
|
||||
// static const float shift[] = { 0, -1.f / 512 };
|
||||
// static const float
|
||||
// A0 = 0.3333333333333333333333333f,
|
||||
// A1 = -0.5f,
|
||||
// A2 = 1.f;
|
||||
|
||||
// #undef LOGPOLY
|
||||
// #define LOGPOLY(x) (((A0*(x) + A1)*(x) + A2)*(x))
|
||||
|
||||
// int i = 0;
|
||||
// Cv32suf buf[4];
|
||||
// const int* x = (const int*)_x;
|
||||
|
||||
// for (; i <= n - 4; i += 4) {
|
||||
// double x0, x1, x2, x3;
|
||||
// double y0, y1, y2, y3;
|
||||
// int h0, h1, h2, h3;
|
||||
|
||||
// h0 = x[i];
|
||||
// h1 = x[i + 1];
|
||||
// buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23);
|
||||
// buf[1].i = (h1 & LOGTAB_MASK2_32F) | (127 << 23);
|
||||
|
||||
// y0 = (((h0 >> 23) & 0xff) - 127) * ln_2;
|
||||
// y1 = (((h1 >> 23) & 0xff) - 127) * ln_2;
|
||||
|
||||
// h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
// h1 = (h1 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y0 += ifbcLogTab[h0];
|
||||
// y1 += ifbcLogTab[h1];
|
||||
|
||||
// h2 = x[i + 2];
|
||||
// h3 = x[i + 3];
|
||||
|
||||
// x0 = LOGTAB_TRANSLATE(buf[0].f, h0);
|
||||
// x1 = LOGTAB_TRANSLATE(buf[1].f, h1);
|
||||
|
||||
// buf[2].i = (h2 & LOGTAB_MASK2_32F) | (127 << 23);
|
||||
// buf[3].i = (h3 & LOGTAB_MASK2_32F) | (127 << 23);
|
||||
|
||||
// y2 = (((h2 >> 23) & 0xff) - 127) * ln_2;
|
||||
// y3 = (((h3 >> 23) & 0xff) - 127) * ln_2;
|
||||
|
||||
// h2 = (h2 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
// h3 = (h3 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y2 += ifbcLogTab[h2];
|
||||
// y3 += ifbcLogTab[h3];
|
||||
|
||||
// x2 = LOGTAB_TRANSLATE(buf[2].f, h2);
|
||||
// x3 = LOGTAB_TRANSLATE(buf[3].f, h3);
|
||||
|
||||
// x0 += shift[h0 == 510];
|
||||
// x1 += shift[h1 == 510];
|
||||
// y0 += LOGPOLY(x0);
|
||||
// y1 += LOGPOLY(x1);
|
||||
|
||||
// y[i] = (float)y0;
|
||||
// y[i + 1] = (float)y1;
|
||||
|
||||
// x2 += shift[h2 == 510];
|
||||
// x3 += shift[h3 == 510];
|
||||
// y2 += LOGPOLY(x2);
|
||||
// y3 += LOGPOLY(x3);
|
||||
|
||||
// y[i + 2] = (float)y2;
|
||||
// y[i + 3] = (float)y3;
|
||||
// }
|
||||
|
||||
// for (; i < n; i++) {
|
||||
// int h0 = x[i];
|
||||
// double y0;
|
||||
// float x0;
|
||||
|
||||
// y0 = (((h0 >> 23) & 0xff) - 127) * ln_2;
|
||||
|
||||
// buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23);
|
||||
// h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y0 += ifbcLogTab[h0];
|
||||
// x0 = (float)LOGTAB_TRANSLATE(buf[0].f, h0);
|
||||
// x0 += shift[h0 == 510];
|
||||
// y0 += LOGPOLY(x0);
|
||||
|
||||
// y[i] = (float)y0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// template<typename dump> static void Log_64f(const double *x, double *y, int n)
|
||||
// {
|
||||
// static const double shift[] = { 0, -1. / 512 };
|
||||
// static const double
|
||||
// A7 = 1.0,
|
||||
// A6 = -0.5,
|
||||
// A5 = 0.333333333333333314829616256247390992939472198486328125,
|
||||
// A4 = -0.25,
|
||||
// A3 = 0.2,
|
||||
// A2 = -0.1666666666666666574148081281236954964697360992431640625,
|
||||
// A1 = 0.1428571428571428769682682968777953647077083587646484375,
|
||||
// A0 = -0.125;
|
||||
|
||||
// #undef LOGPOLY
|
||||
// #define LOGPOLY(x,k) ((x)+=shift[k], xq = (x)*(x),\
|
||||
// (((A0*xq + A2)*xq + A4)*xq + A6)*xq + \
|
||||
// (((A1*xq + A3)*xq + A5)*xq + A7)*(x))
|
||||
|
||||
// int i = 0;
|
||||
// DBLINT buf[4];
|
||||
// DBLINT *X = (DBLINT *)x;
|
||||
|
||||
// for (; i <= n - 4; i += 4) {
|
||||
// double xq;
|
||||
// double x0, x1, x2, x3;
|
||||
// double y0, y1, y2, y3;
|
||||
// int h0, h1, h2, h3;
|
||||
|
||||
// h0 = X[i].i.lo;
|
||||
// h1 = X[i + 1].i.lo;
|
||||
// buf[0].i.lo = h0;
|
||||
// buf[1].i.lo = h1;
|
||||
|
||||
// h0 = X[i].i.hi;
|
||||
// h1 = X[i + 1].i.hi;
|
||||
// buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20);
|
||||
// buf[1].i.hi = (h1 & LOGTAB_MASK2) | (1023 << 20);
|
||||
|
||||
// y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2;
|
||||
// y1 = (((h1 >> 20) & 0x7ff) - 1023) * ln_2;
|
||||
|
||||
// h2 = X[i + 2].i.lo;
|
||||
// h3 = X[i + 3].i.lo;
|
||||
// buf[2].i.lo = h2;
|
||||
// buf[3].i.lo = h3;
|
||||
|
||||
// h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
// h1 = (h1 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y0 += ifbcLogTab[h0];
|
||||
// y1 += ifbcLogTab[h1];
|
||||
|
||||
// h2 = X[i + 2].i.hi;
|
||||
// h3 = X[i + 3].i.hi;
|
||||
|
||||
// x0 = LOGTAB_TRANSLATE(buf[0].d, h0);
|
||||
// x1 = LOGTAB_TRANSLATE(buf[1].d, h1);
|
||||
|
||||
// buf[2].i.hi = (h2 & LOGTAB_MASK2) | (1023 << 20);
|
||||
// buf[3].i.hi = (h3 & LOGTAB_MASK2) | (1023 << 20);
|
||||
|
||||
// y2 = (((h2 >> 20) & 0x7ff) - 1023) * ln_2;
|
||||
// y3 = (((h3 >> 20) & 0x7ff) - 1023) * ln_2;
|
||||
|
||||
// h2 = (h2 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
// h3 = (h3 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y2 += ifbcLogTab[h2];
|
||||
// y3 += ifbcLogTab[h3];
|
||||
|
||||
// x2 = LOGTAB_TRANSLATE(buf[2].d, h2);
|
||||
// x3 = LOGTAB_TRANSLATE(buf[3].d, h3);
|
||||
|
||||
// y0 += LOGPOLY(x0, h0 == 510);
|
||||
// y1 += LOGPOLY(x1, h1 == 510);
|
||||
|
||||
// y[i] = y0;
|
||||
// y[i + 1] = y1;
|
||||
|
||||
// y2 += LOGPOLY(x2, h2 == 510);
|
||||
// y3 += LOGPOLY(x3, h3 == 510);
|
||||
|
||||
// y[i + 2] = y2;
|
||||
// y[i + 3] = y3;
|
||||
// }
|
||||
|
||||
// for (; i < n; i++) {
|
||||
// int h0 = X[i].i.hi;
|
||||
// double xq;
|
||||
// double x0, y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2;
|
||||
|
||||
// buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20);
|
||||
// buf[0].i.lo = X[i].i.lo;
|
||||
// h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
|
||||
|
||||
// y0 += ifbcLogTab[h0];
|
||||
// x0 = LOGTAB_TRANSLATE(buf[0].d, h0);
|
||||
// y0 += LOGPOLY(x0, h0 == 510);
|
||||
// y[i] = y0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // calculates the natural logarithm of the absolute value of every element of the input array
|
||||
// // \f[\texttt{dst} (I) = \fork{\log |\texttt{src}(I)|}{if \(\texttt{src}(I) \ne 0\) }{\texttt{C}}{otherwise}\f]
|
||||
// // support type: float/double, multi-channels
|
||||
// template <typename _Tp, int chs>
|
||||
// int log(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst)
|
||||
// {
|
||||
// FBC_Assert(typeid(float).name() == typeid(_Tp).name() || typeid(double).name() == typeid(_Tp).name());
|
||||
// if (dst.empty()) {
|
||||
// dst = Mat_<_Tp, chs>(src.rows, src.cols);
|
||||
// } else {
|
||||
// FBC_Assert(src.size() == dst.size());
|
||||
// }
|
||||
|
||||
// if (src.isContinuous() == false || dst.isContinuous() == false) {
|
||||
// fprintf(stderr, "Error: src and dst must be continuous\n");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// const Mat_<_Tp, chs>* arrays[] = { &src, &dst, 0 };
|
||||
// uchar* ptrs[2];
|
||||
// ptrs[0] = src.data;
|
||||
// ptrs[1] = dst.data;
|
||||
|
||||
// int len = (int)(src.rows * src.cols *chs);
|
||||
|
||||
// if (sizeof(_Tp) == 4) { // floal
|
||||
// Log_32f<dump>((const float*)ptrs[0], (float*)ptrs[1], len);
|
||||
// } else { // double
|
||||
// Log_64f<dump>((const double*)ptrs[0], (double*)ptrs[1], len);
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// find the minimum and maximum element values and their positions
|
||||
//// support type: single-channel
|
||||
template<typename _Tp, int chs>
|
||||
int minMaxLoc(const Mat_<_Tp, chs>& _img, double* minVal, double* maxVal = 0, Point* minLoc = 0, Point* maxLoc = 0, const Mat_<uchar, 1>& mask = Mat_<uchar, 1>())
|
||||
{
|
||||
FBC_Assert(chs == 1);
|
||||
if (!mask.empty()) {
|
||||
FBC_Assert(_img.rows == mask.rows && _img.cols == mask.cols);
|
||||
}
|
||||
|
||||
double minVal_ = INT_MAX;
|
||||
double maxVal_ = INT_MIN;
|
||||
Point minLoc_ = Point(-1, -1);
|
||||
Point maxLoc_ = Point(-1, -1);
|
||||
|
||||
if (mask.empty()) {
|
||||
for (int y = 0; y < _img.rows; y++) {
|
||||
_Tp* p = (_Tp*)_img.ptr(y);
|
||||
|
||||
for (int x = 0; x < _img.cols; x++) {
|
||||
if (p[x] > maxVal_) {
|
||||
maxVal_ = p[x];
|
||||
maxLoc_.x = x;
|
||||
maxLoc_.y = y;
|
||||
}
|
||||
|
||||
if (p[x] < minVal_) {
|
||||
minVal_ = p[x];
|
||||
minLoc_.x = x;
|
||||
minLoc_.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < _img.rows; y++) {
|
||||
_Tp* p1 = (_Tp*)_img.ptr(y);
|
||||
const uchar* p2 = mask.ptr(y);
|
||||
|
||||
for (int x = 0; x < _img.cols; x++) {
|
||||
if (p2[x] && p1[x] > maxVal_) {
|
||||
maxVal_ = p1[x];
|
||||
maxLoc_.x = x;
|
||||
maxLoc_.y = y;
|
||||
}
|
||||
|
||||
if (p2[x] && p1[x] < minVal_) {
|
||||
minVal_ = p1[x];
|
||||
minLoc_.x = x;
|
||||
minLoc_.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*minVal = minVal_;
|
||||
if (maxVal) *maxVal = maxVal_;
|
||||
if (minLoc) *minLoc = minLoc_;
|
||||
if (maxLoc) *maxLoc = maxLoc_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Normalizes the norm or value range of an array
|
||||
/* \f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f]
|
||||
(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that
|
||||
\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f] */
|
||||
// support type: float/double, multi-channels
|
||||
template<typename _Tp1, typename _Tp2, int chs>
|
||||
int normalize(const Mat_<_Tp1, chs>& _src, Mat_<_Tp2, chs>& _dst, double a = 1, double b = 0, int norm_type = NORM_L2, const Mat_<uchar, 1>& _mask = Mat_<uchar, 1>())
|
||||
{
|
||||
//FBC_Assert(typeid(float).name() == typeid(_Tp).name() || typeid(double).name() == typeid(_Tp).name());
|
||||
if (_dst.empty()) {
|
||||
_dst = Mat_<_Tp2, chs>(_src.rows, _src.cols);
|
||||
} else {
|
||||
FBC_Assert(_src.size() == _dst.size());
|
||||
}
|
||||
|
||||
double scale = 1, shift = 0;
|
||||
if (norm_type == FBC_MINMAX) {
|
||||
double smin = 0, smax = 0;
|
||||
double dmin = MIN(a, b), dmax = MAX(a, b);
|
||||
minMaxLoc(_src, &smin, &smax, 0, 0, _mask);
|
||||
scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1. / (smax - smin) : 0);
|
||||
shift = dmin - smin*scale;
|
||||
} else if (norm_type == FBC_L2 || norm_type == FBC_L1 || norm_type == FBC_C) {
|
||||
fprintf(stderr, "Error: normalize norm no impl\n");
|
||||
FBC_Assert(0); // TODO
|
||||
/*scale = norm(_src, norm_type, _mask);
|
||||
scale = scale > DBL_EPSILON ? a / scale : 0.;
|
||||
shift = 0;*/
|
||||
} else {
|
||||
FBC_Error("Unknown/unsupported norm type");
|
||||
}
|
||||
|
||||
Scalar scalar = Scalar::all(shift);
|
||||
if (_mask.empty()) {
|
||||
_src.convertTo(_dst, scale, scalar);
|
||||
} else {
|
||||
Mat_<_Tp2, chs> tmp;
|
||||
_src.convertTo(tmp, scale, scalar);
|
||||
|
||||
for (int y = 0; y < _dst.rows; y++) {
|
||||
_Tp2* p1 = (_Tp2*)_dst.ptr(y);
|
||||
const _Tp2* p2 = (_Tp2*)tmp.ptr(y);
|
||||
const uchar* p3 = _mask.ptr(y);
|
||||
|
||||
for (int x = 0; x < _dst.cols; x++) {
|
||||
if (p3[x] != 0) {
|
||||
p1[x] = p2[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_MATHFUNCS_HPP_
|
||||
@@ -0,0 +1,851 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_MATX_HPP_
|
||||
#define FBC_CV_CORE_MATX_HPP_
|
||||
|
||||
// reference: include/opencv2/core/matx.hpp
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error matx.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
#include "base.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "saturate.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
////////////////////////////// Small Matrix ///////////////////////////
|
||||
// Template class for small matrices whose type and size are known at compilation time
|
||||
template<typename _Tp, int m, int n> class Matx {
|
||||
public:
|
||||
enum {
|
||||
rows = m,
|
||||
cols = n,
|
||||
channels = rows*cols,
|
||||
shortdim = (m < n ? m : n)
|
||||
};
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef Matx<_Tp, m, n> mat_type;
|
||||
typedef Matx<_Tp, shortdim, 1> diag_type;
|
||||
|
||||
//! default constructor
|
||||
Matx();
|
||||
|
||||
Matx(_Tp v0); //!< 1x1 matrix
|
||||
Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
|
||||
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
|
||||
explicit Matx(const _Tp* vals); //!< initialize from a plain array
|
||||
|
||||
static Matx all(_Tp alpha);
|
||||
static Matx zeros();
|
||||
static Matx ones();
|
||||
static Matx eye();
|
||||
static Matx diag(const diag_type& d);
|
||||
|
||||
//! dot product computed with the default precision
|
||||
_Tp dot(const Matx<_Tp, m, n>& v) const;
|
||||
|
||||
//! dot product computed in double-precision arithmetics
|
||||
double ddot(const Matx<_Tp, m, n>& v) const;
|
||||
|
||||
//! conversion to another data type
|
||||
template<typename T2> operator Matx<T2, m, n>() const;
|
||||
|
||||
//! change the matrix shape
|
||||
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
|
||||
|
||||
//! extract part of the matrix
|
||||
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
|
||||
|
||||
//! extract the matrix row
|
||||
Matx<_Tp, 1, n> row(int i) const;
|
||||
|
||||
//! extract the matrix column
|
||||
Matx<_Tp, m, 1> col(int i) const;
|
||||
|
||||
//! extract the matrix diagonal
|
||||
diag_type diag() const;
|
||||
|
||||
//! element access
|
||||
const _Tp& operator ()(int i, int j) const;
|
||||
_Tp& operator ()(int i, int j);
|
||||
|
||||
//! 1D element access
|
||||
const _Tp& operator ()(int i) const;
|
||||
_Tp& operator ()(int i);
|
||||
|
||||
_Tp val[m*n]; //< matrix elements
|
||||
};
|
||||
|
||||
typedef Matx<float, 1, 2> Matx12f;
|
||||
typedef Matx<double, 1, 2> Matx12d;
|
||||
typedef Matx<float, 1, 3> Matx13f;
|
||||
typedef Matx<double, 1, 3> Matx13d;
|
||||
typedef Matx<float, 1, 4> Matx14f;
|
||||
typedef Matx<double, 1, 4> Matx14d;
|
||||
typedef Matx<float, 1, 6> Matx16f;
|
||||
typedef Matx<double, 1, 6> Matx16d;
|
||||
|
||||
typedef Matx<float, 2, 1> Matx21f;
|
||||
typedef Matx<double, 2, 1> Matx21d;
|
||||
typedef Matx<float, 3, 1> Matx31f;
|
||||
typedef Matx<double, 3, 1> Matx31d;
|
||||
typedef Matx<float, 4, 1> Matx41f;
|
||||
typedef Matx<double, 4, 1> Matx41d;
|
||||
typedef Matx<float, 6, 1> Matx61f;
|
||||
typedef Matx<double, 6, 1> Matx61d;
|
||||
|
||||
typedef Matx<float, 2, 2> Matx22f;
|
||||
typedef Matx<double, 2, 2> Matx22d;
|
||||
typedef Matx<float, 2, 3> Matx23f;
|
||||
typedef Matx<double, 2, 3> Matx23d;
|
||||
typedef Matx<float, 3, 2> Matx32f;
|
||||
typedef Matx<double, 3, 2> Matx32d;
|
||||
|
||||
typedef Matx<float, 3, 3> Matx33f;
|
||||
typedef Matx<double, 3, 3> Matx33d;
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx()
|
||||
{
|
||||
for (int i = 0; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0)
|
||||
{
|
||||
val[0] = v0;
|
||||
for (int i = 1; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 2, "Matx should have at least 2 elements.");
|
||||
val[0] = v0; val[1] = v1;
|
||||
for (int i = 2; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 3, "Matx should have at least 3 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2;
|
||||
for (int i = 3; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 4, "Matx should have at least 4 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
|
||||
for (int i = 4; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 5, "Matx should have at least 5 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
|
||||
for (int i = 5; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 6, "Matx should have at least 6 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
|
||||
val[4] = v4; val[5] = v5;
|
||||
for (int i = 6; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 7, "Matx should have at least 7 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
|
||||
val[4] = v4; val[5] = v5; val[6] = v6;
|
||||
for (int i = 7; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 8, "Matx should have at least 8 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
|
||||
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
|
||||
for (int i = 8; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
|
||||
{
|
||||
FBC_StaticAssert(channels >= 9, "Matx should have at least 9 elements.");
|
||||
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
|
||||
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
|
||||
val[8] = v8;
|
||||
for (int i = 9; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(const _Tp* values)
|
||||
{
|
||||
for (int i = 0; i < channels; i++) val[i] = values[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++) M.val[i] = alpha;
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::zeros()
|
||||
{
|
||||
return all(0);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::ones()
|
||||
{
|
||||
return all(1);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::eye()
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < shortdim; i++)
|
||||
M(i, i) = 1;
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::diag(const typename Matx<_Tp, m, n>::diag_type& d)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < shortdim; i++)
|
||||
M(i, i) = d(i, 0);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
|
||||
{
|
||||
_Tp s = 0;
|
||||
for (int i = 0; i < channels; i++) s += val[i] * M.val[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
|
||||
{
|
||||
double s = 0;
|
||||
for (int i = 0; i < channels; i++) s += (double)val[i] * M.val[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> template<typename T2>
|
||||
inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
|
||||
{
|
||||
Matx<T2, m, n> M;
|
||||
for (int i = 0; i < m*n; i++) M.val[i] = saturate_cast<T2>(val[i]);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> template<int m1, int n1> inline
|
||||
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
|
||||
{
|
||||
FBC_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements");
|
||||
return (const Matx<_Tp, m1, n1>&)*this;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n>
|
||||
template<int m1, int n1> inline
|
||||
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
|
||||
{
|
||||
FBC_Assert(0 <= i && i + m1 <= m && 0 <= j && j + n1 <= n);
|
||||
Matx<_Tp, m1, n1> s;
|
||||
for (int di = 0; di < m1; di++)
|
||||
for (int dj = 0; dj < n1; dj++)
|
||||
s(di, dj) = (*this)(i + di, j + dj);
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)m);
|
||||
return Matx<_Tp, 1, n>(&val[i*n]);
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
|
||||
{
|
||||
FBC_Assert((unsigned)j < (unsigned)n);
|
||||
Matx<_Tp, m, 1> v;
|
||||
for (int i = 0; i < m; i++)
|
||||
v.val[i] = val[i*n + j];
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
|
||||
{
|
||||
diag_type d;
|
||||
for (int i = 0; i < shortdim; i++)
|
||||
d.val[i] = val[i*n + i];
|
||||
return d;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n);
|
||||
return this->val[i*n + j];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n);
|
||||
return val[i*n + j];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
|
||||
{
|
||||
FBC_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
|
||||
FBC_Assert((unsigned)i < (unsigned)(m + n - 1));
|
||||
return val[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
_Tp& Matx<_Tp, m, n>::operator ()(int i)
|
||||
{
|
||||
FBC_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
|
||||
FBC_Assert((unsigned)i < (unsigned)(m + n - 1));
|
||||
return val[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
double norm(const Matx<_Tp, m, n>& M)
|
||||
{
|
||||
return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n));
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
double norm(const Matx<_Tp, m, n>& M, int normType)
|
||||
{
|
||||
switch (normType) {
|
||||
case NORM_INF:
|
||||
return (double)normInf<_Tp, _Tp>(M.val, m*n);
|
||||
case NORM_L1:
|
||||
return (double)normL1<_Tp, _Tp>(M.val, m*n);
|
||||
case NORM_L2SQR:
|
||||
return (double)normL2Sqr<_Tp, _Tp>(M.val, m*n);
|
||||
default:
|
||||
case NORM_L2:
|
||||
return std::sqrt((double)normL2Sqr<_Tp, _Tp>(M.val, m*n));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////// Matx out-of-class operators ////////////////////////////////
|
||||
template<typename _Tp1, typename _Tp2, int m, int n> static inline
|
||||
Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int m, int n> static inline
|
||||
Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m*n; i++)
|
||||
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n, int l> static inline
|
||||
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
|
||||
{
|
||||
Matx<_Tp, m, n> M;
|
||||
for (int i = 0; i < m; i++)
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
_Tp s = 0;
|
||||
for (int k = 0; k < l; k++)
|
||||
s += a(i, k) * b(k, j);
|
||||
M.val[i*n + j] = s;
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
|
||||
{
|
||||
for (int i = 0; i < m*n; i++)
|
||||
if (a.val[i] != b.val[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> static inline
|
||||
bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
///////////////////////////////////////// Vec ///////////////////////////////////
|
||||
// Template class for short numerical vectors, a partial case of Matx
|
||||
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> {
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
enum {
|
||||
channels = cn
|
||||
};
|
||||
|
||||
//! default constructor
|
||||
Vec();
|
||||
|
||||
Vec(_Tp v0); //!< 1-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
|
||||
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
|
||||
explicit Vec(const _Tp* values);
|
||||
|
||||
Vec(const Vec<_Tp, cn>& v);
|
||||
|
||||
static Vec all(_Tp alpha);
|
||||
|
||||
//! per-element multiplication
|
||||
Vec mul(const Vec<_Tp, cn>& v) const;
|
||||
|
||||
//! conversion to another data type
|
||||
template<typename T2> operator Vec<T2, cn>() const;
|
||||
|
||||
/*! element access */
|
||||
const _Tp& operator [](int i) const;
|
||||
_Tp& operator[](int i);
|
||||
const _Tp& operator ()(int i) const;
|
||||
_Tp& operator ()(int i);
|
||||
};
|
||||
|
||||
typedef Vec<uchar, 2> Vec2b;
|
||||
typedef Vec<uchar, 3> Vec3b;
|
||||
typedef Vec<uchar, 4> Vec4b;
|
||||
|
||||
typedef Vec<short, 2> Vec2s;
|
||||
typedef Vec<short, 3> Vec3s;
|
||||
typedef Vec<short, 4> Vec4s;
|
||||
|
||||
typedef Vec<ushort, 2> Vec2w;
|
||||
typedef Vec<ushort, 3> Vec3w;
|
||||
typedef Vec<ushort, 4> Vec4w;
|
||||
|
||||
typedef Vec<int, 2> Vec2i;
|
||||
typedef Vec<int, 3> Vec3i;
|
||||
typedef Vec<int, 4> Vec4i;
|
||||
typedef Vec<int, 6> Vec6i;
|
||||
|
||||
typedef Vec<float, 2> Vec2f;
|
||||
typedef Vec<float, 3> Vec3f;
|
||||
typedef Vec<float, 4> Vec4f;
|
||||
typedef Vec<float, 6> Vec6f;
|
||||
|
||||
typedef Vec<double, 2> Vec2d;
|
||||
typedef Vec<double, 3> Vec3d;
|
||||
typedef Vec<double, 4> Vec4d;
|
||||
typedef Vec<double, 6> Vec6d;
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec() {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0)
|
||||
: Matx<_Tp, cn, 1>(v0) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
|
||||
: Matx<_Tp, cn, 1>(v0, v1) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
|
||||
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(const _Tp* values)
|
||||
: Matx<_Tp, cn, 1>(values) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
|
||||
: Matx<_Tp, cn, 1>(m.val) {}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
|
||||
{
|
||||
Vec v;
|
||||
for (int i = 0; i < cn; i++) v.val[i] = alpha;
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
|
||||
{
|
||||
Vec<_Tp, cn> w;
|
||||
for (int i = 0; i < cn; i++) w.val[i] = saturate_cast<_Tp>(this->val[i] * v.val[i]);
|
||||
return w;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> template<typename T2> inline
|
||||
Vec<_Tp, cn>::operator Vec<T2, cn>() const
|
||||
{
|
||||
Vec<T2, cn> v;
|
||||
for (int i = 0; i < cn; i++) v.val[i] = saturate_cast<T2>(this->val[i]);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
const _Tp& Vec<_Tp, cn>::operator [](int i) const
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)cn);
|
||||
return this->val[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
_Tp& Vec<_Tp, cn>::operator [](int i)
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)cn);
|
||||
return this->val[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
const _Tp& Vec<_Tp, cn>::operator ()(int i) const
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)cn);
|
||||
return this->val[i];
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
_Tp& Vec<_Tp, cn>::operator ()(int i)
|
||||
{
|
||||
FBC_Assert((unsigned)i < (unsigned)cn);
|
||||
return this->val[i];
|
||||
}
|
||||
|
||||
////////////////////////////// Vec out-of-class operators ////////////////////////////////
|
||||
template<typename _Tp1, typename _Tp2, int cn> static inline
|
||||
Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
|
||||
{
|
||||
for (int i = 0; i < cn; i++)
|
||||
a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int cn> static inline
|
||||
Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
|
||||
{
|
||||
for (int i = 0; i < cn; i++)
|
||||
a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
|
||||
{
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
|
||||
{
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
|
||||
{
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * alpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha)
|
||||
{
|
||||
double ialpha = 1. / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha)
|
||||
{
|
||||
float ialpha = 1.f / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha)
|
||||
{
|
||||
double ialpha = 1. / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
double ialpha = 1. / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
float ialpha = 1.f / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha)
|
||||
{
|
||||
Vec<_Tp, cn> v;
|
||||
double ialpha = 1. / alpha;
|
||||
for (int i = 0; i < cn; i++)
|
||||
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename _Tp, int cn> static inline
|
||||
Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a)
|
||||
{
|
||||
Vec<_Tp, cn> t;
|
||||
for (int i = 0; i < cn; i++) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
|
||||
return t;
|
||||
}
|
||||
|
||||
} //yt_tinycv
|
||||
#endif //FBC_CV_CORE_MATX_HPP_
|
||||
@@ -0,0 +1,470 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_RESIZE_HPP_
|
||||
#define FBC_CV_RESIZE_HPP_
|
||||
|
||||
/* reference: imgproc/include/opencv2/imgproc.hpp
|
||||
imgproc/src/imgwarp.cpp
|
||||
*/
|
||||
|
||||
#include <typeinfo>
|
||||
#include "mat.hpp"
|
||||
#include "base.hpp"
|
||||
#include "saturate.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "imgproc.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
static const int MAX_ESIZE = 16;
|
||||
|
||||
// interpolation formulas and tables
|
||||
const int INTER_RESIZE_COEF_BITS = 11;
|
||||
const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;
|
||||
|
||||
template<typename _Tp, int chs> static int resize_nearest(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);
|
||||
template<typename _Tp, int chs> static int resize_linear(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);
|
||||
|
||||
// resize the image src down to or up to the specified size
|
||||
// support type: uchar/float
|
||||
template<typename _Tp, int chs>
|
||||
int resize(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, int interpolation = INTER_LINEAR)
|
||||
{
|
||||
FBC_Assert((interpolation >= 0) && (interpolation < 5));
|
||||
FBC_Assert((src.rows >= 4 && src.cols >= 4) && (dst.rows >= 4 && dst.cols >= 4));
|
||||
FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() || typeid(float).name() == typeid(_Tp).name()); // uchar || float
|
||||
|
||||
Size ssize = src.size();
|
||||
Size dsize = dst.size();
|
||||
|
||||
if (dsize == ssize) {
|
||||
// Source and destination are of same size. Use simple copy.
|
||||
src.copyTo(dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (interpolation) {
|
||||
case 0: {
|
||||
resize_nearest(src, dst);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
resize_linear(src, dst);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename ST, typename DT> struct Cast
|
||||
{
|
||||
typedef ST type1;
|
||||
typedef DT rtype;
|
||||
|
||||
DT operator()(ST val) const { return saturate_cast<DT>(val); }
|
||||
};
|
||||
|
||||
template<typename ST, typename DT, int bits> struct FixedPtCast
|
||||
{
|
||||
typedef ST type1;
|
||||
typedef DT rtype;
|
||||
enum { SHIFT = bits, DELTA = 1 << (bits - 1) };
|
||||
|
||||
DT operator()(ST val) const { return saturate_cast<DT>((val + DELTA) >> SHIFT); }
|
||||
};
|
||||
|
||||
template<typename type>
|
||||
static type clip(type x, type a, type b)
|
||||
{
|
||||
return x >= a ? (x < b ? x : b - 1) : a;
|
||||
}
|
||||
|
||||
template<typename T, typename WT, typename AT>
|
||||
struct HResizeLinear
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef WT buf_type;
|
||||
typedef AT alpha_type;
|
||||
|
||||
void operator()(const T** src, WT** dst, int count,
|
||||
const int* xofs, const AT* alpha,
|
||||
int swidth, int dwidth, int cn, int xmin, int xmax, int ONE) const
|
||||
{
|
||||
int dx, k;
|
||||
int dx0 = 0;
|
||||
|
||||
for (k = 0; k <= count - 2; k++) {
|
||||
const T *S0 = src[k], *S1 = src[k + 1];
|
||||
WT *D0 = dst[k], *D1 = dst[k + 1];
|
||||
for (dx = dx0; dx < xmax; dx++) {
|
||||
int sx = xofs[dx];
|
||||
WT a0 = alpha[dx * 2], a1 = alpha[dx * 2 + 1];
|
||||
WT t0 = S0[sx] * a0 + S0[sx + cn] * a1;
|
||||
WT t1 = S1[sx] * a0 + S1[sx + cn] * a1;
|
||||
D0[dx] = t0; D1[dx] = t1;
|
||||
}
|
||||
|
||||
for (; dx < dwidth; dx++) {
|
||||
int sx = xofs[dx];
|
||||
D0[dx] = WT(S0[sx] * ONE); D1[dx] = WT(S1[sx] * ONE);
|
||||
}
|
||||
}
|
||||
|
||||
for (; k < count; k++) {
|
||||
const T *S = src[k];
|
||||
WT *D = dst[k];
|
||||
for (dx = 0; dx < xmax; dx++) {
|
||||
int sx = xofs[dx];
|
||||
D[dx] = S[sx] * alpha[dx * 2] + S[sx + cn] * alpha[dx * 2 + 1];
|
||||
}
|
||||
|
||||
for (; dx < dwidth; dx++) {
|
||||
D[dx] = WT(S[xofs[dx]] * ONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename WT, typename AT, class CastOp>
|
||||
struct VResizeLinear
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef WT buf_type;
|
||||
typedef AT alpha_type;
|
||||
|
||||
void operator()(const WT** src, T* dst, const AT* beta, int width) const
|
||||
{
|
||||
WT b0 = beta[0], b1 = beta[1];
|
||||
const WT *S0 = src[0], *S1 = src[1];
|
||||
CastOp castOp;
|
||||
int x = 0;
|
||||
|
||||
for (; x <= width - 4; x += 4) {
|
||||
WT t0, t1;
|
||||
t0 = S0[x] * b0 + S1[x] * b1;
|
||||
t1 = S0[x + 1] * b0 + S1[x + 1] * b1;
|
||||
dst[x] = castOp(t0); dst[x + 1] = castOp(t1);
|
||||
t0 = S0[x + 2] * b0 + S1[x + 2] * b1;
|
||||
t1 = S0[x + 3] * b0 + S1[x + 3] * b1;
|
||||
dst[x + 2] = castOp(t0); dst[x + 3] = castOp(t1);
|
||||
}
|
||||
|
||||
for (; x < width; x++) {
|
||||
dst[x] = castOp(S0[x] * b0 + S1[x] * b1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct VResizeLinear<uchar, int, short, FixedPtCast<int, uchar, INTER_RESIZE_COEF_BITS * 2>>
|
||||
{
|
||||
typedef uchar value_type;
|
||||
typedef int buf_type;
|
||||
typedef short alpha_type;
|
||||
|
||||
void operator()(const buf_type** src, value_type* dst, const alpha_type* beta, int width) const
|
||||
{
|
||||
alpha_type b0 = beta[0], b1 = beta[1];
|
||||
const buf_type *S0 = src[0], *S1 = src[1];
|
||||
int x = 0;
|
||||
|
||||
for (; x <= width - 4; x += 4) {
|
||||
dst[x + 0] = uchar((((b0 * (S0[x + 0] >> 4)) >> 16) + ((b1 * (S1[x + 0] >> 4)) >> 16) + 2) >> 2);
|
||||
dst[x + 1] = uchar((((b0 * (S0[x + 1] >> 4)) >> 16) + ((b1 * (S1[x + 1] >> 4)) >> 16) + 2) >> 2);
|
||||
dst[x + 2] = uchar((((b0 * (S0[x + 2] >> 4)) >> 16) + ((b1 * (S1[x + 2] >> 4)) >> 16) + 2) >> 2);
|
||||
dst[x + 3] = uchar((((b0 * (S0[x + 3] >> 4)) >> 16) + ((b1 * (S1[x + 3] >> 4)) >> 16) + 2) >> 2);
|
||||
}
|
||||
|
||||
for (; x < width; x++) {
|
||||
dst[x] = uchar((((b0 * (S0[x] >> 4)) >> 16) + ((b1 * (S1[x] >> 4)) >> 16) + 2) >> 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp, typename value_type, typename buf_type, typename alpha_type, int chs>
|
||||
static void resizeGeneric_Linear(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst,
|
||||
const int* xofs, const void* _alpha, const int* yofs, const void* _beta, int xmin, int xmax, int ksize, int ONE)
|
||||
{
|
||||
Size ssize = src.size(), dsize = dst.size();
|
||||
int dy, cn = src.channels;
|
||||
ssize.width *= cn;
|
||||
dsize.width *= cn;
|
||||
xmin *= cn;
|
||||
xmax *= cn;
|
||||
// image resize is a separable operation. In case of not too strong
|
||||
|
||||
Range range(0, dsize.height);
|
||||
|
||||
int bufstep = (int)alignSize(dsize.width, 16);
|
||||
AutoBuffer<buf_type> _buffer(bufstep*ksize);
|
||||
const value_type* srows[MAX_ESIZE] = { 0 };
|
||||
buf_type* rows[MAX_ESIZE] = { 0 };
|
||||
int prev_sy[MAX_ESIZE];
|
||||
|
||||
for (int k = 0; k < ksize; k++) {
|
||||
prev_sy[k] = -1;
|
||||
rows[k] = (buf_type*)_buffer + bufstep*k;
|
||||
}
|
||||
|
||||
const alpha_type* beta = (const alpha_type*)_beta + ksize * range.start;
|
||||
|
||||
HResizeLinear<value_type, buf_type, alpha_type> hresize;
|
||||
VResizeLinear<value_type, buf_type, alpha_type, FixedPtCast<int, uchar, INTER_RESIZE_COEF_BITS * 2>> vresize1;
|
||||
VResizeLinear<value_type, buf_type, alpha_type, Cast<float, float>> vresize2;
|
||||
|
||||
for (dy = range.start; dy < range.end; dy++, beta += ksize) {
|
||||
int sy0 = yofs[dy], k0 = ksize, k1 = 0, ksize2 = ksize / 2;
|
||||
|
||||
for (int k = 0; k < ksize; k++) {
|
||||
int sy = clip<int>(sy0 - ksize2 + 1 + k, 0, ssize.height);
|
||||
for (k1 = std::max(k1, k); k1 < ksize; k1++) {
|
||||
if (sy == prev_sy[k1]) { // if the sy-th row has been computed already, reuse it.
|
||||
if (k1 > k) {
|
||||
memcpy(rows[k], rows[k1], bufstep*sizeof(rows[0][0]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k1 == ksize) {
|
||||
k0 = std::min(k0, k); // remember the first row that needs to be computed
|
||||
}
|
||||
srows[k] = (const value_type*)src.ptr(sy);
|
||||
prev_sy[k] = sy;
|
||||
}
|
||||
|
||||
if (k0 < ksize) {
|
||||
hresize((const value_type**)(srows + k0), (buf_type**)(rows + k0), ksize - k0, xofs, (const alpha_type*)(_alpha),
|
||||
ssize.width, dsize.width, cn, xmin, xmax, ONE);
|
||||
}
|
||||
if (sizeof(_Tp) == 1) { // uchar
|
||||
vresize1((const buf_type**)rows, (value_type*)(dst.data + dst.step*dy), beta, dsize.width);
|
||||
} else { // float
|
||||
vresize2((const buf_type**)rows, (value_type*)(dst.data + dst.step*dy), beta, dsize.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
static int resize_nearest(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst)
|
||||
{
|
||||
Size ssize = src.size();
|
||||
Size dsize = dst.size();
|
||||
|
||||
double fx = (double)dsize.width / ssize.width;
|
||||
double fy = (double)dsize.height / ssize.height;
|
||||
|
||||
AutoBuffer<int> _x_ofs(dsize.width);
|
||||
int* x_ofs = _x_ofs;
|
||||
int pix_size = (int)src.elemSize();
|
||||
int pix_size4 = (int)(pix_size / sizeof(int));
|
||||
double ifx = 1. / fx, ify = 1. / fy;
|
||||
|
||||
for (int x = 0; x < dsize.width; x++) {
|
||||
int sx = fbcFloor(x*ifx);
|
||||
x_ofs[x] = std::min(sx, ssize.width - 1)*pix_size;
|
||||
}
|
||||
|
||||
Range range(0, dsize.height);
|
||||
int x, y;
|
||||
|
||||
for (y = range.start; y < range.end; y++) {
|
||||
uchar* D = dst.data + dst.step*y;
|
||||
int sy = std::min(fbcFloor(y*ify), ssize.height - 1);
|
||||
const uchar* S = src.ptr(sy);
|
||||
|
||||
switch (pix_size) {
|
||||
case 1:
|
||||
for (x = 0; x <= dsize.width - 2; x += 2) {
|
||||
uchar t0 = S[x_ofs[x]];
|
||||
uchar t1 = S[x_ofs[x + 1]];
|
||||
D[x] = t0;
|
||||
D[x + 1] = t1;
|
||||
}
|
||||
|
||||
for (; x < dsize.width; x++) {
|
||||
D[x] = S[x_ofs[x]];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (x = 0; x < dsize.width; x++) {
|
||||
*(ushort*)(D + x * 2) = *(ushort*)(S + x_ofs[x]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (x = 0; x < dsize.width; x++, D += 3) {
|
||||
const uchar* _tS = S + x_ofs[x];
|
||||
D[0] = _tS[0]; D[1] = _tS[1]; D[2] = _tS[2];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (x = 0; x < dsize.width; x++) {
|
||||
*(int*)(D + x * 4) = *(int*)(S + x_ofs[x]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
for (x = 0; x < dsize.width; x++, D += 6) {
|
||||
const ushort* _tS = (const ushort*)(S + x_ofs[x]);
|
||||
ushort* _tD = (ushort*)D;
|
||||
_tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2];
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (x = 0; x < dsize.width; x++, D += 8) {
|
||||
const int* _tS = (const int*)(S + x_ofs[x]);
|
||||
int* _tD = (int*)D;
|
||||
_tD[0] = _tS[0]; _tD[1] = _tS[1];
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
for (x = 0; x < dsize.width; x++, D += 12) {
|
||||
const int* _tS = (const int*)(S + x_ofs[x]);
|
||||
int* _tD = (int*)D;
|
||||
_tD[0] = _tS[0]; _tD[1] = _tS[1]; _tD[2] = _tS[2];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (x = 0; x < dsize.width; x++, D += pix_size) {
|
||||
const int* _tS = (const int*)(S + x_ofs[x]);
|
||||
int* _tD = (int*)D;
|
||||
for (int k = 0; k < pix_size4; k++)
|
||||
_tD[k] = _tS[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename _Tp, int chs>
|
||||
static int resize_linear(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst)
|
||||
{
|
||||
Size ssize = src.size();
|
||||
Size dsize = dst.size();
|
||||
|
||||
double inv_scale_x = (double)dsize.width / ssize.width;
|
||||
double inv_scale_y = (double)dsize.height / ssize.height;
|
||||
double scale_x = 1. / inv_scale_x, scale_y = 1. / inv_scale_y;
|
||||
|
||||
int iscale_x = saturate_cast<int>(scale_x);
|
||||
int iscale_y = saturate_cast<int>(scale_y);
|
||||
|
||||
bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON && std::abs(scale_y - iscale_y) < DBL_EPSILON;
|
||||
// in case of scale_x && scale_y is equal to 2
|
||||
// INTER_AREA (fast) also is equal to INTER_LINEAR
|
||||
// if (is_area_fast && iscale_x == 2 && iscale_y == 2) {
|
||||
// resize_area(src, dst);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int cn = dst.channels;
|
||||
int k, sx, sy, dx, dy;
|
||||
int xmin = 0, xmax = dsize.width, width = dsize.width*cn;
|
||||
bool fixpt = sizeof(_Tp) == 1 ? true : false;
|
||||
float fx, fy;
|
||||
int ksize = 2, ksize2;
|
||||
ksize2 = ksize / 2;
|
||||
|
||||
AutoBuffer<uchar> _buffer((width + dsize.height)*(sizeof(int) + sizeof(float)*ksize));
|
||||
int* xofs = (int*)(uchar*)_buffer;
|
||||
int* yofs = xofs + width;
|
||||
float* alpha = (float*)(yofs + dsize.height);
|
||||
short* ialpha = (short*)alpha;
|
||||
float* beta = alpha + width*ksize;
|
||||
short* ibeta = ialpha + width*ksize;
|
||||
float cbuf[MAX_ESIZE];
|
||||
|
||||
for (dx = 0; dx < dsize.width; dx++) {
|
||||
fx = (float)((dx + 0.5)*scale_x - 0.5);
|
||||
sx = fbcFloor(fx);
|
||||
fx -= sx;
|
||||
|
||||
if (sx < ksize2 - 1) {
|
||||
xmin = dx + 1;
|
||||
if (sx < 0) {
|
||||
fx = 0, sx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sx + ksize2 >= ssize.width) {
|
||||
xmax = std::min(xmax, dx);
|
||||
if (sx >= ssize.width - 1) {
|
||||
fx = 0, sx = ssize.width - 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0, sx *= cn; k < cn; k++) {
|
||||
xofs[dx*cn + k] = sx + k;
|
||||
}
|
||||
|
||||
cbuf[0] = 1.f - fx;
|
||||
cbuf[1] = fx;
|
||||
|
||||
if (fixpt) {
|
||||
for (k = 0; k < ksize; k++) {
|
||||
ialpha[dx*cn*ksize + k] = saturate_cast<short>(cbuf[k] * INTER_RESIZE_COEF_SCALE);
|
||||
}
|
||||
for (; k < cn*ksize; k++) {
|
||||
ialpha[dx*cn*ksize + k] = ialpha[dx*cn*ksize + k - ksize];
|
||||
}
|
||||
} else {
|
||||
for (k = 0; k < ksize; k++) {
|
||||
alpha[dx*cn*ksize + k] = cbuf[k];
|
||||
}
|
||||
for (; k < cn*ksize; k++) {
|
||||
alpha[dx*cn*ksize + k] = alpha[dx*cn*ksize + k - ksize];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (dy = 0; dy < dsize.height; dy++) {
|
||||
fy = (float)((dy + 0.5)*scale_y - 0.5);
|
||||
sy = fbcFloor(fy);
|
||||
fy -= sy;
|
||||
|
||||
yofs[dy] = sy;
|
||||
cbuf[0] = 1.f - fy;
|
||||
cbuf[1] = fy;
|
||||
|
||||
if (fixpt) {
|
||||
for (k = 0; k < ksize; k++) {
|
||||
ibeta[dy*ksize + k] = saturate_cast<short>(cbuf[k] * INTER_RESIZE_COEF_SCALE);
|
||||
}
|
||||
} else {
|
||||
for (k = 0; k < ksize; k++) {
|
||||
beta[dy*ksize + k] = cbuf[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof(_Tp) == 1) { // uchar
|
||||
typedef uchar value_type; // HResizeLinear/VResizeLinear
|
||||
typedef int buf_type;
|
||||
typedef short alpha_type;
|
||||
int ONE = INTER_RESIZE_COEF_SCALE;
|
||||
|
||||
resizeGeneric_Linear<_Tp, value_type, buf_type, alpha_type, chs>(src, dst,
|
||||
xofs, fixpt ? (void*)ialpha : (void*)alpha, yofs, fixpt ? (void*)ibeta : (void*)beta, xmin, xmax, ksize, ONE);
|
||||
} else if (sizeof(_Tp) == 4) { // float
|
||||
typedef float value_type; // HResizeLinear/VResizeLinear
|
||||
typedef float buf_type;
|
||||
typedef float alpha_type;
|
||||
int ONE = 1;
|
||||
|
||||
resizeGeneric_Linear<_Tp, value_type, buf_type, alpha_type, chs>(src, dst,
|
||||
xofs, fixpt ? (void*)ialpha : (void*)alpha, yofs, fixpt ? (void*)ibeta : (void*)beta, xmin, xmax, ksize, ONE);
|
||||
} else {
|
||||
fprintf(stderr, "not support type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace yt_tinycv
|
||||
|
||||
#endif // FBC_CV_RESIZE_HPP_
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_SATURATE_HPP_
|
||||
#define FBC_CV_CORE_SATURATE_HPP_
|
||||
|
||||
// reference: include/opencv2/core/saturate.hpp
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "fast_math.hpp"
|
||||
|
||||
namespace yt_tinycv
|
||||
{
|
||||
template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(unsigned int v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
|
||||
template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
|
||||
|
||||
template<> inline uchar saturate_cast<uchar>(schar v) { return (uchar)std::max((int)v, 0); }
|
||||
template<> inline uchar saturate_cast<uchar>(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
|
||||
template<> inline uchar saturate_cast<uchar>(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
|
||||
template<> inline uchar saturate_cast<uchar>(short v) { return saturate_cast<uchar>((int)v); }
|
||||
template<> inline uchar saturate_cast<uchar>(unsigned int v) { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
|
||||
template<> inline uchar saturate_cast<uchar>(float v) { int iv = fbcRound(v); return saturate_cast<uchar>(iv); }
|
||||
template<> inline uchar saturate_cast<uchar>(double v) { int iv = fbcRound(v); return saturate_cast<uchar>(iv); }
|
||||
|
||||
template<> inline schar saturate_cast<schar>(uchar v) { return (schar)std::min((int)v, SCHAR_MAX); }
|
||||
template<> inline schar saturate_cast<schar>(ushort v) { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
|
||||
template<> inline schar saturate_cast<schar>(int v) { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
|
||||
template<> inline schar saturate_cast<schar>(short v) { return saturate_cast<schar>((int)v); }
|
||||
template<> inline schar saturate_cast<schar>(unsigned v) { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
|
||||
template<> inline schar saturate_cast<schar>(float v) { int iv = fbcRound(v); return saturate_cast<schar>(iv); }
|
||||
template<> inline schar saturate_cast<schar>(double v) { int iv = fbcRound(v); return saturate_cast<schar>(iv); }
|
||||
|
||||
template<> inline ushort saturate_cast<ushort>(schar v) { return (ushort)std::max((int)v, 0); }
|
||||
template<> inline ushort saturate_cast<ushort>(short v) { return (ushort)std::max((int)v, 0); }
|
||||
template<> inline ushort saturate_cast<ushort>(int v) { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
|
||||
template<> inline ushort saturate_cast<ushort>(unsigned v) { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
|
||||
template<> inline ushort saturate_cast<ushort>(float v) { int iv = fbcRound(v); return saturate_cast<ushort>(iv); }
|
||||
template<> inline ushort saturate_cast<ushort>(double v) { int iv = fbcRound(v); return saturate_cast<ushort>(iv); }
|
||||
|
||||
template<> inline short saturate_cast<short>(ushort v) { return (short)std::min((int)v, SHRT_MAX); }
|
||||
template<> inline short saturate_cast<short>(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
|
||||
template<> inline short saturate_cast<short>(unsigned v) { return (short)std::min(v, (unsigned)SHRT_MAX); }
|
||||
template<> inline short saturate_cast<short>(float v) { int iv = fbcRound(v); return saturate_cast<short>(iv); }
|
||||
template<> inline short saturate_cast<short>(double v) { int iv = fbcRound(v); return saturate_cast<short>(iv); }
|
||||
|
||||
template<> inline int saturate_cast<int>(float v) { return fbcRound(v); }
|
||||
template<> inline int saturate_cast<int>(double v) { return fbcRound(v); }
|
||||
|
||||
template<> inline unsigned saturate_cast<unsigned>(float v) { return fbcRound(v); }
|
||||
template<> inline unsigned saturate_cast<unsigned>(double v) { return fbcRound(v); }
|
||||
|
||||
} // yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_SATURATE_HPP_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,189 @@
|
||||
// fbc_cv is free software and uses the same licence as OpenCV
|
||||
// Email: fengbingchun@163.com
|
||||
|
||||
#ifndef FBC_CV_CORE_UTILITY_HPP_
|
||||
#define FBC_CV_CORE_UTILITY_HPP_
|
||||
|
||||
// reference: include/opencv2/core/utility.hpp
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error utility.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
#include "fbcdef.hpp"
|
||||
#include "base.hpp"
|
||||
|
||||
namespace yt_tinycv {
|
||||
|
||||
// The function returns the aligned pointer of the same type as the input pointer
|
||||
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n = (int)sizeof(_Tp))
|
||||
{
|
||||
return (_Tp*)(((size_t)ptr + n - 1) & -n);
|
||||
}
|
||||
|
||||
// The function returns the minimum number that is greater or equal to sz and is divisible by n
|
||||
static inline size_t alignSize(size_t sz, int n)
|
||||
{
|
||||
FBC_Assert((n & (n - 1)) == 0); // n is a power of 2
|
||||
return (sz + n - 1) & -n;
|
||||
}
|
||||
|
||||
// Automatically Allocated Buffer Class
|
||||
// The class is used for temporary buffers in functions and methods.
|
||||
template<typename _Tp, size_t fixed_size = 1024 / sizeof(_Tp) + 8> class AutoBuffer {
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
|
||||
// the default constructor
|
||||
AutoBuffer();
|
||||
// constructor taking the real buffer size
|
||||
AutoBuffer(size_t _size);
|
||||
|
||||
// the copy constructor
|
||||
AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf);
|
||||
// the assignment operator
|
||||
AutoBuffer<_Tp, fixed_size>& operator = (const AutoBuffer<_Tp, fixed_size>& buf);
|
||||
|
||||
// destructor. calls deallocate()
|
||||
~AutoBuffer();
|
||||
|
||||
// allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used
|
||||
void allocate(size_t _size);
|
||||
// deallocates the buffer if it was dynamically allocated
|
||||
void deallocate();
|
||||
// resizes the buffer and preserves the content
|
||||
void resize(size_t _size);
|
||||
// returns the current buffer size
|
||||
size_t size() const;
|
||||
// returns pointer to the real buffer, stack-allocated or head-allocated
|
||||
operator _Tp* ();
|
||||
// returns read-only pointer to the real buffer, stack-allocated or head-allocated
|
||||
operator const _Tp* () const;
|
||||
|
||||
protected:
|
||||
// pointer to the real buffer, can point to buf if the buffer is small enough
|
||||
_Tp* ptr;
|
||||
// size of the real buffer
|
||||
size_t sz;
|
||||
//! pre-allocated buffer. At least 1 element to confirm C++ standard reqirements
|
||||
_Tp buf[(fixed_size > 0) ? fixed_size : 1];
|
||||
};
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::AutoBuffer()
|
||||
{
|
||||
ptr = buf;
|
||||
sz = fixed_size;
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
|
||||
{
|
||||
ptr = buf;
|
||||
sz = fixed_size;
|
||||
allocate(_size);
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::AutoBuffer(const AutoBuffer<_Tp, fixed_size>& abuf)
|
||||
{
|
||||
ptr = buf;
|
||||
sz = fixed_size;
|
||||
allocate(abuf.size());
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
ptr[i] = abuf.ptr[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>&
|
||||
AutoBuffer<_Tp, fixed_size>::operator = (const AutoBuffer<_Tp, fixed_size>& abuf)
|
||||
{
|
||||
if (this != &abuf) {
|
||||
deallocate();
|
||||
allocate(abuf.size());
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
ptr[i] = abuf.ptr[i];
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
|
||||
{
|
||||
deallocate();
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline void
|
||||
AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
|
||||
{
|
||||
if (_size <= sz) {
|
||||
sz = _size;
|
||||
return;
|
||||
}
|
||||
|
||||
deallocate();
|
||||
if (_size > fixed_size) {
|
||||
ptr = new _Tp[_size];
|
||||
sz = _size;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline void
|
||||
AutoBuffer<_Tp, fixed_size>::deallocate()
|
||||
{
|
||||
if (ptr != buf) {
|
||||
delete[] ptr;
|
||||
ptr = buf;
|
||||
sz = fixed_size;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline void
|
||||
AutoBuffer<_Tp, fixed_size>::resize(size_t _size)
|
||||
{
|
||||
if (_size <= sz) {
|
||||
sz = _size;
|
||||
return;
|
||||
}
|
||||
size_t i, prevsize = sz, minsize = MIN(prevsize, _size);
|
||||
_Tp* prevptr = ptr;
|
||||
|
||||
ptr = _size > fixed_size ? new _Tp[_size] : buf;
|
||||
sz = _size;
|
||||
|
||||
if (ptr != prevptr) {
|
||||
for (i = 0; i < minsize; i++) {
|
||||
ptr[i] = prevptr[i];
|
||||
}
|
||||
}
|
||||
for (i = prevsize; i < _size; i++) {
|
||||
ptr[i] = _Tp();
|
||||
}
|
||||
|
||||
if (prevptr != buf) {
|
||||
delete[] prevptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline size_t
|
||||
AutoBuffer<_Tp, fixed_size>::size() const
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
} // yt_tinycv
|
||||
|
||||
#endif // FBC_CV_CORE_UTILITY_HPP_
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>YTCv</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.youtu.cv</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>YTCv</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>v0.0.7-2-g3bdc755</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v0.0.7-2-g3bdc755</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
TencentCloudHuiyanSDKFace_framework/Libs/YTCv.framework/YTCv
Normal file
BIN
TencentCloudHuiyanSDKFace_framework/Libs/YTCv.framework/YTCv
Normal file
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
#ifndef _YT_COMMON_H_
|
||||
#define _YT_COMMON_H_
|
||||
|
||||
typedef void *yt_handle;
|
||||
|
||||
typedef enum {
|
||||
YT_IMG_BGR_8UC3,
|
||||
YT_IMG_RGB_8UC3,
|
||||
YT_IMG_GRAY_8UC1,
|
||||
YT_IMG_DEPTH_16UC1,
|
||||
YT_IMG_BGRA_8UC4,
|
||||
YT_IMG_RGBA_8UC4,
|
||||
YT_IMG_NV21,
|
||||
YT_IMG_NV12,
|
||||
YT_IMG_UNKNOWN,
|
||||
} yt_img_type;
|
||||
|
||||
typedef struct yt_image_t {
|
||||
unsigned char *data;
|
||||
int width;
|
||||
int height;
|
||||
yt_img_type type;
|
||||
} yt_image;
|
||||
|
||||
typedef struct yt_rect_t {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} yt_rect;
|
||||
|
||||
typedef struct yt_pointf_t {
|
||||
float x;
|
||||
float y;
|
||||
} yt_pointf;
|
||||
|
||||
typedef struct yt_point3f_t {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} yt_point3f;
|
||||
|
||||
#endif // _YT_COMMON_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef _YT_DEFINES_H_
|
||||
#define _YT_DEFINES_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu for cross platform defines export c api.
|
||||
// windows @see: http://geoffair.net/ms/declspec.htm
|
||||
// ----------------------------------------------------------------------------
|
||||
#if (defined(WIN32) || defined(WIN64))
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __declspec(dllexport)
|
||||
#else
|
||||
#define YT_PUBLIC_ __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __attribute__((visibility("default")))
|
||||
#else
|
||||
#define YT_PUBLIC_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define YT_PUBLIC extern "C" YT_PUBLIC_
|
||||
#else
|
||||
#define YT_PUBLIC YT_PUBLIC_
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu error code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_SUCCESS 0
|
||||
#define YT_ERROR -1
|
||||
|
||||
// init error code: [-10, -99]
|
||||
#define YT_ERROR_OPEN_FILE -10
|
||||
#define YT_ERROR_READ_FILE -11
|
||||
#define YT_ERROR_FILE_EMPTY -12
|
||||
|
||||
#define YT_ERROR_RPN_NET_INIT -20
|
||||
#define YT_ERROR_RPN_NET_NOT_INIT -21
|
||||
#define YT_ERROR_RPN_INST_INIT -22
|
||||
#define YT_ERROR_RPN_INST_NOT_INIT -23
|
||||
#define YT_ERROR_RPN_FORWARD -24
|
||||
#define YT_ERROR_TNN_MEMORY_ALLOC_FAILED -25
|
||||
|
||||
#define YT_ERROR_INVALID_INSTANCE -99
|
||||
|
||||
// arguments error code: [-100, -999]
|
||||
#define YT_ERROR_MUST_NOT_NULL -100
|
||||
|
||||
#define YT_ERROR_IMAGE_TYPE -110
|
||||
#define YT_ERROR_IMAGE_DATA -111
|
||||
|
||||
#define YT_ERROR_FACE_POINTS -120
|
||||
#define YT_ERROR_FACE_FIVE_POINTS -121
|
||||
#define YT_ERROR_FACE_NINETY_POINTS -122
|
||||
#define YT_ERROR_FACE_RECT -123
|
||||
|
||||
#define YT_ERROR_INVALID_MODEL_VERSION -130
|
||||
#define YT_ERROR_MODEL_THRESHOLDS_SIZE -131
|
||||
|
||||
// auth error code
|
||||
#define YT_ERROR_AUTH_FAILED -1024
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu common code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_FACE_FEATURE_SIZE_512 512
|
||||
#define YT_FACE_FEATURE_SIZE_1024 1024
|
||||
|
||||
#define YT_FACE_FIVE_POINTS_SIZE 5
|
||||
#define YT_FACE_NINETY_POINTS_SIZE 90
|
||||
|
||||
#endif // _YT_DEFINES_H_
|
||||
@@ -0,0 +1,224 @@
|
||||
#ifndef _YT_FACE_ALIGNMENT_TINY_H_
|
||||
#define _YT_FACE_ALIGNMENT_TINY_H_
|
||||
|
||||
#include "yt_common.h"
|
||||
#include "yt_defines.h"
|
||||
|
||||
// 人脸配准模式
|
||||
#define YT_FACE_ALIGNMENT_MODE_SPARSE 1
|
||||
#define YT_FACE_ALIGNMENT_MODE_DENSE 2
|
||||
|
||||
// 人脸追踪过程,置信度不满足阈值要求时的失败结果
|
||||
#define YT_ERROR_FACE_ALIGNMENT_TRACK_CONF -10000
|
||||
|
||||
// 人脸稠密点点位数量
|
||||
// 左眉毛,右眉毛,左眼,右眼
|
||||
// 鼻子,嘴巴,轮廓,前额,瞳孔
|
||||
#define YT_DENSE_EYEBROW_POINTS_NUM 16
|
||||
#define YT_DENSE_EYE_POINTS_NUM 24
|
||||
#define YT_DENSE_NOSE_POINTS_NUM 22
|
||||
#define YT_DENSE_MOUTH_POINTS_NUM 72
|
||||
#define YT_DENSE_PROFILE_POINTS_NUM 41
|
||||
#define YT_DENSE_FOREHEAD_POINTS_NUM 7
|
||||
#define YT_DENSE_PUPIL_POINTS_NUM 34
|
||||
|
||||
|
||||
typedef struct yt_face_shape_tiny_t_liveness {
|
||||
int eye_size; ///< 眼睛点数(左眼,右眼)
|
||||
int eyebrow_size; ///< 眉毛点数(左眉,右眉)
|
||||
int nose_size; ///< 鼻子点数
|
||||
int mouth_size; ///< 嘴巴点数
|
||||
int profile_size; ///< 轮廓点数
|
||||
int forehead_size; ///< 前额点数
|
||||
int pupil_size; ///< 瞳孔点数
|
||||
|
||||
yt_pointf left_eyebrow[YT_DENSE_EYEBROW_POINTS_NUM];
|
||||
yt_pointf right_eyebrow[YT_DENSE_EYEBROW_POINTS_NUM];
|
||||
yt_pointf left_eye[YT_DENSE_EYE_POINTS_NUM];
|
||||
yt_pointf right_eye[YT_DENSE_EYE_POINTS_NUM];
|
||||
yt_pointf nose[YT_DENSE_NOSE_POINTS_NUM];
|
||||
yt_pointf mouth[YT_DENSE_MOUTH_POINTS_NUM];
|
||||
yt_pointf profile[YT_DENSE_PROFILE_POINTS_NUM];
|
||||
yt_pointf forehead[YT_DENSE_FOREHEAD_POINTS_NUM];
|
||||
yt_pointf pupil[YT_DENSE_PUPIL_POINTS_NUM];
|
||||
|
||||
float left_eyebrow_vis[YT_DENSE_EYEBROW_POINTS_NUM];
|
||||
float right_eyebrow_vis[YT_DENSE_EYEBROW_POINTS_NUM];
|
||||
float left_eye_vis[YT_DENSE_EYE_POINTS_NUM];
|
||||
float right_eye_vis[YT_DENSE_EYE_POINTS_NUM];
|
||||
float nose_vis[YT_DENSE_NOSE_POINTS_NUM];
|
||||
float mouth_vis[YT_DENSE_MOUTH_POINTS_NUM];
|
||||
float profile_vis[YT_DENSE_PROFILE_POINTS_NUM];
|
||||
float forehead_vis[YT_DENSE_FOREHEAD_POINTS_NUM];
|
||||
float pupil_vis[YT_DENSE_PUPIL_POINTS_NUM];
|
||||
|
||||
float confidence; ///< 置信度
|
||||
float occuRatio; ///< 遮挡比例
|
||||
} Yt_face_shape_tiny_liveness;
|
||||
|
||||
typedef struct yt_face_shape_3d_tiny_t_liveness {
|
||||
yt_point3f dense_points[1000]; // 三维姿态点位
|
||||
|
||||
float pitch; // Up < 0 | Down > 0, 范围在 [-60 ~ 60 ] 内会更加准确
|
||||
float yaw; // Left > 0 | Right < 0, 范围在 [-60 ~ 60] 内会更加准确
|
||||
float roll; // Anti-clockwise < 0 | Clockwise > 0
|
||||
|
||||
float transform[4][4];
|
||||
} Yt_face_shape_3d_tiny_liveness;
|
||||
|
||||
/**
|
||||
* @brief 获取版本
|
||||
*
|
||||
* @param[in] handle 实例句柄,获得 SDK 版本
|
||||
* @return SDK 版本
|
||||
*/
|
||||
// YT_PUBLIC const char *yt_face_alignment_tiny_get_version();
|
||||
YT_PUBLIC const char *Yt_face_alignment_tiny_get_version_liveness();
|
||||
|
||||
/**
|
||||
* @brief 初始化SDK,每个进程只需调用一次
|
||||
*
|
||||
* @param[in] model_dirpath 传入模型绝对路径或者相对路径,例如:`./model/face-xxx`
|
||||
* @param[in] config_filename 传入模型路径下的配置文件名称,例如:`config.ini`
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_create_handle(yt_handle *handle, const char *model_dirpath, const char *config_filename);
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_create_handle_liveness(yt_handle *handle, const char *model_dirpath, const char *config_filename);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/asset_manager.h>
|
||||
/**
|
||||
* @brief 初始化SDK,每个进程只需调用一次,该接口用于 android 加载 assets 目录下模型文件
|
||||
* 如有 jni 开发需求,可以通过此接口加载模型
|
||||
*
|
||||
* @param[in] mgr 通过 `AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);` 获得
|
||||
* @param[in] assets_model_dirpath 传入模型相对于 `assets` 目录的路径,例如:`models/face-xxx`
|
||||
* @param[in] assets_config_filename 传入模型路径下的配置文件名称,例如:`config.ini`
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_create_handle_android_liveness(yt_handle *handle, AAssetManager *mgr, const char *model_dirpath, const char *config_filename);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_create_handle_android(yt_handle *handle, AAssetManager *mgr, const char *model_dirpath, const char *config_filename);
|
||||
#endif
|
||||
|
||||
#ifdef UNIVERSE_IO
|
||||
#include <io/io.hpp>
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_create_handle_io_liveness(yt_handle *handle, const char *model_dirpath, const char *config_filename, IO* io);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 销毁实例
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @return
|
||||
*/
|
||||
YT_PUBLIC void Yt_face_alignment_tiny_destroy_handle_liveness(yt_handle handle);
|
||||
// YT_PUBLIC void yt_face_alignment_tiny_destroy_handle(yt_handle handle);
|
||||
|
||||
/**
|
||||
* @brief 设置实例出来的人脸配准点的置信度阈值
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] threshold 人脸配准置信度阈值
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_set_threshold_liveness(yt_handle handle, float threshold);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_set_threshold(yt_handle handle, float threshold);
|
||||
|
||||
/**
|
||||
* @brief 设置实例align和track接口的配准模式
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] mode 1:代表 SPARSE/130 点配准,2:代表 DENSE/256 点配准
|
||||
* 可选择模式取决于初始化时 config 文件中的 type,DENSE兼容模式:1、2,SPARSE只支持模式:1
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_set_mode_liveness(yt_handle handle, int mode);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_set_mode(yt_handle handle, int mode);
|
||||
|
||||
/**
|
||||
* @brief 配准接口,用于人脸框得到人脸信息
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] image 图片,推荐 YT_IMG_BGR_8UC3 / YT_IMG_RGB_8UC3 / YT_IMG_GRAY_8UC1
|
||||
* @param[in] rect 人脸框
|
||||
* @param[out] face 人脸信息
|
||||
* @return YT_PUBLIC yt_face_alignment_tiny_align
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_align_liveness(yt_handle handle, const yt_image image, const yt_rect rect, Yt_face_shape_tiny_liveness *face);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_align(yt_handle handle, const yt_image image, const yt_rect rect, yt_face_shape_tiny *face);
|
||||
|
||||
/**
|
||||
* @brief 追踪配准接口
|
||||
* @example 当配合 YTFaceDetector SDK 使用时候的调用示例
|
||||
*
|
||||
* ```c++
|
||||
* int ret;
|
||||
* // step 1: 获取输入图片上检测到的人脸
|
||||
* yt_rect *rects;
|
||||
* int rect_count = 0;
|
||||
* ret = yt_face_detector_detect(yt_detect_handle, image, param, &rects, &rect_count);
|
||||
*
|
||||
* // step 2: 使用 rect 进行配准,首帧时要求 rect 准确
|
||||
* yt_face_shape_tiny *face_shapes = new yt_face_shape_tiny[rect_count];
|
||||
* for (int i = 0; i < rect_count; i++) {
|
||||
* int face_id = i;
|
||||
* yt_rect face_rect = rect[face_id];
|
||||
* ret = yt_face_alignment_tiny_track(yt_align_hanele, image, face_id, face_rect, &face_shapes[face_id]);
|
||||
* }
|
||||
*
|
||||
* // step 3: 释放
|
||||
* delete[] rects;
|
||||
* for (int i = 0; i < rect_count; i++) {
|
||||
* yt_face_alignment_tiny_release(face_shapes[i]);
|
||||
* }
|
||||
* delete[] face_shapes;
|
||||
* ```c++
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] image 图片,推荐 YT_IMG_BGR_8UC3 / YT_IMG_RGB_8UC3 / YT_IMG_GRAY_8UC1
|
||||
* @param[in] face_id 需要追踪的人脸框 ID
|
||||
* @param[in] face_rect 追踪的人脸框
|
||||
* @param[out] faces 每个框对应的人脸配准点
|
||||
* @return YT_SUCCESS:成功
|
||||
* -10000:人脸追踪过程,置信度不满足阈值要求时的失败结果
|
||||
* 其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_track_liveness(yt_handle handle, const yt_image image, const int face_id, const yt_rect face_rect, Yt_face_shape_tiny_liveness *face_shape);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_track(yt_handle handle, const yt_image image, const int face_id, const yt_rect face_rect,
|
||||
// yt_face_shape_tiny *face_shape);
|
||||
|
||||
// /**
|
||||
// * @brief 释放检测结果
|
||||
// *
|
||||
// * @param[in] yt_face_shape_tiny
|
||||
// */
|
||||
// YT_PUBLIC void yt_face_alignment_tiny_release(yt_face_shape_tiny *face);
|
||||
|
||||
/**
|
||||
* @brief 重置追踪状态
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_reset_liveness(yt_handle handle);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_reset(yt_handle handle);
|
||||
|
||||
/**
|
||||
* @brief 人脸透视投影姿态估计接口函数,输出三维角度
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] face_shape 人脸配准点
|
||||
* @param[in] focal 摄像头像素焦距,如 600
|
||||
* @param[in] center_x 图像中点x,如 image.width / 2
|
||||
* @param[in] center_y 图像中点y,如 image.height / 2
|
||||
* @param[in] is_deg true : 以角度形式输出
|
||||
* false : 以弧度形式输出
|
||||
* @param[out] face_shape_3d 三维角度及3D平移shape
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_alignment_tiny_get_face_shape_3d_liveness(yt_handle handle, const Yt_face_shape_tiny_liveness face_shape, float focal, float center_x, float center_y, bool is_deg, Yt_face_shape_3d_tiny_liveness *face_shape_3d);
|
||||
// YT_PUBLIC int yt_face_alignment_tiny_get_face_shape_3d(yt_handle handle, const yt_face_shape_tiny face_shape,
|
||||
// float focal, float center_x, float center_y, bool is_deg,
|
||||
// yt_face_shape_3d_tiny *face_shape_3d);
|
||||
|
||||
#endif // _YT_FACE_ALIGNMENT_H_
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>YTFaceAlignmentTiny</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.youtu.alignment</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>YTFaceAlignmentTinyLiveness</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>v3.0.2-mini.5-2-g7035ab4</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v3.0.2-mini.5-2-g7035ab4</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
#ifndef _YT_COMMON_H_
|
||||
#define _YT_COMMON_H_
|
||||
|
||||
typedef void *yt_handle;
|
||||
|
||||
typedef enum {
|
||||
YT_IMG_BGR_8UC3,
|
||||
YT_IMG_RGB_8UC3,
|
||||
YT_IMG_GRAY_8UC1,
|
||||
YT_IMG_DEPTH_16UC1,
|
||||
YT_IMG_BGRA_8UC4,
|
||||
YT_IMG_RGBA_8UC4,
|
||||
YT_IMG_NV21,
|
||||
YT_IMG_NV12,
|
||||
YT_IMG_UNKNOWN,
|
||||
} yt_img_type;
|
||||
|
||||
typedef struct yt_image_t {
|
||||
unsigned char *data;
|
||||
int width;
|
||||
int height;
|
||||
yt_img_type type;
|
||||
} yt_image;
|
||||
|
||||
typedef struct yt_rect_t {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} yt_rect;
|
||||
|
||||
typedef struct yt_pointf_t {
|
||||
float x;
|
||||
float y;
|
||||
} yt_pointf;
|
||||
|
||||
typedef struct yt_point3f_t {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} yt_point3f;
|
||||
|
||||
#endif // _YT_COMMON_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef _YT_DEFINES_H_
|
||||
#define _YT_DEFINES_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu for cross platform defines export c api.
|
||||
// windows @see: http://geoffair.net/ms/declspec.htm
|
||||
// ----------------------------------------------------------------------------
|
||||
#if (defined(WIN32) || defined(WIN64))
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __declspec(dllexport)
|
||||
#else
|
||||
#define YT_PUBLIC_ __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __attribute__((visibility("default")))
|
||||
#else
|
||||
#define YT_PUBLIC_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define YT_PUBLIC extern "C" YT_PUBLIC_
|
||||
#else
|
||||
#define YT_PUBLIC YT_PUBLIC_
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu error code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_SUCCESS 0
|
||||
#define YT_ERROR -1
|
||||
|
||||
// init error code: [-10, -99]
|
||||
#define YT_ERROR_OPEN_FILE -10
|
||||
#define YT_ERROR_READ_FILE -11
|
||||
#define YT_ERROR_FILE_EMPTY -12
|
||||
|
||||
#define YT_ERROR_RPN_NET_INIT -20
|
||||
#define YT_ERROR_RPN_NET_NOT_INIT -21
|
||||
#define YT_ERROR_RPN_INST_INIT -22
|
||||
#define YT_ERROR_RPN_INST_NOT_INIT -23
|
||||
#define YT_ERROR_RPN_FORWARD -24
|
||||
#define YT_ERROR_TNN_MEMORY_ALLOC_FAILED -25
|
||||
|
||||
#define YT_ERROR_INVALID_INSTANCE -99
|
||||
|
||||
// arguments error code: [-100, -999]
|
||||
#define YT_ERROR_MUST_NOT_NULL -100
|
||||
|
||||
#define YT_ERROR_IMAGE_TYPE -110
|
||||
#define YT_ERROR_IMAGE_DATA -111
|
||||
|
||||
#define YT_ERROR_FACE_POINTS -120
|
||||
#define YT_ERROR_FACE_FIVE_POINTS -121
|
||||
#define YT_ERROR_FACE_NINETY_POINTS -122
|
||||
#define YT_ERROR_FACE_RECT -123
|
||||
|
||||
#define YT_ERROR_INVALID_MODEL_VERSION -130
|
||||
#define YT_ERROR_MODEL_THRESHOLDS_SIZE -131
|
||||
|
||||
// auth error code
|
||||
#define YT_ERROR_AUTH_FAILED -1024
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu common code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_FACE_FEATURE_SIZE_512 512
|
||||
#define YT_FACE_FEATURE_SIZE_1024 1024
|
||||
|
||||
#define YT_FACE_FIVE_POINTS_SIZE 5
|
||||
#define YT_FACE_NINETY_POINTS_SIZE 90
|
||||
|
||||
#endif // _YT_DEFINES_H_
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef _YT_FACE_DETECTOR_H_
|
||||
#define _YT_FACE_DETECTOR_H_
|
||||
|
||||
#include "yt_common.h"
|
||||
#include "yt_defines.h"
|
||||
|
||||
typedef struct yt_face_detector_param_t_liveness {
|
||||
int min_face_size; ///< 最小搜索步长,建议使用默认值
|
||||
int max_face_size; ///< 最大搜索步长,建议使用默认值
|
||||
int bigger_face_mode; ///< 检测模式:0:完整检测, 1:快速检测
|
||||
bool non_square_rect; ///< 检测框:是否为正方形框
|
||||
float threshold; ///< 检测阈值:建议使用默认值
|
||||
} Yt_face_detector_param_liveness;
|
||||
|
||||
/**
|
||||
* @brief 获取版本
|
||||
*
|
||||
* @param[in] handle 实例句柄,获得 SDK 版本
|
||||
* @return SDK 版本
|
||||
*/
|
||||
YT_PUBLIC const char *Yt_face_detector_get_version_liveness();
|
||||
|
||||
/**
|
||||
* @brief 初始化SDK,每个进程只需调用一次
|
||||
*
|
||||
* @param[in] model_dirpath 传入模型绝对路径或者相对路径,例如:`./model/face-xxx`
|
||||
* @param[in] config_filename 传入模型路径下的配置文件名称,例如:`config.ini`
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_detector_create_handle_liveness(yt_handle *handle, const char *model_dirpath, const char *config_filename);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/asset_manager.h>
|
||||
/**
|
||||
* @brief 初始化SDK,每个进程只需调用一次,该接口用于 android 加载 assets 目录下模型文件
|
||||
* 如有 jni 开发需求,可以通过此接口加载模型
|
||||
*
|
||||
* @param[in] mgr 通过 `AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);` 获得
|
||||
* @param[in] assets_model_dirpath 传入模型相对于 `assets` 目录的路径,例如:`models/face-xxx`
|
||||
* @param[in] assets_config_filename 传入模型路径下的配置文件名称,例如:`config.ini`
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_detector_create_handle_android_liveness(yt_handle *handle, AAssetManager *mgr, const char *model_dirpath, const char *config_filename);
|
||||
#endif
|
||||
|
||||
#ifdef UNIVERSE_IO
|
||||
#include <io/io.hpp>
|
||||
YT_PUBLIC int Yt_face_detector_create_handle_io_liveness(yt_handle* handle, const char* model_dirpath, const char* config_filename, IO* io);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 销毁实例
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
*/
|
||||
YT_PUBLIC void Yt_face_detector_destroy_handle_liveness(yt_handle handle);
|
||||
|
||||
/**
|
||||
* @brief 获取参数
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[out] param 默认参数
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_detector_get_default_param_liveness(yt_handle handle, Yt_face_detector_param_liveness *param);
|
||||
|
||||
/**
|
||||
* @brief 检测接口,单帧图片检测
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] image 图片,图片类型:YT_IMG_BGR_8UC3 or YT_IMG_RGB_8UC3
|
||||
* @param[in] param 自定义的参数
|
||||
* @param[out] tracked_faces 检测到的人脸信息
|
||||
* @param[out] tracked_faces_count 检测到的人脸数量
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int Yt_face_detector_detect_liveness(yt_handle handle, const yt_image image, const Yt_face_detector_param_liveness param,
|
||||
yt_rect **rects, int *count);
|
||||
|
||||
/**
|
||||
* @brief 释放检测结果
|
||||
*
|
||||
* @param[in] rects
|
||||
*/
|
||||
YT_PUBLIC void Yt_face_detector_release_rects_liveness(yt_rect *rects);
|
||||
|
||||
#endif // _YT_FACE_DETECTOR_H_
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>YTFaceDetector</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.youtu.detector</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>YTFaceDetectorLiveness</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>v1.2.0-mini.5-2-g4e1d28c</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v1.2.0-mini.5-2-g4e1d28c</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// DataDef.h
|
||||
// FaceVideoTest
|
||||
//
|
||||
// Created by starimeliu on 2017/4/13.
|
||||
// Copyright © 2017年 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef DataDef_h
|
||||
#define DataDef_h
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#ifdef __APPLE__
|
||||
#include <YTCv/core.hpp>
|
||||
#endif
|
||||
// ===== Observation Pack ======
|
||||
|
||||
struct YTRawImgData // === N pairs of images along with their landmarks ===
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
yt_tinycv::Mat3BGR frameMat;//iOS新一闪逐帧回调专用 用于OC层转UIImage对象再转jpeg android用JNI回调的方式在cpp方法内部做了jpeg图像转换
|
||||
#endif
|
||||
std::vector<unsigned char> frame_buffer; // Frame data in buffer
|
||||
std::string frame_buffer_string; //frame_buffer的std::string类型值
|
||||
std::string checksum;
|
||||
long long CaptureTime;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct RawYuvData
|
||||
{
|
||||
std::vector<unsigned char> yuvData;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct YTDataPack
|
||||
{
|
||||
std::vector<YTRawImgData> VideoData; // Length = 2*N
|
||||
long long BeginTime;
|
||||
long long ChangePointTime;
|
||||
std::vector<long long> ChangePointTimeList;
|
||||
float OffsetSys;
|
||||
int config_begin;
|
||||
int frameNum; // Number of frames = 2*N
|
||||
int LandMarkNum; // Length of landmark points = 90 here
|
||||
int width;
|
||||
int height;
|
||||
const char *log; // text log info
|
||||
const char *SeqID;
|
||||
const char *version;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ===== CAPTCHA Pack ======
|
||||
|
||||
struct YTCAPTCHA{
|
||||
int fixedInterval;
|
||||
int unit;
|
||||
int rand_shift;
|
||||
int rand_inv;
|
||||
std::vector<int> intervals;
|
||||
|
||||
const char *SeqID;
|
||||
};
|
||||
|
||||
// ===== Full Pack ======
|
||||
struct YTFullPack{
|
||||
YTDataPack AGin;
|
||||
YTCAPTCHA CP;
|
||||
};
|
||||
|
||||
#endif /* DataDef_h */
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Version.h
|
||||
// YTFaceLiveReflect
|
||||
//
|
||||
// Created by sunnydu on 2022/10/13.
|
||||
// Copyright © 2022 Patrick Yang. All rights reserved.
|
||||
//
|
||||
#define R_FRAMEWORK_VERSION "1.1.15.175.1"
|
||||
#ifndef Version_h
|
||||
#define Version_h
|
||||
|
||||
|
||||
#endif /* Version_h */
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// YTAGReflectDeviceDelegate.h
|
||||
// FaceVideoTest
|
||||
//
|
||||
// Created by CosperYu on 2019/02/28.
|
||||
// Copyright © 2019 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef YTAGReflectDeviceDelegate_h
|
||||
#define YTAGReflectDeviceDelegate_h
|
||||
|
||||
@protocol YTAGReflectDeviceDelegate <NSObject>
|
||||
//设置camera的曝光时间和iso
|
||||
- (void)setCameraSettings:(long)expTime1000thSec iso:(int)isoValue;
|
||||
//用于获取iso等摄像头信息,该接口不会进行任何device设置,只会读取device信息;
|
||||
- (AVCaptureDevice *_Nonnull)getCaptureDevice;
|
||||
@end
|
||||
|
||||
#endif /* YTAGReflectDeviceDelegate_h */
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// YTBrightnessManager.h
|
||||
// YTFaceLiveReflect
|
||||
//
|
||||
// Created by CosperYu on 2019/01/03.
|
||||
// Copyright © 2019年 Patrick Yang. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol YTOnGetBrightness <NSObject>
|
||||
-(void)onGetBrightness:(float)brightness; //获取到光线强度
|
||||
-(void)getBrightnessOverTime; //获取超时
|
||||
@end
|
||||
|
||||
@class BrightnessDevice;
|
||||
|
||||
@interface YTBrightnessManager : NSObject {
|
||||
std::vector<float> vec;
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) id<YTOnGetBrightness> onGetBrightnessDelegate;
|
||||
@property (nonatomic, strong, nullable) BrightnessDevice *brightnessDevice;
|
||||
@property (nonatomic, strong, nullable) NSTimer *timer;
|
||||
//@property (nonatomic, assign) std::vector<float> vec;
|
||||
@property (nonatomic, assign) int recordCount;
|
||||
|
||||
|
||||
+ (NSDictionary*)getUploadDic:(float)brightnessValue;
|
||||
|
||||
//overTime 超时时间(单位:ms),超时后回调getBrightnessOverTime。
|
||||
//启动后会调用前置摄像头传感设备获取信息,如果当前正在使用前置摄像头可能会造成短时间(7plus上1秒内)的显示卡顿
|
||||
- (int)getBrightness:(id<YTOnGetBrightness>)onGetBrightness overTime:(NSTimeInterval)overTime;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// YTFaceHandle.h
|
||||
// FaceVideoTest
|
||||
//
|
||||
// Created by CosperYu on 2019/02/28.
|
||||
// Copyright © 2019 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "DataDef.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#import "YTAGReflectDeviceDelegate.h"
|
||||
|
||||
#import <CommonCrypto/CommonCrypto.h>
|
||||
|
||||
|
||||
#ifndef YTFaceHandle_h
|
||||
#define YTFaceHandle_h
|
||||
|
||||
//#define YT_ENCODE_REFLECT_DATA
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Comment this version define avoid redefined and use interfaces instead.
|
||||
#define YT_FACE_REFLECT_VERSION @"3.7.4"
|
||||
|
||||
//活体类型
|
||||
enum YTLIVETYPE {
|
||||
LIVETYPE_REFLECT = 1, //反光
|
||||
LIVETYPE_POSE = 2, //动作
|
||||
};
|
||||
|
||||
//服务器回调验证
|
||||
enum YTSERVERCHECK_TYPE {
|
||||
YTSERVERCHECK_INPUTPARAM_NULL = -1, //入参为空
|
||||
YTSERVERCHECK_CHECKPASS = 0, //检测通过
|
||||
|
||||
//反光验证使用
|
||||
YTSERVERCHECK_REFLECT_FAILED = 1, //反光验证失败
|
||||
YTSERVERCHECK_PICTURE_FAILED = 2, //防翻拍验证失败
|
||||
YTSERVERCHECK_COMPARE_FAILED = 3, //对比失败
|
||||
};
|
||||
|
||||
enum YTREFLECT_SAFETY_LEVEL {
|
||||
YTREFLECT_SAFETY_RECOMMAND = 0, //推荐大小,反光上传数据大概500K
|
||||
YTREFLECT_SAFETY_LOW = 1, //低安全性,上传包体大概300K。若网络环境或者破解要求没那么高的场景使用
|
||||
YTREFLECT_SAFETY_HIGH = 2, //高安全性,上传包体可能会到2M。微信在用
|
||||
|
||||
YTREFLECT_SAFETY_COUNT = 3
|
||||
};
|
||||
|
||||
/*
|
||||
@brief 反光结束时的回调
|
||||
@param ret: 反光序列字符串
|
||||
0 成功
|
||||
-1 调用了clearAG终止反光
|
||||
-1491 反光图片序列检验的时候检查不到人脸
|
||||
-1493 时间戳数量跟图片数量对不上,通常是sdk内部错误
|
||||
-1494 iso变光点时序不正确,通常是sdk内部错误造成
|
||||
@param fullPack: 反光结果图
|
||||
*/
|
||||
typedef void (^onFinish)(int ret, YTFullPack fullPack);
|
||||
typedef void (^onDalayCalc)();
|
||||
typedef void (^onReflectLiveImgData)(YTRawImgData frame);
|
||||
|
||||
/*
|
||||
@brief 解析rgb请求
|
||||
@param rgbconfig: 解析后的rgb序列
|
||||
@param error: 解析产生错误或者服务器回调错误。如果无错误,则为nil
|
||||
*/
|
||||
typedef void (^YTRgbconfigParseResult)(NSString* _Nullable rgbconfig, NSError *_Nullable error);
|
||||
/**
|
||||
@brief 反光事件回调接口
|
||||
@param rgb 屏幕颜色
|
||||
@param light 屏幕亮度
|
||||
*/
|
||||
typedef void (^YTReflectEventCallback)(uint argb ,CGFloat light);
|
||||
|
||||
/**
|
||||
@brief 反光SDK日志注册回调
|
||||
@param level 日志等级 (0 - error, 1 - warn, 2 - info, 3 - error)
|
||||
@param message 日志信息
|
||||
*/
|
||||
typedef void (^OnYTFaceReflectSDKLoggerEventBlock)(int level, NSString * _Nonnull message);
|
||||
|
||||
@interface YTFaceHandle : NSObject
|
||||
#pragma mark - Global Interface
|
||||
|
||||
/**
|
||||
* 0 RGB
|
||||
* 1 BGR
|
||||
*/
|
||||
@property (assign, nonatomic) int innerImgType;
|
||||
@property (assign, nonatomic) float compressReflectionImageScore;
|
||||
/**
|
||||
@brief 日志注册接口
|
||||
@param level 日志等级 (0 - error, 1 - warn, 2 - info, 3 - error)
|
||||
@param listener 日志回调
|
||||
*/
|
||||
+ (void)registerSDKLogger:(int) level withListener:(OnYTFaceReflectSDKLoggerEventBlock _Nullable)listener;
|
||||
+ (NSString * _Nonnull)checksum:(NSString * _Nonnull)act_str withData:(id _Nonnull)data;
|
||||
#pragma mark - Life Circle
|
||||
/**
|
||||
* 更新配置
|
||||
* @param key is_alone_raw_push是否流式传输(边压帧边吐帧) 1打开 is_shorten_strategy 当流式传输时生效(解决性能问题) 1开启抽帧
|
||||
* @param value
|
||||
*/
|
||||
- (void)updateParam:(NSString * _Nonnull)key withValue:(NSString * _Nonnull)value;
|
||||
/**
|
||||
@brief 初始化反光实例
|
||||
@param appId: 应用的appid,需要在优图后台申请
|
||||
@param extraData: ppl version
|
||||
*/
|
||||
- (id _Nullable )initWithAppId:(NSString*_Nonnull)appId withExtraData:(NSString *_Nullable)extraData;
|
||||
/**
|
||||
@brief 反光事件回调注册函数
|
||||
@param callback 反光事件回调
|
||||
*/
|
||||
- (void)setReflectEvent:(YTReflectEventCallback _Nonnull)callback;
|
||||
/**
|
||||
@brief 获取sdk版本
|
||||
@return 返回版本信息
|
||||
*/
|
||||
- (const NSString * _Nonnull)getVersion;
|
||||
|
||||
/**
|
||||
@brief 初始化并且开始反光过程
|
||||
@param rgbConfig: 反光序列字符串
|
||||
@param device:遵循YTAGReflectDeviceDelegate协议的对象
|
||||
@param shapeView: 用于控制屏幕颜色变化的view
|
||||
@param onDalayCalc: 开始延迟计算过程
|
||||
@param onFinish: 前段反光过程完成,具体返回内容含义参照onFinish定义。回调发生在主线程
|
||||
@return error code:
|
||||
0 成功
|
||||
-1 CP_string格式组成不正确
|
||||
-2 device为空
|
||||
-3 shapeView为空
|
||||
-4 onDalayCalc为空
|
||||
-5 onFinish为空
|
||||
-1024 授权验证失败
|
||||
@warning 1、请在主线程调用
|
||||
2、反光活体暂不支持多线程同时使用
|
||||
*/
|
||||
- (NSInteger)initAG:(NSString *_Nonnull)rgbConfig
|
||||
device:(id<YTAGReflectDeviceDelegate> _Nonnull)device
|
||||
shapeView:(UIView* _Nullable)shapeView
|
||||
onDalayCalc:(onDalayCalc _Nonnull)onDalayCalc
|
||||
onFinish:(onFinish _Nonnull)onFinish
|
||||
onReflectLiveImgData:(onReflectLiveImgData _Nonnull)onReflectLiveImgData
|
||||
outputDurationMS:(long &)durationMS;
|
||||
/**
|
||||
@brief 自动生成反光序列
|
||||
@return 返回反光序列
|
||||
*/
|
||||
- (NSString * _Nonnull)AutoGenRgb:(int)rgbNum mode:(NSString * _Nonnull)mode;
|
||||
/**
|
||||
@brief 反光过程压帧接口
|
||||
@param faceImageCrop: 反光开始后的每帧数据
|
||||
@param faceAlign: 当前帧的配准结果
|
||||
@param timeStamp: 当前帧时间戳
|
||||
*/
|
||||
- (void)PushImgSequence:(void*_Nonnull)faceRgbMat faceAlign:(NSMutableArray* _Nonnull)faceAlign timeStamp:(uint64_t)timeStamp;
|
||||
|
||||
//终止反光并清理反光数据,调用后如需再次反光,需要重新调用initAG
|
||||
//可以在反光过程的任意阶段调用,如用户反光过程来电或者其他原因希望结束反光验证时
|
||||
//正常流程下依然建议使用demo的方式,反光过程进行界面锁定避免用户不必要的操作
|
||||
- (void)clearAG;
|
||||
|
||||
#pragma mark - Settings
|
||||
//安全性设置,参照 YTSAFETYLEVEL
|
||||
- (void)setSafety:(YTREFLECT_SAFETY_LEVEL) value;
|
||||
- (int)getSafety;
|
||||
|
||||
|
||||
#pragma mark - Utility
|
||||
|
||||
//检测是否睁眼
|
||||
//反光开始前需要用户睁眼,以避免沉睡状态下通过了反光验证
|
||||
- (float) precheckCloseEye:(const NSMutableArray* _Nonnull) att;
|
||||
|
||||
////临时存储图的路径(测试用)
|
||||
//-(void)setSavePath:(NSString* _Nonnull)savePath;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* YTFaceHandle_h */
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
#ifndef _YT_COMMON_H_
|
||||
#define _YT_COMMON_H_
|
||||
|
||||
typedef void *yt_handle;
|
||||
|
||||
typedef enum {
|
||||
YT_IMG_BGR_8UC3,
|
||||
YT_IMG_RGB_8UC3,
|
||||
YT_IMG_GRAY_8UC1,
|
||||
YT_IMG_DEPTH_16UC1,
|
||||
YT_IMG_BGRA_8UC4,
|
||||
YT_IMG_RGBA_8UC4,
|
||||
YT_IMG_NV21,
|
||||
YT_IMG_NV12,
|
||||
YT_IMG_UNKNOWN,
|
||||
} yt_img_type;
|
||||
|
||||
typedef struct yt_image_t {
|
||||
unsigned char *data;
|
||||
int width;
|
||||
int height;
|
||||
yt_img_type type;
|
||||
} yt_image;
|
||||
|
||||
typedef struct yt_rect_t {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} yt_rect;
|
||||
|
||||
typedef struct yt_pointf_t {
|
||||
float x;
|
||||
float y;
|
||||
} yt_pointf;
|
||||
|
||||
typedef struct yt_point3f_t {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} yt_point3f;
|
||||
|
||||
#endif // _YT_COMMON_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef _YT_DEFINES_H_
|
||||
#define _YT_DEFINES_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu for cross platform defines export c api.
|
||||
// windows @see: http://geoffair.net/ms/declspec.htm
|
||||
// ----------------------------------------------------------------------------
|
||||
#if (defined(WIN32) || defined(WIN64))
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __declspec(dllexport)
|
||||
#else
|
||||
#define YT_PUBLIC_ __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#ifdef YT_EXPORT
|
||||
#define YT_PUBLIC_ __attribute__((visibility("default")))
|
||||
#else
|
||||
#define YT_PUBLIC_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define YT_PUBLIC extern "C" YT_PUBLIC_
|
||||
#else
|
||||
#define YT_PUBLIC YT_PUBLIC_
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu error code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_SUCCESS 0
|
||||
#define YT_ERROR -1
|
||||
|
||||
// init error code: [-10, -99]
|
||||
#define YT_ERROR_OPEN_FILE -10
|
||||
#define YT_ERROR_READ_FILE -11
|
||||
#define YT_ERROR_FILE_EMPTY -12
|
||||
|
||||
#define YT_ERROR_RPN_NET_INIT -20
|
||||
#define YT_ERROR_RPN_NET_NOT_INIT -21
|
||||
#define YT_ERROR_RPN_INST_INIT -22
|
||||
#define YT_ERROR_RPN_INST_NOT_INIT -23
|
||||
#define YT_ERROR_RPN_FORWARD -24
|
||||
#define YT_ERROR_TNN_MEMORY_ALLOC_FAILED -25
|
||||
|
||||
#define YT_ERROR_INVALID_INSTANCE -99
|
||||
|
||||
// arguments error code: [-100, -999]
|
||||
#define YT_ERROR_MUST_NOT_NULL -100
|
||||
|
||||
#define YT_ERROR_IMAGE_TYPE -110
|
||||
#define YT_ERROR_IMAGE_DATA -111
|
||||
|
||||
#define YT_ERROR_FACE_POINTS -120
|
||||
#define YT_ERROR_FACE_FIVE_POINTS -121
|
||||
#define YT_ERROR_FACE_NINETY_POINTS -122
|
||||
#define YT_ERROR_FACE_RECT -123
|
||||
|
||||
#define YT_ERROR_INVALID_MODEL_VERSION -130
|
||||
#define YT_ERROR_MODEL_THRESHOLDS_SIZE -131
|
||||
|
||||
// auth error code
|
||||
#define YT_ERROR_AUTH_FAILED -1024
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// YouTu common code defines
|
||||
// ----------------------------------------------------------------------------
|
||||
#define YT_FACE_FEATURE_SIZE_512 512
|
||||
#define YT_FACE_FEATURE_SIZE_1024 1024
|
||||
|
||||
#define YT_FACE_FIVE_POINTS_SIZE 5
|
||||
#define YT_FACE_NINETY_POINTS_SIZE 90
|
||||
|
||||
#endif // _YT_DEFINES_H_
|
||||
@@ -0,0 +1,125 @@
|
||||
#ifndef _YT_FACE_TRACKER_H_
|
||||
#define _YT_FACE_TRACKER_H_
|
||||
|
||||
#include "yt_common.h"
|
||||
#include "yt_defines.h"
|
||||
|
||||
#define YT_MINI_NAMESPACE liveness
|
||||
|
||||
#define SUFFIX_HELPER_(x, y) x##_##y
|
||||
#define SUFFIX_HELPER(x, y) SUFFIX_HELPER_(x, y)
|
||||
#define SUFFIX(x) SUFFIX_HELPER(x, YT_MINI_NAMESPACE)
|
||||
|
||||
typedef struct yt_face_tracker_param_t_liveness {
|
||||
int min_face_size; ///< 最小物体大小,建议使用默认值
|
||||
int max_face_size; ///< 最大物体大小,建议使用默认值
|
||||
int bigger_face_mode; ///< 检测模式:0:完整检测, 1:快速检测
|
||||
bool non_square_rect; ///< 检测框:是否为正方形框
|
||||
float threshold; ///< 检测阈值:建议使用默认值
|
||||
int detect_interval; ///< 检测间隔,默认6; detect_interval为-1时,只在第一帧或没有人时做检测
|
||||
int noface_detect_interval; /// < 检测间隔, 默认0,未检测到人脸后下一次检测间隔
|
||||
} SUFFIX(Yt_face_tracker_param);
|
||||
|
||||
typedef struct yt_tracked_face_t_liveness {
|
||||
int shape_size; ///< 人脸配准点有效位数 130 or 256
|
||||
yt_pointf face_shape[256]; ///< 人脸配准点
|
||||
float face_vis[256]; ///< 人脸配准点置信度
|
||||
yt_rect face_rect; ///< 人脸框
|
||||
|
||||
int frame_id; ///< 帧ID
|
||||
int trace_id; ///< 轨迹ID
|
||||
|
||||
float pitch; ///< 人脸俯仰角
|
||||
float yaw; ///< 人脸偏航角
|
||||
float roll; ///< 人脸翻滚角
|
||||
} SUFFIX(Yt_tracked_face);
|
||||
|
||||
/**
|
||||
* @brief 获取sdk版本
|
||||
*
|
||||
* @return yt_sdk_version
|
||||
*/
|
||||
YT_PUBLIC const char *SUFFIX(Yt_face_tracker_get_version)();
|
||||
|
||||
/**
|
||||
* @brief 创建实例,每个线程需要单独的实例
|
||||
*
|
||||
* @param[out] handle 创建的handle,每个线程需要独立的handle
|
||||
* @param[in] model_dirpath 传入模型绝对路径或者相对路径,例如:./model/
|
||||
* @param[in] config_filename 传入模型绝对路径或者相对路径下的配置文件名称,例如:config.ini
|
||||
* @param[in] param 模型初始化参数,其中的image_width、image_height和image_pading属性要根据视频长宽调整
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_create_handle)(yt_handle *handle, const char *model_dirpath, const char *config_filename);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/asset_manager.h>
|
||||
/**
|
||||
* @brief 创建实例,每个线程需要单独的实例,该接口用于 android 加载 assets 目录下模型文件
|
||||
* 如有 jni 开发需求,可以通过此接口加载模型
|
||||
*
|
||||
* @param[in] mgr 通过 `AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);` 获得
|
||||
* @param[in] model_dirpath 传入模型相对于 `assets` 目录的路径,例如:`models/face-xxx`
|
||||
* @param[in] config_filename 传入模型路径下的配置文件名称,例如:`config.ini`
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_create_handle_android)(yt_handle *handle, AAssetManager *mgr, const char *model_dirpath, const char *config_filename);
|
||||
#endif
|
||||
|
||||
#ifdef UNIVERSE_IO
|
||||
# include "io.hpp"
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_create_handle_io)(yt_handle* handle, const char* model_dirpath, const char* config_filename, IO* io);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 销毁实例
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
*/
|
||||
YT_PUBLIC void SUFFIX(Yt_face_tracker_destroy_handle)(yt_handle handle);
|
||||
|
||||
/**
|
||||
* @brief 获取参数
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[out] param 当前实例的参数
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_get_param)(yt_handle handle, SUFFIX(Yt_face_tracker_param) *param);
|
||||
|
||||
/**
|
||||
* @brief 设置参数,推荐先获取参数,再设置
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] param 自定义的参数
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_set_param)(yt_handle handle, const SUFFIX(Yt_face_tracker_param) param);
|
||||
|
||||
/**
|
||||
* @brief 追踪接口,适合于视频流检测,内部封装了检测、5点配准、稳定模块,具有内部状态
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @param[in] image 图片,图片类型:YT_IMG_BGR_8UC3 or YT_IMG_RGB_8UC3
|
||||
* @param[out] tracked_faces 人脸追踪结果
|
||||
* @param[out] tracked_faces_count 检测到的人脸数量
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_track)(yt_handle handle, const yt_image image, SUFFIX(Yt_tracked_face) **tracked_faces, int *tracked_faces_count);
|
||||
|
||||
/**
|
||||
* @brief 重置追踪接口,当对新的视频进行追踪时调用,用于清空追踪内部状态
|
||||
*
|
||||
* @param[in] handle 实例句柄
|
||||
* @return YT_SUCCESS:成功,其他:失败
|
||||
*/
|
||||
YT_PUBLIC int SUFFIX(Yt_face_tracker_reset)(yt_handle handle);
|
||||
|
||||
/**
|
||||
* @brief 释放人脸追踪结果
|
||||
*
|
||||
* @param[in] tracked_faces 人脸追踪结果
|
||||
*/
|
||||
YT_PUBLIC void SUFFIX(Yt_face_tracker_release_tracked_faces)(SUFFIX(Yt_tracked_face) *tracked_faces);
|
||||
|
||||
#endif // _YT_FACE_TRACKER_H_
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>YTFaceTracker</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.youtu.tracker</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>YTFaceTrackerLiveness</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>v3.0.5-mini.16</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>v3.0.5-mini.16</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// YtSDKKitFrameworkTool.h
|
||||
// YtSDKKitFrameworkTool
|
||||
//
|
||||
// Created by sunnydu on 2022/10/12.
|
||||
// Copyright © 2022 Tecnet.Youtu. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface YtSDKTool : NSObject
|
||||
#define T_FRAMEWORK_VERSION "1.1.15.175.1";
|
||||
/**
|
||||
获取YtSDKKitFrameworkTool*/
|
||||
+(NSString*) getFrameworkVersion;
|
||||
|
||||
/**
|
||||
慧眼版本
|
||||
*/
|
||||
+(void) setHuiYanVersion:(NSString*)huiyanVersion;
|
||||
/**
|
||||
远程下发模型场景,对算法模型做MD5校验
|
||||
*/
|
||||
+(int) md5ValidityByDir:(NSString*) path;
|
||||
|
||||
/**
|
||||
开启bugly
|
||||
*/
|
||||
+(void) openBuglyShared;
|
||||
|
||||
typedef enum {
|
||||
//验证完成。
|
||||
VALIDITY_OK=11000,
|
||||
//模型文件夹目录为空 或者找不到路径
|
||||
NOT_FOUND_MODEL_DIR=11001,
|
||||
//找不到md5效验文件
|
||||
NOT_FOUND_MODEL_MD5=11002,
|
||||
//读取md5文件异常
|
||||
READ_MD5_ERROR=11003,
|
||||
//效验失败
|
||||
VALIDITY_ERROR=11004,
|
||||
//目标MD5值没有找到
|
||||
TARGET_MD5_NOT_FOUND=11005,
|
||||
//生成md5 失败
|
||||
CREATE_MD5_ERROR=11006,
|
||||
//模型文件存在个别缺失
|
||||
MODEL_FILE_MISS=11007
|
||||
}ModelValidityCode;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user