You need to enable JavaScript to run this app.
导航
Android(v4.1.0.0及以上)
最近更新时间:2022.02.28 19:42:09首次发布时间:2022.02.25 17:16:51
项目中加入SDK
  1. 打开压缩包 byted_effect_andr.zip,找到 effect-SDKXXX.aar 文件
  2. 拷贝其到项目中的主模块(一般是 app)的 libs 目录下,如拷贝到 app/libs/ 目录(没有 libs 文件夹,可手动创建)
  3. 打开主模块(一般是 app)下的 build.gradle,在 android 下加入 SDK 查询路径:
repositories {
        flatDir {
            dirs 'libs'
        }
}
  1. 然后在主模块的 build.gradle 中的 dependencies 下加入 SDK 引用,implementation(name: 'effect-sdkXXX', ext: 'aar')
  2. 添加素材,将提供的素材包(一般是 resource 文件夹)拷贝到项目的 assets 中
代码中集成SDK

以下指南针对使用 sample 中封装的 Java 代码进行集成,如果直接在项目中使用 CV SDK 提供的 C 接口集成,参见 接口说明-特效接口说明-算法

准备阶段

  1. 拷贝 androidsample 项目中的 com.bytedance.labcv.core 模块到自己的工程中,core模块是 SDK 的调用封装。特效相关的调用封装在EffectManager类中;基础算法相关的封装在algorithm目录下,xxxTask代表不同算法的封装;画质算法相关的调用封装在ImageQualityManager类中。
  2. 将素材拷贝代码 com.bytedance.labcv.demo.task.UnzipTask 及相关逻辑应用到自己项目中(没有此步骤,素材无法使用),更多内容参见 素材拷贝说明
  3. (可选)SDK版本为v4.2.1及以上的情况,需要将EffectLicenseHelper.java中的_licenseMode设置为LICENSE_MODE_ENUM.OFFLINE_LICENSE,并依据绑定了自身应用包名的license的名字修改Config.LICENSE_NAME。

以上为主要接口,以上代码可能会对 sample 中的其他代码有依赖,可将这些也拷贝到自己项目中。

使用阶段

以特效SDK为例,特效SDK 的统一封装接口为 EffectManager,SDK 的使用可以分为三个阶段:

  1. 初始化 特效SDK
  2. 使用 特效SDK 进行图像处理
  3. 特效SDK 参数设置,如设置美颜、贴纸、滤镜等

注意,SDK 的所有操作都应该在 openGL 线程中执行。如果是在推流 SDK 中集成,一般直接在推流 SDK 提供的自定义美颜接口中进行即可,如果是本地环境,一般与 GLSurfaceView 一起使用,并在它提供的 openGL 环境中使用 CV SDK。

1.初始化特效SDK

初始化的调用时机一般在 openGL 环境初始化完成后,如在 onSurfaceCreated 中(如使用推流 SDK,一般在推流 SDK 提供的初始化自定义美颜的接口)执行,需要调用的函数为:

mEffectManager = new EffectManager(this, new EffectResourceHelper(this));
mEffectManager.setOnEffectListener(this);
int ret =  mEffectManager.init();

2.使用 SDK 进行特效处理

支持的输入数据类型

支持的数据类型支持的数据格式
textureOES,2D

图像处理的调用,在 onDrawFrame 中执行(如果使用推流 SDK,可在推流 SDK 提供的接口中调用),对应的函数为:

// 将输入纹理转换出人脸为正的2D纹理
 ProcessInput input = transToPortrait();
 // 准备帧缓冲区纹理对象
 int dstTexture = mImageUtil.prepareTexture(input.getWidth(), input.getHeight());
 // 执行特效处理,输出的纹理是人脸为正的2D纹理
  boolean ret = mEffectManager.process(input.getTexture(),dstTexture, input.getWidth(),input.getHeight(),input.getSensorRotation(), mImageSourceProvider.getTimestamp());
        

补充说明:
如果推流SDK默认接收的输入纹理是原始带有旋转角度的纹理,为了适配推流SDK,可以参考调用如下代码,将特效SDK输出的纹理转回原始的角度。

ImageUtil.Transition transition = new ImageUtil.Transition().rotate(mImageSourceProvider.getOrientation()).flip(false, mImageSourceProvider.isFront()).reverse();
 int texture = mImageUtil.transferTextureToTexture(dstTexture,BytedEffectConstants.TextureFormat.Texure2D,
                       input.getWidth(), input.getHeight(),transition);               

process接口参数说明:

参数名含义
srcTexture输入纹理ID,需要确保该纹理是一张人脸为正的图像,如果是前置摄像头,需要同时完成镜像处理
dstTexture输出纹理ID
width输入纹理宽度
height输入纹理高度
sensorRotation手机角度,通过手机传感器取得
timeStamp当前时间,参见 timeStamp获取

处理结果:

process 方法的输出为渲染后的 2D 纹理。

注意,不推荐使用 SDK 直接处理 buffer,SDK 最终需要接收的是待处理纹理,如需要处理 buffer,建议先将 buffer 转成纹理使用,但这会造成耗时增加。

3.SDK 参数设置,如设置美颜、贴纸、滤镜等

注意,SDK 参数设置需要在初始化之后调用,请尽量与 SDK图像处理 处于同一线程使用,以避免可能出现的问题。

(1)设置美颜、美型、美妆

美颜、美型、美妆的设置使用的是同一个接口,一般来说使一个美颜生效需要两步:

第一步:设置素材对应的路径
第二步:设置素材中,特效的强度(一般强度默认为 0,所以这一步不执行会没有效果)

设置素材路径接口

/**
 * 设置特效组合,目前支持美颜、美形、美体、 美妆特效的任意叠加
 */
boolean setComposeNodes(String[] nodes);

// 示例
mEffectManager.setComposeNodes(new String[]{"beauty_Android_live"});

此处的素材路径,是相对于 ComposeMakeup.bundle/ComposeMakeup 的路径,素材包结构参见 素材包结构说明

注意,SDK 内部不会保存已设置的素材,所以此方法每次调用都需要将所有需要生效的素材路径加上。

设置素材中,特效强度接口

/**
 * 更新组合特效(美颜、美形、美体、 美妆)中某个节点的强度
 */
boolean updateComposerNodeIntensity(String node, String key, float intensity);

// 示例
mEffectManager.updateComposerNodeIntensity("beauty_Android_live", "whiten", 0.8f);

以美颜素材为例,需要通过 key 来控制我们要修改的是美白、磨皮还是锐化的强度,素材中 key 与功能的对应关系参见 素材key对应说明

(2)设置贴纸

设置贴纸接口

/**
 * 开启或者关闭贴纸 如果path为空 关闭贴纸
 * @param path 贴纸素材的文件路径
 */
boolean setSticker(String path);

// 示例
mEffectManager.setSticker("baibianfaxing");

此处的贴纸路径为素材包中 StickerResource.bundle/stickers 中的相对路径。

(3)设置滤镜

/**
 * 开启或者关闭滤镜 如果path为空 关闭滤镜
 *
 * @param path path of filter file 滤镜资源文件路径
 */
boolean setFilter(String path);

/**
 * 设置滤镜强度
 *
 * @param intensity intensity 参数值
 */
boolean updateFilterIntensity(float intensity);

// 示例
mEffectManager.setFilter("Filter_01_38");
mEffectManager.updateFilterIntensity(0.8f);

此处的滤镜路径为素材包中 FilterResource.bundle/Filter 中的相对路径。

4.SDK 基础算法功能使用

以人脸算法为例:
人脸算法的调用封装在FaceAlgorithmTask中
1.算法初始化

public int initTask()

返回值表示初始化结果。

2.算法检测

public BefFaceInfo process(ByteBuffer buffer, int width, int height, int stride, BytedEffectConstants.PixlFormat pixlFormat, BytedEffectConstants.Rotation rotation)

3.算法参数设置

算法参数设置的函数定义为:

public void setConfig(AlgorithmTaskKey key, Object p)

其中 key表示参数的类型,p 为参数值,每一个算法的参数类型可以在算法的定义中看到,如key可以使用 FACE_280、FACE_ATTR 这几种。

启用FaceAlgorithmTask则需在AlgorithmTaskFactory进行注册。

AlgorithmTaskFactory.register(FaceAlgorithmTask.FACE, new AlgorithmTaskFactory.AlgorithmTaskGenerator<FaceAlgorithmTask.FaceResourceProvider>() {
            @Override
            public AlgorithmTask<FaceAlgorithmTask.FaceResourceProvider, ?> create(Context context, FaceAlgorithmTask.FaceResourceProvider provider) {
                return new FaceAlgorithmTask(context, provider);
            }
        });
附录:素材拷贝说明

android 中内置素材时是把素材放到 asset 中,这里面的文件内容无法通过路径获取,所以 sample 中的做法是在初次启动 app 时将其拷贝到应用私有目录中,通过 com.bytedance.labcv.demo.task.UnzipTask 完成,如果需要拷贝的素材过多,可能会导致启动时间太长,对此有以下参考方法:

  1. 只将一些很简单的素材,如美颜、美型等内置
  2. 贴纸这种比较大的,可以做成在线下发,在 app 需要用到的时候通过网络下载到本地,既可以降低包大小,也可以提升启动速度
附录:timeStamp 获取

如果是使用相机采集数据,并使用了 SurfaceTexture 作为输出数据容器,可以直接调用它的 getTimestamp 方法:

long timeStamp = surfaceTexture.getTimestamp();

否则使用系统方法:

long timeStamp System.currentTimeMillis();
附录:ImageSource 类型

三种不同的类型主要在与对于输入纹理的处理和绘制上的区别,具体看下面。

类型区别输出纹理
TYPE_CAMERA会根据传进来的 srcTextureFormat、 cameraRotation 和 sensorRotation 对纹理做旋转,更容易保证效果正确,但由于需要两次旋转,性能较差输出纹理与输入纹理方向相同
TYPE_VIDEO会根据传进来的 srcTextureFormat 和 videoRotation 对纹理做旋转,需要做一次旋转输出纹理保持为正向,不一定与输入纹理同方向
TYPE_IMAGE不对纹理做预处理,需要保证传进来的纹理是 2D 且人脸是正的方向,相对的性能也更好输出与输入同向,未做任何旋转
附录:算法 key 与返回结果类型一览
算法key返回结果
人脸检测FaceAlgorithmTask.FACE
FaceAlgorithmTask.FACE_280(280 点) FaceAlgorithmTask.FACE_ATTR(人脸属性) FaceAlgorithmTask.FACE_MASK(人脸 mask) FaceAlgorithmTask.MOUTH_MASK(嘴唇 mask) FaceAlgorithmTask.TEETH_MASK(牙齿 mask)
com.bytedance.labcv.effectsdk.BefFaceInfo
人脸比对FaceVerifyAlgorithmTask.FACE_VERIFYcom.bytedance.labcv.core.algorithm.FaceVerifyAlgorithmTask.FaceVerifyCaptureResult
AnimojiAnimojiAlgorithmTask.ANIMOJIcom.bytedance.labcv.effectsdk.BefAnimojiInfo
C1 场景分类C1AlgorithmTask.C1com.bytedance.labcv.effectsdk.BefC1Info
C2 场景分类C2AlgorithmTask.C2com.bytedance.labcv.effectsdk.BefC2Info
车辆检测CarAlgorithmTask.CAR_ALGO CarAlgorithmTask.CAR_RECOG(车辆检测) CarAlgorithmTask.BRAND_RECOG(车牌检测)com.bytedance.labcv.effectsdk.BefCarDetectInfo
专注度检测ConcentrateAlgorithmTask.CONCENTRATIONcom.bytedance.labcv.core.algorithm.ConcentrateAlgorithmTask.BefConcentrationInfo
视线估计GazeEstimationAlgorithmTask.GAZE_ESTIMATIONcom.bytedance.labcv.effectsdk.BefGazeEstimationInfo
头发分割HairParserAlgorithmTask.HAIR_PARSERcom.bytedance.labcv.effectsdk.HairParser.HairMask
手势检测HandAlgorithmTask.HANDcom.bytedance.labcv.effectsdk.BefHandInfo
人头分割HeadSegAlgorithmTask.HEAD_SEGMENTcom.bytedance.labcv.effectsdk.BefHeadSegInfo
距离估计HumanDistanceAlgorithmTask.HUMAN_DISTANCEcom.bytedance.labcv.effectsdk.BefDistanceInfo
光线分类LightClsAlgorithmTask.LIGHT_CLScom.bytedance.labcv.effectsdk.BefLightclsInfo
宠物脸检测PetFaceAlgorithmTask.PET_FACEcom.bytedance.labcv.effectsdk.BefPetFaceInfo
人体分割PortraitMattingAlgorithmTask.PORTRAIT_MATTINGcom.bytedance.labcv.effectsdk.PortraitMatting.MattingMask
骨骼检测SkeletonAlgorithmTask.SKELETONcom.bytedance.labcv.effectsdk.BefSkeletonInfo
天空分割SkySegAlgorithmTask.SKY_SEGMENTcom.bytedance.labcv.effectsdk.BefSkyInfo
视频分类VideoClsAlgorithmTask.VIDEO_CLScom.bytedance.labcv.effectsdk.BefVideoClsInfo
运动分类ActionRecognitionAlgorithmTask.ACTION_RECOGNITIONcom.bytedance.labcv.effectsdk.BefActionRecognitionInfo