如何捏出千人千面的虚拟形象,助力开发者快速实现虚拟形象!
2022/10/21

虚拟形象是虚拟世界的核心资产,也是打造元宇宙社交的数字名片,从虚拟形象为切入点,ZEGO Avatar 基于强大的 AI 算法能力,可以为企业提供多元化风格虚拟形象制作及智能互动服务,助力企业打造虚拟形象数字资产,创造多样的玩法体验,支持客户以相对较低的门槛快速进入元宇宙赛道。

上期内容中我们介绍了元宇宙场景下的虚拟直播实践流程,本期内容我们以 iOS 版本为例来讲一讲如何捏出千人千面的虚拟形象,助力开发者快速实现虚拟形象!

前提条件

在实现基本的 Avatar 功能之前,请确保:

  • 已在项目中集成了 Avatar SDK,详情请参考 集成 SDK
  • 已开启摄像头权限。

使用步骤

本节介绍如何使用 ZegoAvatar SDK 实现基本的图像处理功能,API 调用时序如下图:

1申请鉴权

ZEGO Avatar 目前使用 在线鉴权 的方式获取 License 授权文件。

1.1 开通 ZegoAvatar 权限

  • 请先在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 – 项目管理 中的“项目信息”。
  • 请联系 ZEGO 商务人员,提供自己项目的 Bundle Id,开通相关权限。

1.2 获取参考代码

请将从 下载 获取到的示例源码中的 LicenseHelper 文件夹中的代码,拷贝到自己的项目下。

  • 修改 ZegoAvatarConfig.h 文件,请使用已获取的 AppID 和 AppSign 正确填写,否则示例源码无法正常运行。

// 鉴权服务器的地址
static NSString *AVATAR_BASE_URL = @"https://aieffects-api.zego.im?Action=DescribeAvatarLicense";

// 向 ZEGO 申请的 AppID, APPID 跟 Bundle Id 有绑定关系,“Bundle Identifier” 设置为申请 AppID 时所提供的 Bundle Id
static NSUInteger AVATAR_APPID = YOUR_APP_ID;

// 向 ZEGO 申请的得到的 AppSign
static NSString *AVATAR_APP_SIGN = YOUR_APP_SIGN;
  • 在项目中,选择 “TARGETS > Signing & Capabilities” 菜单,将 “Bundle Identifier” 设置为申请权限时所提供的 Bundle Id。

1.3 安装依赖库

  • 打开终端,进入项目根目录,执行 pod 'YTKNetwork'引入依赖库;
  • 执行 pod install 命令安装依赖库。

1.4 获取 License

通过 ZGAvatarLicenseHelper 中的 requestLicense 接口,发起网络请求,获取鉴权 License 字符串。


// 发起网络请求获取 License
[ZGAvatarLicenseHelper requestLicense:^(NSString * _Nonnull license) {
    if (license.length > 0) {

        // 初始化 avatar Service
        [self initAvatarService: license];
    }
}];

2初始化 AvatarService

2.1 初始化 AvatarService 之前,请先导入以下相关的头文件,准备基础工作。

// 引入 头文件
#import 

2.2 导入头文件后,调用 initWithConfig 接口,传入之前获取到的鉴权 License 字符串,初始化 AvatarService。


// 初始化 AvatarService
- (void) initAvatarService: (NSString*) license{
    // 创建 config
    ZegoServiceConfig *config = [[ZegoServiceConfig alloc] init];
    // 将获取到的 License 文件传入
    config.license = license;
    // 指定 AI 模型的路径
    config.AIPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/assets/AIModel.bundle"];
    // 监听初始化状态,addServiceObserver 需要在 "主线程" 执行!!!
    [[ZegoAvatarService sharedInstance] addServiceObserver:self];

    // 初始化 AvatarService
    [[ZegoAvatarService sharedInstance] initWithConfig:config];
}

2.3 注册 onStateChange 回调,接收初始化状态的相关回调通知。


// avatarService初始化状态回调
- (void)onStateChange:(ZegoAvatarServiceState)state {
    // SDK初始化成功
    if (state == ZegoAvatarServiceState_InitSucceed) {
        // 初始化虚拟形象
        [self initAvatar];
    }
}

3创建虚拟形象

注意:在创建虚拟人物形象时,为了简化 Character(虚拟人物形象)的初始化、序列化、数据缓存、路径拼接等功能的接入流程,ZEGO Avatar SDK 提供了 ZegoCharacterHelper 类(开源),帮助开发者快速创建人物虚拟形象,详情请参考 ZegoCharacterHelper 使用说明

初始化 AvatarService 后,通过创建 ZegoCharacterHelper 对象,传入虚拟人物形象的外观数据(捏脸、换装、妆容等),设置视图参数(宽、高、位置等),创建一个虚拟形象。


- (void) initAvatar{
    // 创建 Helper,传入基础资源的路径
    NSString *resourcePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/assets/base.bundle"];
    _characterHelper = [[ZegoCharacterHelper alloc] init:resourcePath];

    // 设置素材资源包地址,如果是动态下载,则传入下载的目标目录
    NSString *packagesPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/assets/Packages"];
    [_characterHelper setExtendPackagesPath:packagesPath];

    // 使用默认形象,以男性角色为例
    [_characterHelper setDefaultAvatar:MODEL_ID_MALE];

    // 创建 AvatarView
    _avatarView = [[ZegoAvatarService sharedInstance] createAvatarView:CGRectMake(0, 0, 200, 200)];
    [self.view addSubview:_avatarView];

    //角色上屏,请保证上屏之前设置过正确的 AvatarJson 数据,即调用过 setDefaultAvatar 或 setAvatarJson 方法。
    [_characterHelper setCharacterView:_avatarView];
}

说明:如果用户不使用默认形象,想要根据图片自动生成定制化的虚拟形象,请参考 AI 捏脸

Avatar 功能拓展

我们已经知道,图像由像素组成,而像素通过记录色彩空间各分量呈现各种各样的色彩。对于 RGB 色彩空间,其三个分量 R(红)、G(绿)、B(蓝),它们之间具有相关性,对于色彩的表示来说缺一不可。

虚拟形象创建完成后,可体验 Avatar 相关功能:

1表情随动

ZEGO Avatar SDK 提供了表情随动功能,基于领先的人脸关键点精准识别,结合面部、舌头、眼球在内的 52 种基础面部表情维度,实时捕获用户脸部的表情动作,在虚拟形象上进行实时的还原渲染。可广泛应用于社交互动、语聊直播等场景中。

开发者请参考以下步骤,实现 “表情随动” 功能:

1.1 开始表情检测

  • 开启表情检测前,请确认已开启摄像头权限;
  • 开发者如果使用了 ZegoCharacterHelper,则无需再调用 IZegoCharacter 的任何相关接口。

搭建出基本的虚拟人物形象后,调用 startDetectExpression 接口,设置驱动模式为 ZegoExpressionDetectModeCamera,通过前置摄像头,开始检测表情;然后可以直接通过 ZegoCharacterHelper的 setExpression 接口设置表情,驱动当前虚拟人物的面部表情变化。

// 开始表情检测
___weak typeof(self) weakSelf = self;
BOOL ret = [[[ZegoAvatarService sharedInstance] getInteractEngine] startDetectExpression:ZegoExpressionDetectModeCamera callback:^(ZegoExpression *expression) {
    // 驱动虚拟人物的脸部变化
    __strong typeof(self) strongSelf = weakSelf;
    [strongSelf.characterHelper setExpression: expression];
}];

1.2 停止表情检测

将应用切换到后台运行、或退出当前页面时,需要调用 stopDetectExpression 接口,停止表情检测。

// 停止表情检测
[[[ZegoAvatarService sharedInstance] getInteractEngine] stopDetectExpression];

2语音驱动

ZEGO Avatar SDK 提供了语音驱动功能,通过声音的声波信息,实时驱动当前虚拟人物的嘴形变化,使得虚拟形象能够和真人一样进行自然的情绪表达。

可广泛应用于社交互动、语聊直播等场景中。

开发者请参考以下步骤,实现 “语音驱动” 功能:

2.1 开始语音检测

  • 开始语音检测前,请确认已开启麦克风权限;
  • 开发者如果使用了 ZegoCharacterHelper,则无需再调用 IZegoCharacter 的任何相关接口。

搭建出基本的虚拟人物形象后,调用 startDetectExpression 接口,设置驱动模式为 ZegoExpressionDetectModeAudio,通过麦克风,开始检测声音波动;然后可以直接通过 ZegoCharacterHelper 的 setExpression 接口设置表情,驱动当前虚拟人物的嘴形变化。


// 开始语音检测
___weak typeof(self) weakSelf = self;
BOOL ret = [[[ZegoAvatarService sharedInstance] getInteractEngine] startDetectExpression:ZegoExpressionDetectModeAudio callback:^(ZegoExpression *expression) {
    // 驱动虚拟人物的嘴形变化
    __strong typeof(self) strongSelf = weakSelf;
    [strongSelf.characterHelper setExpression: expression];
}];

2.2 自定义音频采集

开发者可以调用 setCustomAudioDelegate 接口,设置自定义的音频数据采集代理(需要继承 AudioDataDelegate 实现 onStartonStop 方法)。采集到音频数据后,调用 sendAudioData 接口,发送数据。


@interface ExpressAudioCaptureDelegate()
{
    BOOL _isRunning;
}
@end

@implementation ExpressAudioCaptureDelegate

- (void)onStart{
    // 启动音频采集
    _isRunning = YES;
}

- (void)onStop{
    // 停止音频采集
    _isRunning = NO;
}

// 这是 Express 的自定义声音的前处理回调, 把数据发送给 Avatar SDK
- (void)onProcessCapturedAudioData:(unsigned char * _Nonnull)data dataLength:(unsigned int)dataLength param:(ZegoAudioFrameParam *)param timestamp:(double)timestamp; {
    if(_isRunning){
        // data: pcm的原始数据
        // length: data的长度
        // dataType: data采集的位数  0表示16位,1表示8位
        // timeStamp: 时间戳, 从启动采集到现在经过的时间
        // sendAudioData 是父类方法, 数据透传给 Avatar SDK, RTC 的数据是 8位的, dataType 是 1
        [super sendAudioData: (void*)data  size:dataLength dataType: 1 /* RTC 给的 8bit*/ timeStamp: [super getDurationMs]/*这个方法是父类的,直接调用*/];
    }
}
@end

2.3 停止语音检测

将应用切换到后台运行、或退出当前页面时,需要调用 stopDetectExpression 接口,停止语音检测。

// 停止语音检测
[[[ZegoAvatarService sharedInstance] getInteractEngine] stopDetectExpression];

3手动捏脸

ZEGO Avatar SDK 提供了手动捏脸功能,支持用户根据自己的审美偏好,对虚拟人物形象脸部的各个部位进行细微调节(如眼睛大小、鼻子宽窄、嘴巴大小等),融合成自定义的虚拟人物形象人脸,自由定义,打造独一无二的专属形象,可广泛应用于各类游戏场景中。

开发者请参考以下步骤,实现 “手动捏脸” 功能:

搭建出基本的虚拟人物形象后调用 setFaceShape 接口,传入 faceshapeID(可调整的脸部维度,请参考下表)和 value(捏脸系数)等参数,设置或修改脸部相关位置的形状。我们在 helper/ZegoCharacterHelper.h 中,同样声明了所有可支持调整的脸部维度 faceshapeID。

/** 设置捏脸系数,faceshapeID 值参考下表,并且 ZegoCharacterHelper 内有定义好的常量,可以直接使用。*/
[_characterHelper setFaceShape:FACESHAPE_BROW_SIZE_Y value:0.3];

目前,支持调整的脸部维度可以点击链接查看详情:https://doc-zh.zego.im/article/14959

4AI 捏脸

ZEGO Avatar SDK 提供了AI 捏脸功能,支持通过“摄像头”或者“上传图像”的方式,结合对人脸进行海量分析和训练后的 AI 算法,识别人脸特征,再以美术设计提供的虚拟形象人模为基础,生成与真人高度还原的虚拟形象。可广泛应用于各类游戏场景中。

开发者请参考以下步骤,实现 “AI 捏脸” 功能。

4.1 初始化 AvatarService

请参考 创建虚拟形象 文档,获取鉴权 License 文件;并传入正确的 AIPath,初始化 AvatarService。

4.2 创建虚拟人物形象

准备需要用来创建虚拟人物形象的 UIImage 图片。

  • 推荐使用摄像头拍摄图片。

准备好图片后,调用 detectFaceFeature 接口,传入 UIImage,即可生成该图片对应的虚拟人物形象。

// 根据传入的图片,提取人脸特征
ZegoFaceFeature *feature = [[[ZegoAvatarService sharedInstance] getInteractEngine] detectFaceFeature:image];
  • 如果 UIImage 中检测不到人脸,调用 detectFaceFeature 接口会直接返回 nil。

4.3 设置捏脸数据

创建出虚拟人物形象后,调用 ZegoCharacterHelper 的 applyFaceFeature 接口,传入 feature(设置的脸部维度,可设置的维度请参考下表),设置脸部相关位置的形状。

// 根据人脸特征,设置人物外形
[_characterHelper applyFaceFeature:feature];

目前,支持调整的脸部维度可以点击链接查看详情:https://doc-zh.zego.im/article/14972

5妆容换装

ZEGO Avatar SDK 提供了多种妆容配饰(如美瞳、口红、眼镜、胡子、服装等)等美术素材,支持在虚拟形象上实时渲染、自然替换,打造符合自己品味的专属形象。

开发者请参考以下步骤,实现 “换妆容、换服装” 功能。

目前,支持调整的维度有:眉毛、刺青、嘴唇、胡子、美瞳、眼镜、耳机、耳饰、头发、服装等。具体的支持维度和资源类型,请咨询 ZEGO 商务人员。

开发者如果使用了 ZegoCharacterHelper,则无需再调用 IZegoCharacter 的任何相关接口。虽然 IZegoCharacter 也有同名的 setPackage 接口,但请不要直接调用。如果跳过 ZegoCharacterHelper 直接调用 IZegoCharacter 的接口,ZegoCharacterHelper 层的缓存将不再可信。

搭建出基本的虚拟人物形象后:

  • 如果开发者把 Packages 资源包做成动态下载,则需要在使用 Packages 前,调用 ZegoCharacterHelper 的 setExtendPackagesPath 接口设置 Packages 的下载目录到参数 downloadPath,以便资源索引。

downloadPath 需指到 Packages 文件夹,例如:/Documents/downloads/Package/。

  • 调用 setPackage 接口,传入 packageID,调整虚拟人物相关位置的外观。

//确保换装调用前已经设置的外部 Packages 的目录
[_characterHelper setExtendPackagesPath:downloadPath]
/** 调用换装接口*/
NSString *packageID = @"earphone7";  //earphone7 是一款耳机资源的目录名称,使用 Zego 提供的 Pacakges 下的目录名称即可。
[_characterHelper setPackage:packageID];

demo 展示

元宇宙是人类对于未来社会的美好想象,而虚拟人则是人类对于未来“Better me”的美好寄托。ZEGO 即构科技为用户定制个性化的虚拟形象,从技术底层为开发者赋能,与元宇宙生态里的所有成员一起,让元宇宙的理想进程推进得再快、再稳一些。如需体验 Avatar可点击链接进行下载

扫一扫,获取更多服务与支持
热门推荐
H.264 与 H.265 视频编解码器的区别,哪个更好?
2024/07/26
直播产品中的“六边形战士”来了!ZEGO 超低延迟直播,高质量带来新增长!
2024/07/23
什么是抖动?如何使用抖动缓冲区来减少抖动
2024/07/22
热门标签
AI 降噪
AI课堂
ExpressSDK
MSDN
RTI
SEI
webrtc
ZIM
互动白板
即构融资
在线KTV
在线K歌
屏幕共享
录屏采集
数智人
直播技术
范围语音
行业报告
语聊房
语音社交
超分
音视频
音视频开发
音视频技术
音频编码
关注我们
获得更多服务与支持了解价格与优惠 扫码关注我们
关注我们
获得更多服务与支持了解价格与优惠 扫码关注我们