AR Scene 技术文档
说明:
AR Scene开发在拍摄和编辑上有不同的实现,这两种方式略有不同,本文档以拍摄为例进行讲述。
概述
1.1、AR Scene介绍
AR Scene技术是AR技术的一个分支,将虚拟信息与真实世界巧妙融合,创造出相关场景,将定制好的场景和实物交融,使效果逼真形象。底层原理是模式识别、轮廓识别、流媒体渲染技术,实现对真实世界的增强。AR Scene是通过场景进行现实增强,有效的呈现出增强世界的内容。
互联网视频中,AR Scene非常常用,通过修饰,构造形象。增强趣味性和动态性。在短视频与直播领域,AR Scene使用更加广泛,成为今天移动视频技术重要的一环。
从技术本质上讲,AR Scene的本质是对GPU的编程,把编辑、合成、字幕、特效、动画等各种效果融为一体。从一定程度上讲,AR Scene是视频合成渲染技术,需要专业的编辑渲染合成操作,美摄科技多年深耕,研发高效SDK、视频捕捉时动态合成,使用户快速的生成,个性化高质量视频或图片。符合互联网时代对视频增强的要求。
1.2、美摄SDK对AR Scene功能的支持
美摄SDK通过多媒体和三维建模,在桌面端、Web端、移动端都对AR Scene提供了完整的支持。
目前美摄SDK AR Scene功能主要偏重于人脸轮廓检测,定位人脸的边界,在检测后添加相关场景或者对人脸现有部分进行改变。后期美摄AR Scene技术将会有更多的支持,更细腻的处理。
1.3、AR Scene整体结构
说明:磨皮(1/2/3),美型(1/2),美白(A/B)在本文档主题7中有解释。
2、AR Scene的使用
AR Scene 特效使用是基于人脸点位的特技效果,集成使用流程一般都需要三个步骤:
- 1.模型初始化
- 2.添加AR Scene特技
- 3.调节特技的参数
2.1、美颜、美型、美妆以及道具,使用的时候都需要模型的初始化,这个是前置操作。
下面是模型的初始化流程
mCanUseARFaceType = NvsStreamingContext.hasARModule();
首先判断是否包含AR功能,如果包含再去初始化模型文件,否则会初始化失败
如果包含AR功能,接下来就可以进行模型初始化操作,**模型初始化操作涉及文件拷贝耗时操作,建议放在子线程去出处理。**
基础模型初始化部分:
modelPath = "/facemode/ms/ms_face_v1.2.2.model";
faceModelName = "ms_face_v1.2.2.model";
className = "facemode/ms";
if (BuildConfig.FACE_MODEL == 240) {
modelPath = "/facemode/ms/240/ms_face240_v2.0.0.model";
faceModelName = "ms_face240_v2.0.0.model";
className = "facemode/ms/240";
}
licensePath = "";
boolean copySuccess = FileUtils.copyFileIfNeed(MainActivity.this, faceModelName, className);
Logger.e(TAG, "copySuccess-->" + copySuccess);
File rootDir = getApplicationContext().getExternalFilesDir("");
if (AndroidOS.USE_SCOPED_STORAGE) {
rootDir = getApplicationContext().getFilesDir();
}
String destModelDir = rootDir + modelPath;
boolean initSuccess = NvsStreamingContext.initHumanDetection(MSApplication.getContext(), destModelDir, licensePath,
NvsStreamingContext.HUMAN_DETECTION_FEATURE_FACE_LANDMARK | NvsStreamingContext.HUMAN_DETECTION_FEATURE_FACE_ACTION);
Logger.e(TAG, "initSuccess-->" + initSuccess);
if (BuildConfig.FACE_MODEL == 240) {
String pePath = "assets:/facemode/ms/240/pe240_ms_v1.0.0.dat";
boolean peSuccess = NvsStreamingContext.setupHumanDetectionData(NvsStreamingContext.HUMAN_DETECTION_DATA_TYPE_PE240, pePath);
Logger.e(TAG, "ms240 peSuccess-->" + peSuccess);
}
上面是基础人脸的模型初始化部分,基本上只要用到AR功能都需要初始化这部分。如果只使用的是106点位,可以不用初始化这个pe240_ms_v1.0.0.dat。
个性功能的模型初始化,按照增加的功能进行初始化就可以。
String fakeFacePath = "assets:/facemode/common/fakeface.dat";
boolean fakefaceSuccess = NvsStreamingContext.setupHumanDetectionData(NvsStreamingContext.HUMAN_DETECTION_DATA_TYPE_FAKE_FACE, fakeFacePath);
Logger.e(TAG, "fakefaceSuccess-->" + fakefaceSuccess);
String makeUpPath2 = "assets:/facemode/common/makeup2_106_v1.0.0.dat";
if (BuildConfig.FACE_MODEL == 240) {
makeUpPath2 = "assets:/facemode/common/makeup2_240_v1.0.0.dat";
}
boolean makeupSuccess2 = NvsStreamingContext.setupHumanDetectionData(NvsStreamingContext.HUMAN_DETECTION_DATA_TYPE_MAKEUP2, makeUpPath2);
Logger.e(TAG, BuildConfig.FACE_MODEL + "makeupSuccess-->" + makeupSuccess2);
String segPath = "assets:/facemode/ms/ms_humanseg_v1.0.7.model";
boolean segSuccess = NvsStreamingContext.initHumanDetectionExt(MSApplication.getContext(),
segPath, null, NvsStreamingContext.HUMAN_DETECTION_FEATURE_SEGMENTATION_BACKGROUND);
Logger.e(TAG, "ms segSuccess-->" + segSuccess);
String halfBodyPath = "assets:/facemode/ms/ms_halfbodyseg_v1.0.6.model";
boolean halfBodySuccess = NvsStreamingContext.initHumanDetectionExt(MSApplication.getContext(),
halfBodyPath, null, NvsStreamingContext.HUMAN_DETECTION_FEATURE_SEGMENTATION_HALF_BODY);
Logger.e(TAG, "ms halfBodySuccess-->" + halfBodySuccess);
String segSkyPath = "assets:/facemode/ms/ms_skyseg_v1.0.0.model";
boolean segSkySuccess = NvsStreamingContext.initHumanDetectionExt(MSApplication.getContext(),
segSkyPath, null, NvsStreamingContext.HUMAN_DETECTION_FEATURE_SEGMENTATION_SKY);
Logger.e(TAG, "ms segSkySuccess-->" + segSkySuccess);
String handPath = "assets:/facemode/ms/ms_hand_v1.0.0.model";
boolean handSuccess = NvsStreamingContext.initHumanDetectionExt(MSApplication.getContext(),
handPath, null, NvsStreamingContext.HUMAN_DETECTION_FEATURE_HAND_LANDMARK | NvsStreamingContext.HUMAN_DETECTION_FEATURE_HAND_ACTION);
Logger.e(TAG, "ms handSuccess-->" + handSuccess);
modelPath = rootDir + "/facemode/common/ms_expression_v1.0.2.model";
faceModelName = "ms_expression_v1.0.2.model";
String expressionModel = "facemode/common";
FileUtils.copyFileIfNeed(MainActivity.this, faceModelName, expressionModel);
NvsStreamingContext.initHumanDetectionExt(MSApplication.getContext(),
modelPath,
null,
NvsStreamingContext.HUMAN_DETECTION_FEATURE_AVATAR_EXPRESSION);
模型介绍:
- fakeface.dat : 假脸模型初始化,凡是道具里边特效**跟随脸部运动**的都需要初始化这个模型,比如如果使用道具里边的面具效果等。
- makeup2_106_v1.0.0.dat:106点位的美妆模型,如果需要集成美妆的功能需要初始化这个模型文件。
- makeup2_240_v1.0.0.dat:240点位的美妆模型文件。
- ms_humanseg_v1.0.7.model:人像背景分割模型,使用到**扣像背景**功能需要初始化这个模型,如果是全身的场景使用这个效果比较好。
- ms_halfbodyseg_v1.0.6.model:半身人像分割模型,这个也是对**扣像背景**功能的支持的,当人像是半身的时候使用这个模型初始化效果比较好。
- ms_skyseg_v1.0.0.model:天空分割模型,这个模型是专门使用于**天空分割功能**,如果不涉及这个场景不需要加载这个模型。
- ms_hand_v1.0.0.model: 手势点位模型,道具里边使用需要**跟随手指动**的特效需要加载这个模型,比如比心效果等。
- ms_expression_v1.0.2.model:avatar模型,**跟随表情动**的特效需要加载这个模型,比如道具里边的狐狸效果等。
以后的模型都是为了支持个性功能,如果没有用到是不需要加载的,以免增加不必要的内存开销。
2.2、特技的创建
有了前面的前置操作,下面就正式进入AR功能的接入操作,以拍摄添加AR Scene特技为例
private void initArsceneEffect(boolean isOpenArsceneEffect) {
if (isOpenArsceneEffect && mArSceneFaceEffect == null) {
mArSceneFaceEffect = mStreamingContext.appendBuiltinCaptureVideoFx(Constants.AR_SCENE);
}
boolean singleBufferMode = parameterValues.isSingleBufferMode();
if (mArSceneFaceEffect != null) {
if (BuildConfig.FACE_MODEL == 240) {
mArSceneFaceEffect.setBooleanVal("Use Face Extra Info", true);
}
mArSceneFaceEffect.setBooleanVal(Constants.MAX_FACES_RESPECT_MIN, true);
mArSceneFaceEffect.setBooleanVal("Beauty Effect", true);
mArSceneFaceEffect.setBooleanVal("Face Mesh Internal Enabled", true);
mArSceneFaceEffect.setBooleanVal("Advanced Beauty Enable", true);
mArSceneFaceEffect.setBooleanVal("Single Buffer Mode", true);
}
}
上面是effect的创建以及一些开关设置,这些也是按使用到的具体功能进行设置的。由于底层是需要render操作,如果没有用到不要开启,这样可以减少内存以及cpu的消耗。
2.3美颜功能集成
美颜的集成很简单,只需要调节相应的特技的强度就可以看到效果。比如磨皮的添加
mArSceneFaceEffect.setFloatVal("Beauty Strength", 0.6);
这样就可以看到磨皮的效果了,美颜这块的特技都是这样的集成方式。
凡是**带Advanced 的都是是高级美颜**,如果需要使用都需要将高级美颜开关打开。
另外有一个特殊的就是高级磨皮
mArSceneFaceEffect.setFloatVal("Advanced Beauty Intensity", 0.5);
这样就添加了一个高级磨皮的效果了。
部分美颜的整理
| 美颜类别 | 名称 | 参数区间 |
| Beauty Strength | 磨皮 | (0,1) |
| Advanced Beauty Remove Nasolabial Folds Intensity | 法令纹 | (0,1) |
| Advanced Beauty Remove Dark Circles Intensity | 黑眼圈 | (0,1) |
| Advanced Beauty Brighten Eyes Intensity | 亮眼 | (0,1) |
| Advanced Beauty Whiten Teeth IntensityAdvanced Beauty Whiten Teeth Intensity | 美牙 | (0,1) |
| Advanced Beauty Intensity | 高级磨皮 | (0,1) |
2.4美型的使用
美型效果是一个特效包,使用这类效果就修要比美颜多一个步骤:特效包的安装操作。
//安装特效包
StringBuilder sb = new StringBuilder();
String assetPath="assets:/beauty/shapePackage/3632E2FF-8760-4D90-A2B6-FFF09C117F5D.1.facemesh";
int i = mStreamingContext.getAssetPackageManager().installAssetPackage(assetPath, null, NvsAssetPackageManager.ASSET_PACKAGE_TYPE_FACE_MESH, false, sb);
if (i != NvsAssetPackageManager.ASSET_PACKAGE_MANAGER_ERROR_NO_ERROR && i != NvsAssetPackageManager.ASSET_PACKAGE_MANAGER_ERROR_ALREADY_INSTALLED) {
return false;
}
//设置美型特效
mArSceneFaceEffect.setStringVal("Face Mesh Nose Length Custom Package Id", sb.toString()); //参数的key和特效包是对应的
mArSceneFaceEffect.setFloatVal("Face Mesh Nose Length Degree", 0.6);//参数的key和特效包是对应的
注意:对特效id的使用以及强度的设置中的key跟特效包是对应的,特效包不一样key是不一样的。
2.5道具的使用
道具特效是一个特效包,同样需要安装。
下面是道具的使用
//道具安装
NvsAssetPackageManager assetPackageManager = mStreamingContext.getAssetPackageManager();
StringBuilder sceneId = new StringBuilder();
String arfacePath="assets:/arface/084A6EC1-43AB-40EF-BBD5-D83F692B011B.3.arscene";
int i = assetPackageManager.installAssetPackage(arfacePath, null,
NvsAssetPackageManager.ASSET_PACKAGE_TYPE_ARSCENE, true, sceneId);
//设置道具效果
mArSceneFaceEffect.setStringVal("Scene Id", sceneId);
这样我们就添加了一个道具效果,非常简单。
如果需要取消到道具效果:
mArSceneFaceEffect.setStringVal("Scene Id", "");
2.7美妆的使用
美妆分为:单妆和妆容。
**单妆**:是一个特效包,效果也是单一的比如嘴唇的口红、眼影、眉毛等,单一的效果。
NvsAssetPackageManager assetPackageManager = mStreamingContext.getAssetPackageManager();
StringBuilder makeupId = new StringBuilder();
String makeupPath="assets:/makeup/07E4CE0F-3AEA-4510-8C23-9267522B7BFE.1.makeup";
int i = assetPackageManager.installAssetPackage(makeupPath, null,
NvsAssetPackageManager.ASSET_PACKAGE_TYPE_MAKEUP , true, uuid);
mArSceneFaceEffect.setIntVal("Makeup Custom Enabled Flag",
NvsMakeupEffectInfo.MAKEUP_EFFECT_CUSTOM_ENABLED_FLAG_ALL);
mArSceneFaceEffect.setColorVal("Makeup " + Id + " Color", new NvsColor(x, x, x,
x));
mArSceneFaceEffect.setFloatVal("Makeup " + Id + " Intensity", x);
mArSceneFaceEffect.setStringVal("Makeup " + Id + " Package Id", uuid);
这样就添加了一个单妆
单妆Id的值如下:
| Id | 名称 |
| Lip | 口红 |
| Eyebrow | 眉毛 |
| Eyeshadow | 眼影 |
| Eyelash | 睫毛 |
| Eyeliner | 眼线 |
| Blusher | 腮红 |
| Shadow | 修容 |
| Brighten | 高光 |
**妆容**:就是几个单妆、美颜以及美型的一个集合,整体调整出来的一个比较好的效果。妆容的接入有一套中间层的API调用,免去了json解析等各种繁琐的操作,可参考sdkdemo。
{
"name": "occident",
"uuid": "76439F13-47FD-4F98-912F-E3B6B2ED7F54",
"version": 1,
"cover": "cover.png",
"minSdkVersion": "3.4.0",
"supportedAspectRatio": "9v16",
"translation": [
{
"originalText": "occident",
"targetLanguage": "zh_CN",
"targetText": "欧美素颜"
}
],
"effectContent": {
"makeupArgs": [
{
"type": "Blusher",
"canReplace": 1,
"className": "Makeup Blusher Package Id",
"uuid": "3821DB49-DBEE-40A8-8064-034E329F5E15",
"value": 1
},
{
"type": "Brighten",
"canReplace": 1,
"className": "Makeup Brighten Package Id",
"uuid": "77C2D7B7-4F32-4E13-92F9-0E85EEA9381D",
"value": 1
},
{
"type": "Shadow",
"canReplace": 1,
"className": "Makeup Shadow Package Id",
"uuid": "F98BFAC3-8CAE-46B4-9098-F6C762E486C3",
"value": 1
},
{
"type": "Eyebrow",
"canReplace": 1,
"className": "Makeup Eyebrow Package Id",
"uuid": "D0F81D94-C66A-4523-8008-48C240D1C1EC",
"value": 0.5
},
{
"type": "Eyeshadow",
"canReplace": 1,
"className": "Makeup Eyeshadow Package Id",
"uuid": "95B37789-078E-4CC5-A017-D6D8F1BE5EC1",
"value": 0.7
},
{
"type": "Eyelash",
"canReplace": 1,
"className": "Makeup Eyelash Package Id",
"uuid": "FF251056-7B07-431F-A9A1-8621813EC57C",
"value": 0.8
},
{
"type": "Eyeliner",
"canReplace": 1,
"className": "Makeup Eyeliner Package Id",
"uuid": "71555D37-11DB-4713-A1A2-687FCD5349A9",
"value": 0.5
},
{
"type": "Lip",
"canReplace": 1,
"className": "Makeup Lip Package Id",
"uuid": "7C854DBE-91D2-4573-8E4C-D60CAF06050B",
"value": 0.8
}
],
"beauty": [
{
"Advanced Beauty Enable": 1,
"Advanced Beauty Type":1,
"canReplace": 1,
"value": 1
},
{
"className": "Beauty Whitening",
"Whitening Lut Enabled": 1,
"canReplace": 1,
"value": 0.3
},
{
"className": "Beauty Reddening",
"canReplace": 1,
"value": 0.2
},
{
"className": "Default Beauty Enabled",
"canReplace": 1,
"value": 0.5
},
{
"className": "Default Sharpen Enabled",
"canReplace": 1,
"value": 0
}
],
"shape": [
{
"uuid": "71C4CF51-09D7-4CB0-9C24-5DE9375220AE",
"type":"Eye Size",
"className": "Face Mesh Eye Size Custom Package Id",
"degreeName":"Face Mesh Eye Size Degree",
"canReplace": 1,
"value": 1
},
{
"uuid": "80AED78B-F31A-4772-8D5E-44E4AABAAE32",
"type":"Face Width",
"className": "Face Mesh Face Width Custom Package Id",
"degreeName":"Face Mesh Face Width Degree",
"canReplace": 1,
"value": 0.8
},
{
"uuid": "FC7C9104-1FDB-483B-BA31-E2D71807E65A",
"type":"Hairline Height",
"className": "Face Mesh Hairline Height Custom Package Id",
"degreeName":"Face Mesh Hairline Height Degree",
"canReplace": 1,
"value": 1
}
],
"microShape": [
{
"uuid": "7425A707-3CD7-40BC-B9F5-D4B61387467D",
"type":"Temple Width",
"className": "Face Mesh Temple Width Custom Package Id",
"degreeName":"Face Mesh Temple Width Degree",
"canReplace": 1,
"value": 0.3
}
],
"filter":[
{
"isBuiltIn": 0,
"canReplace": 1,
"uuid": "4EFE3455-C58D-499C-B311-D445F752D567",
"value": 0.4
}
]
}
}
这就是一个妆容的json数据,json介绍:
- makeupArgs:包含的多个单妆特效
- beauty:包含的多个美颜特效
- shape:包含多个美型的特效
- microShape:包含多个微整形特效(这个就是美颜或者美型)
- filter:包含的多个滤镜滤镜特效
只要解析这个这个json,并将这些特效应用就是妆容的效果。
以上代码片段,来自美摄sdk demo的主页面以及拍摄页面,可以直接参考工程进行集成。