蓝松SDK技术文档
• 此文档由开发人员持续更新,建议您收藏此链接。
• (建议您放到浏览器的书签栏,以方便阅览)
• SDK最新版本:蓝松SDK- 5.0.0
产品说明
绿幕抠图 | • 功能:抠绿算法,工作流程:一帧图像输入,把绿色抠去,输出有透明的一帧图像。 • 适用人群:所有用到抠绿的开发人员。 |
绿幕抠图-图层版 | • 功能:提供抠图算法外,还提供直播场景用到一整套图层处理解决方案,包括:背景视频、背景图片、前景,挂件,nv21输入,纹理surface输入,摄像图输入,图层调节,图层抠绿,图层叠加,图层替换,合并导出等功能。 • 适用人群:无相关图像处理经验的开发人员,或希望我们提供整套解决方案的客户。可一键集成。 |
AI人像抠图 | • 功能:AI人像识别算法,工作流程:一帧图像输入,把图像里的人识别出来,输出除人外都透明的一帧画面。 • 适用人群:用到AI人像识别的开发人员,比如AR,VR,MR,视频会议,无绿幕抠图功能等。 |
AI人像抠图-录制版 | • 功能:提供AI人像抠图外,还提供录制场景中一整套图层处理解决方案,包括:背景视频,背景图片,前景,挂件,图层调节,分段录制,回删,图层调节,合成导出为mp4等。 • 适用人群:无相关图像处理经验的开发人员,或希望我们提供整套解决方案的客户。 |
视频编辑 | • 功能:一整套基于时间轴的视频编辑能力解决方案。 • 适用人群:所有人。可一键集成。 |
自由编辑 | • 功能:提供底层的图层API,类似提供了很多积木,并积木可任意调节配置。 • 适用人群:想自由扩展个性化视频功能的人员。给您最大的灵活度,可有界面,也可无界面(配置好参数导出)。 |
系统和素材格式支持
系统:
1. Android:android6.0+ , Opengles2.0, OpenCL。
2. iOS: iOS9.0+,(AI抠图建议ios13+)
3. windows: window7+
素材格式:
1. 图片: jpg, jpeg, png, heic,webp。
2. 视频: mp4,mov, 分辨率支持 720P,1080P,4K。
3. 动画: GIF,蓝松SDK定义的mv视频, SVGA
4. 声音: mp3,m4a,wav,有声音的mp4文件;
语言支持:
1. android : java, C++
2. ios : object-c;
3. windows:C++,(C#可调用C++ 接口,提供调用demo)
4. 其他1: Flutter:可配置调用android的java或ios的 object-c
5. 其他2:uni-app:可配置调用android的java 或ios的object-c
规格说明:
iOS
1. 最大编辑时长:30分钟
2. 最大图片数量:300张。
3. 最大视频时长:30分钟。
4. 如超过,则会提示无法加载。
Android
1. TODO
集成和授权
蓝松SDK的API设计规律:1+1
1. 为了让API尽可能的简洁:我们严格让功能设计为:1+1 的形式;即一个容器类 + 一个图层类; 2. 容器类是:是放置各种图层的容器,负责预览,编辑,录制,导出,图层增删改查,图层管理等。 3. 图层类是:每个图片、视频、摄像头、gif、贴纸、声音、文字,纹理,外置播放器,外置摄像头等等在增加到我们SDK里后,我们把他封装为一个图层。类似UI布局中的组件。 4. 5. 加一个素材,得到一个对应的图层对象,图层对象可做各种大小位置角度,透明,隐藏,遮罩,调色,滤镜编辑,抠绿,AI抠人,美颜,push数据,切换图片等操作。 6. |
调试 • android中的TAG是LanSongSDK • iOS和Windows 会以LanSongSDK开头的日志 • 可提供过过滤日志的关键字来查看我们的日志输出,我们的每个容器的开启和关闭,会有日志输出。 |
Android集成
1. 导入过程: 在你的项目中点击 File/import module 弹出对话框, 选中LanSongSDK和LanSongAISDK文件夹,点击导入, 然后在你需要调用的module里, 打开build.gradle, 增加 implementation project(':LanSongSDK') implementation project(':LanSongAISDK')
2. 初始化: 把授权文件放到 app的assets文件夹下,在继承Application类的onCreate方法中,调用一下方法:
Markdown String keyName="放在assets里的授权文件名字"; LanSoEditor.initSDK(getApplicationContext(),keyName); LSOBoxMattingTexture.setAiMatting(new LSOAiMattingTextureImpl(new LSOAiMattingVideo())); LSOMattingAuth.loadModel(getApplicationContext(), keyName); |
3. 其他代码的集成:
Markdown 1. 绿幕直播:容器类LSOCameraLive, demo在GreenMattingLiveActivity.java中,规则是:在Activity的 onCreate, onPause,onResume, onDestory中分别加入LSOCameraLive对应的同方法名字,然后大概看LSOCameraLive在GreenMattingLiveActivity.java中的使用即可。大概就是addXXXLayer然后得到一个图层对象,用图层对象去设置各种效果 2. 视频编辑:容器类LSOEditPlayer, demo在VideoEditorDemoActivity.java中,规则是:在Activity的 onCreate, onPause,onResume, onDestory中分别加入LSOEditPlayer对应的同方法名字,然后开启容器即可。 |
4. 代码混淆:
Markdown 如果您要发布的时候混淆代码,则建议不要混淆我们的sdk,混淆规则如下: - (已在 LanSongSDK和LanSongAISDK里的proguard-rules.pro文件中写好) -keep public class com.lansosdk.videoeditor.** { *; } -keep public class com.lansosdk.videoplayer.** { *; } |
iOS集成
1. 把<<LanSongSDK>>和 <<LanSongAISDK>>文件夹拖进您的Xcode中, 并检查Build Phases的Link和Copy中是否有对应的文件.
2. 增加各种系统头文件
Markdown 增加SDK的头文件; - #import <LanSongEditorFramework/LanSongEditor.h> - #import "LanSongAIMatting/VisionSDKMattingAPI.h" - 导入一些系统依赖库:OpenGLES.framework Accelerate.framework Metal.framework,CoreML.framework,VideoToolbox.framework CoreGraphics.framework, CoreVideo.framework CoreMedia.framework, libiconv.tbd,libz.tbd,libbz2.tbd libc++.tbd |
3. 初始化:
○ 把授权文件拖到您项目中,并确保在bundl phases中。
○ 把一下代码复制到AppDelegate.m中的didFinishLaunchingWithOptions方法中.
Markdown //初始化蓝松SDK NSString *path = [[NSBundle mainBundle] pathForResource:@"ios_lansong_end20220801" ofType:@"license"]; [self setupLanSongSDKwithLicense:path];
其中方法是: /// 初始化蓝松SDK /// @param licensePath 授权文件的完整路径 - (void)setupLanSongSDKwithLicense:(NSString *)licensePath { [LanSongContext setOpengles30:YES]; if ([LanSongEditor initSDKWithPath:licensePath] == NO) { NSLog(@"蓝松SDK 初始化失败"); return; }
[LanSongFFmpeg initLanSongFFmpeg]; [LSOFileUtil deleteAllSDKFiles]; [VisionSDKMattingAPI setLicenseWithPath:licensePath]; LSOAiMattingInterface *interface=[[LSOAiMattingInterface alloc] init]; [LSOAiMattingEntry2 setSegmentInput:interface]; } |
Windows集成
1. SDK是一个《LanSongSDK》文件夹,里面有多个文件,其中有dll和模型文件。
2. dll文件采用动态加载库的形式执行,故在您的项目中没有引用和配置,只需要把dll文件和模型文件放到执行文件夹下,并在代码里设置好路径即可。
3. 参考我们demo中的加载dll的形式,把3个方法的指针函数加载进来
Markdown 具体如下: - 声明: t_fn_VisionSDKSegmentAPI_init pfn_VisionSDKSegmentAPI_init; t_fn_VisionSDKSegmentAPI_segmentOneFrame pfn_VisionSDKSegmentAPI_segmentOneFrame; t_fn_VisionSDKSegmentAPI_release pfn_VisionSDKSegmentAPI_release; - 使用 m_hTNNModule = ::LoadLibrary(_T("TNN.dll")); if (NULL == m_hTNNModule) { OutputDebugString(_T("load TNN.dll failed")); return; } pfn_VisionSDKSegmentAPI_init = (t_fn_VisionSDKSegmentAPI_init)GetProcAddress(m_hTNNModule, "?VisionSDKSegmentAPI_init@@YAHPEAX00@Z"); pfn_VisionSDKSegmentAPI_segmentOneFrame = (t_fn_VisionSDKSegmentAPI_segmentOneFrame)GetProcAddress(m_hTNNModule, "?VisionSDKSegmentAPI_segmentOneFrame@@YAHPEAEHH0@Z"); pfn_VisionSDKSegmentAPI_release = (t_fn_VisionSDKSegmentAPI_release)GetProcAddress(m_hTNNModule, "?VisionSDKSegmentAPI_release@@YAXXZ"); if (NULL == pfn_VisionSDKSegmentAPI_init || NULL == pfn_VisionSDKSegmentAPI_segmentOneFrame || NULL == pfn_VisionSDKSegmentAPI_release) { OutputDebugString(_T("GetProcAddress TNN.dll failed")); return; } |
演示工程代码说明
Android:
CSS ── MainActivity.java (主界面) ├── GreenMattingAPIDemoActivity.java (绿幕抠图演示) ├ ├── GreenMattingLiveActivity.java (抠绿抠图-图层版演示) ├ ├── AiMattingAPIDemoActivity.java (AI人像抠图演示) ├ ├── AiMattingRecordDemoActivity.java (AI人像抠图-录制版演示) ├ └── VideoEditorDemoActivity.java (视频编辑演示) ├ └── LayerEditorDemoActivity.java (自由编辑演示) |
iOS :
CSS ── HomeViewController.m (主界面) ├── DemoGreenMattingAPIVC.m (绿幕抠图演示) ├ ├── GmLiveRootViewController.m (抠绿抠图-图层版演示) ├ ├── DemoAiMattingCameraVC.m (AI人像抠图演示) ├ ├── CameraRecordViewController.m (AI人像抠图-录制版演示) ├ └── VideoEditViewController.m (视频编辑演示) ├ └── LayerEditorViewController.m (自由编辑演示) |
API 接口文档说明
绿幕抠图-android
Java public class LSOGreenMatting { public LSOGreenMatting(); /** * 设置抠像强度, 范围是0--100; */ public void setGreenMattingLevel(int level); /** * 获取当前抠图强度 * 范围是0--100; */ public int getGreenMattingLevel(); /** * 获取默认抠图强度 */ public int getGreenMattingDefaultLevel(); /** * 抠绿的保护区域设置 * xStart和xEnd的范围 0.0---1.0; * yStart 和 yEnd的范围是0.0 --1.0; * * @param xStart 横向坐标的开始区域. * @param xEnd 横向坐标的结束区域坐标. 范围是0.0---1.0; 左侧是0.0, 最右侧是1.0; * @param yStart 纵向Y的开始坐标范围是0.0---1.0; 上侧是0.0, 最下侧是1.0; * @param yEnd 纵向Y的结束坐标, 范围是0.0---1.0; 上侧是0.0, 最下侧是1.0; */ public void setGreenMattingProtectRect(float xStart, float xEnd, float yStart, float yEnd); /** * 取消绿幕抠图的区域保护 */ public void cancelGreenMattingProtectRect(); /** * 获取抠绿的最小阈值范围 */ public Range<Float> getMattingGreenMinThresholdRange(); /** * 获取抠绿的最大阈值范围 */ public Range<Float> getMattingGreenMaxThresholdRange(); /** * 设置抠绿的最小阈值; */ public void setMattingGreenMinThreshold(float value); /** * 获取当前抠绿的最小阈值; */ public float getMattingGreenMinThreshold(); /** * 设置抠绿的最大阈值; */ public void setMattingGreenMaxThreshold(float value); /** * 获取抠绿的最大阈值; */ public float getMattingGreenMaxThreshold(); /** * 设置抠蓝的最小阈值范围; * @return */ public Range<Float> getMattingBlueMinThresholdRange(); /** * 设置抠蓝的最大阈值范围; */ public Range<Float> getMattingBlueMaxThresholdRange(); /** * 设置抠蓝的最小阈值 */ public void setMattingBlueMinThreshold(float value); /** * 获取当前抠蓝的最小阈值 */ public float getMattingBlueMinThreshold() ; /** * 设置抠蓝的最大阈值 */ public void setMattingBlueMaxThreshold(float value); /** * 获取当前抠蓝的最大阈值; */ public float getMattingBlueMaxThreshold() ; /** * 获取抠红的最小阈值范围; */ public Range<Float> getMattingRedMinThresholdRange() ; /** * 获取抠红的最大阈值范围; */ public Range<Float> getMattingRedMaxThresholdRange(); /** * 设置抠红的最小阈值; */ public void setMattingRedMinThreshold(float value) ; /** * 获取当前抠红的最小阈值 */ public float getMattingRedMinThreshold() ; /** * 设置抠红的最大阈值; */ public void setMattingRedMaxThreshold(float value); /** * 获取当前抠红的最大阈值 */ public float getMattingRedMaxThreshold() ; /** * 设置抠图类型; * 当前支持 NONE/ GREEN /BLUE/RED; * @param type */ public void setMattingType(LSOGreenMattingType type) ; /** * 执行绿幕抠图 * 此方法工作在opengles语境中. * @param context android的Context的语境可以是getApplicationContext() * @param textureId sample2D类型的纹理, 建议是fbo渲染后的. * @param width 纹理的宽度 * @param height 纹理的高度 * @return 返回渲染后的纹理, 失败则返回-1 */ public int renderOnGPU(Context context, int textureId, int width, int height); ; /** * 执行绿幕抠图 camera环境下. * 此方法工作在opengles语境中. * @param context android的context语境 * @param textureId 输入的相机纹理EXT类型 * @param tmpMatrix 相机获取到的坐标 * @param front 当前是否前置 * @param width 纹理宽度 * @param height 高度 * @return 返回渲染后的纹理,失败则返回-1 */ public int renderCameraExtIdOnGPU(Context context, int textureId, float[] tmpMatrix, boolean front, int width, int height); /** * 释放纹理 * 此方法工作在opengles语境中. */ public void releaseOnGPU(); } |
绿幕抠图-iOS
Objective-C #import <Foundation/Foundation.h> #import "LSOObject.h" NS_ASSUME_NONNULL_BEGIN @interface LSOGreenMatting : LSOObject /** 初始化 */ - (instancetype)init; /** size: 是输入的图像宽高; 如果是竖屏则建议是720x1280 / 1080x1920; 如果是横屏,则建议是1280x720 / 1920x1080;
仅在初始化后,设置一次; 不可多次设置; */ @property (nonatomic, assign)CGSize renderSize; /** 渲染一帧,输入的是sampleBuffer 输出的是CVPixelBuffer; */ - (CVPixelBufferRef)renderOneFrameWithSampeBuffer:(CMSampleBufferRef)sampleBuffer; /** 抠绿一帧 */ - (CVPixelBufferRef)renderOneFrameWithPixelBuffer:(CVPixelBufferRef)pixelBuffer; /** 释放; */ - (void)releaseLSO; /** 设置分割类型, 默认是绿色; 支持绿色/红色/蓝色/无; */ @property (nonatomic, assign) VisionSDKMattingType mattingType; /** 绿幕抠图的调节级别 范围是: 0--1.0f; 0是禁止抠像; 0.1抠的很弱; 0.5适中; 1.0是抠的最强(可能会把一些不是绿的也抠去) */ @property (nonatomic,assign) CGFloat greenMattingLevel; /** 读取默认强度; */ @property (nonatomic,readonly) CGFloat greenMattingLevelDefault; /// 在绿幕抠图的时候, 光线很暗的情况下可能有阴影,这里是设置阴影的百分比. /// 范围是0.0---1.0; 默认是1.0; 0.0是完全消除; 1.0是不消除; @property (nonatomic, assign) CGFloat greenMattingShadowPercent; ///--------------------------------------------抠绿--------------------------------- /// 获取抠绿最小阈值范围start; @property (nonatomic, readonly) CGFloat mattingGreenMin_start; /// 获取抠绿的最小阈值范围end @property (nonatomic, readonly) CGFloat mattingGreenMin_end; /// 获取抠绿的最小阈值默认值; @property (nonatomic, readonly) CGFloat mattingGreenMin_default; /// 设置和获取抠绿的最小阈值 @property (nonatomic,assign) CGFloat mattingGreenMin; /// 获取抠绿的最大阈值范围start; @property (nonatomic, readonly) CGFloat mattingGreenMax_start; /// 获取抠绿的最大阈值end @property (nonatomic, readonly) CGFloat mattingGreenMax_end; /// 获取抠绿的最大阈值默认值; @property (nonatomic, readonly) CGFloat mattingGreenMax_default; /// 设置和获取抠绿的最大阈值 @property (nonatomic,assign) CGFloat mattingGreenMax; ///----------------------------------------------抠蓝(参数含义同抠绿)------------------------------- //调节蓝色抠图最小阈值 @property (nonatomic, readonly) CGFloat mattingBlueMin_start; @property (nonatomic, readonly) CGFloat mattingBlueMin_end; @property (nonatomic, readonly) CGFloat mattingBlueMin_default; @property (nonatomic, assign) CGFloat mattingBlueMin; //调节蓝色抠图最大阈值 @property (nonatomic, readonly) CGFloat mattingBlueMax_start; @property (nonatomic, readonly) CGFloat mattingBlueMax_end; @property (nonatomic, readonly) CGFloat mattingBlueMax_default; @property (nonatomic, assign) CGFloat mattingBlueMax; ///---------------------------------------------抠红(参数含义同抠绿)------------------------------- //调节红色抠图最小阈值 @property (nonatomic, readonly) CGFloat mattingRedMin_start; @property (nonatomic, readonly) CGFloat mattingRedMin_end; @property (nonatomic, readonly) CGFloat mattingRedMin_default; @property (nonatomic, assign) CGFloat mattingRedMin; //调节红色抠图最大阈值 @property (nonatomic, readonly) CGFloat mattingRedMax_start; @property (nonatomic, readonly) CGFloat mattingRedMax_end; @property (nonatomic, readonly) CGFloat mattingRedMax_default; @property (nonatomic, assign) CGFloat mattingRedMax; /// 设置绿色抠图的保护区域. /// 保护区域内不抠图; /// @param startX 横向的开始点, 横向从左到右,分别是0.0---1.0; /// @param endX 横向的结束点, 横向从左到右,分别是0.0---1.0; /// @param startY 竖向的结束点, 从上到下,分别是0.0---1.0; /// @param endY 竖向的结束点, 从上到下,分别是0.0---1.0; -(void)setMattingProtectRect:(CGFloat)startX endX:(CGFloat)endX startY:(CGFloat)startY endY:(CGFloat)endY; /** 取消保护区域 */ -(void)cancelMattingProtectRect; @end NS_ASSUME_NONNULL_END |
AI人像抠图-Android
PHP public class LSOAiMattingCamera { /** * 异步初始化 */ public void initAsync() /** * 异步初始化是否完毕; */ public boolean isReady() /** * 相机是否切换镜头 * 如果是视频抠图,则不需要调用; */ public void changeCameraOnGPU() /** * 对相机camera的抠图 * @param isExt 是否是ext类型的纹理 * @param texture 纹理id * @param tmpMatrix 纹理的matrix坐标 * @param front 当前是否是前置 * @param width 纹理的宽度 * @param height 纹理的高度 * @return 抠图后的纹理, 如失败返回-1; * @throws Exception 其他情况会抛出异常 */ public int mattingTextureOnGPU(boolean isExt, int texture, float[] tmpMatrix, boolean front, int width, int height) throws Exception; /** * sample2D类型的纹理; * [图片抠图用到] * @param textureId 纹理 * @param width 纹理宽度 * @param height 纹理高度 * @return */ public int mattingSample2DTextureOnGPU(int textureId, int width, int height) throws Exception; /** * 释放 * 工作在GPU语境下; */ public void releaseOnGPU(); } |
AI 人像抠图- iOS
Objective-C // // VisionSDKAiMattingAPI.h // LanSongEditorFramework // // Created by sno on 2021/12/30. // Copyright © 2021 sno. All rights reserved. // #import <Foundation/Foundation.h> #import <Foundation/Foundation.h> #import "LSOObject.h" NS_ASSUME_NONNULL_BEGIN @interface LSOAiMatting : NSObject /// 抠图初始化 , 此方法耗时,建议放到异步执行; /// @param force 是否强制等级, 如设置为NO,则内部会根据不同处理器,而做相关的调整; 设置为YES则用最好的等级; /// @param fastMode 是否是快速模式, 建议为快速模式; 设置为YES /// @param angle 本地视频的时候, 是否旋转角度; - (instancetype)initWithForceLevel:(BOOL)force fastMode:(BOOL)fastMode videoRotateAngle:(int)angle; /// 是否正在工作; @property (nonatomic, readonly) BOOL isWorking; /// 是否画面左右镜像; @property (nonatomic, assign) BOOL mirrorX; /// 是否输出mask类型的黑白图像; 在调用mattingWithSampleBuffer 之前设置; /// [不建议设置] @property (nonatomic, assign) BOOL outMaskData; @property (nonatomic, assign) BOOL advanceMatting; /// 抠图方法 /// @param sampleBuffer 输入的是摄像头的图像, 需要是kCVPixelFormatType_32BGRA格式 /// @param handler 抠图完毕后的画面,可转换为UIImage,直接预览, 工作在UI(dispatch_get_main_queue)线程中; - (void)mattingWithSampleBuffer:(CMSampleBufferRef)sampleBuffer handler:(void (^)(CVImageBufferRef)) handler; /// 释放 - (void)releaseLSO; @end NS_ASSUME_NONNULL_END |
AI人像抠图- widows
C++ #ifndef VisionSDKSegmentAPI_H #define VisionSDKSegmentAPI_H #include <string> #pragma warning(push) #pragma warning(disable : 4251) class __declspec(dllimport) VisionSDKSegmentAPI { public: /** * @brief 初始化分割模型 * * @param keyPath 模型的授权文件, 暂时为null; * @param protoPath 输入我们提供的tenLineV3.proto路径 * @param modelPath 输入我们提供的tenLineV3.model路径 * @return int 初始化成功,返回0; 失败返回-1; */ int init(std::string keyPath, std::string protoPath, std::string modelPath); /** * @brief 开始分割一帧数据 * * @param rgba 要分割的图像数据指针,rgba格式 * @param width 图像数据的宽度 * @param height 图像的高度 * @param dst 分割完毕后返回的图像指针, rgba格式,内部是抠图完毕后的一帧带透明的画面。 * @return int 分割成功返回0,失败返回-1; */ int segmentOneFrame(unsigned char *rgba, int width, int height, unsigned char *dst); /** * @brief 释放分割模型 * * @return int 返回0; */ int release(); private: int createModelEnty(int level, int cpuType); double testRunTime(int type); }; //------------------ // // 如果您是C# 接口, 则建议用以下形式 // 以下代码和VisionSDKSegmentAPI类对象的形式底层是同一份代码. // /** * @brief 打印调试信息开关; * is =1 则打印信息, =0 不打印; */ __declspec(dllimport) void _stdcall setVisionSDKSegmentAPIPrintDebugInfo(int is); /** * @brief 初始化 * * @param ptrKeyPath 授权文件路径的指针, 内部会转好为char *; * @param ptrProtoPath * @param ptrModelPath * @return int 成功返回0; 失败返回-1; */ __declspec(dllimport) int _stdcall VisionSDKSegmentAPI_init(void *ptrKeyPath, void *ptrProtoPath, void *ptrModelPath); /** * @brief 开始分割一帧数据 * * @param rgba 要分割的图像数据指针,rgba格式 * @param width 图像数据的宽度 * @param height 图像的高度 * @param dst 分割完毕后返回的图像指针, rgba格式 * @return int 分割成功返回0,失败返回-1; */ __declspec(dllimport) int _stdcall VisionSDKSegmentAPI_segmentOneFrame(unsigned char *rgba, int width, int height, unsigned char *dst); /** * @brief 释放分割模型 */ __declspec(dllimport) void _stdcall VisionSDKSegmentAPI_release(void); #pragma warning(pop) #endif // VisionSDKSegmentAPI_H |
绿幕抠图- 图层版
• 因我们android和ios的接口代码都是公开的,可以在您集成好我们SDK后,在SDK的文件中即可看到每个类每个接口的说明。
• android:类名:LSOCameraLive.java;位置:在LanSongSDK文件夹的main/java目录下。
• ios:类名:LSOCameraLive.h;位置在:LanSongEditorFrameWork/LSOCameraLive.h 下。
• 大致说明:LSOCameraLive是一个相机预览容器,我们默认是封装了系统的相机Camera,如你不需要系统相机,则可以设置为隐藏;可输入各种图层,每个图层可设置位置、大小、旋转、抠绿,滤镜,图层之间可上下叠加,显示,隐藏,替换,删除等操作。
AI人像抠图- 录制版
• 因我们android和ios的接口代码都是公开的,可以在您集成好我们SDK后,在SDK的文件即可看到每个类中每个接口的说明
• android:类名:LSOCamera.java 位置:在LanSongSDK文件夹的main/java目录下。
• Ios: 类名: LSOCamera.h 位置在:LanSongEditorFrameWork/LSOCamera.h 下。
• 大致说明:是一个容器,可输入各种图层,每个图层可设置位置、大小、旋转、滤镜,图层之间可上下叠加,显示,隐藏,替换,删除,分段录制,回删,合成等操作。
视频编辑
• 因我们android和ios的接口代码都是公开的,可以在您集成好我们SDK后,在SDK的文件即可看到每个类中每个接口的说明
• android:类名:LSOEditPlayer. Java 位置:在LanSongSDK文件夹的main/java目录下。
• ios:类名: VisionSDKEditPlayer.h 位置在:LanSongEditorFrameWork/VisionSDKEditPlayer.h 下。
• 大致说明:名字是一个编辑播放器,播放的是一个容器里的图层,可以增加一个或多个,多个图层之间可拼接,可叠加,可调节上下位置,每个图层可设置不同的调色,滤镜,动画,遮罩,特效文字,有时间轴,时间轴可拖动,缩放,裁剪;支持画布,比例,贴纸,文字,声音,水印,马赛克,涂鸦等功能。
自由编辑
• (待续)
图层方法说明
• 因我们SDK里不同的产品的图层名字不同,大致为XXXLayer,
• 如视频编辑则是LSOLayer,摄像头相关的是LSOCamLayer,积木剪辑是LSOMindLayer,AE模板是LSOAexLayer
• 但他们的功能,方法名字,用法,大致相同,只是因使用场景不同,具有的方法属性略有不同。
• 一下是视频编辑的图层LSOLayer类的说明,其他图层xxxLayer类中的方法名和用法 大致相同,不再一一列出。
• 每个方法的说明,在此方法的下一行;(文字描述的是上一行的方法作用)
Markdown public String getOriginalPath() 功能: • 获取原视频/图片的路径 参数: • @return public long getOriginalDurationUs() 功能: • 获取视频/图片的原始时长 参数: • @return public int getOriginalWidth() 功能: • 获取原始宽度 参数: • @return public int getOriginalHeight() 功能: • 获取原始高度 参数: • @return public long getDisplayDurationUs() 功能: • 获取显示时长; • 如果播放器中只有一个视频或图片, 则此时长等于播放器的时长; 参数: • @return public long getThumbnailDurationUs() 功能: • 获取缩略图的显示时间; • 注: 因转场等功能,拼接层可能有重叠区域. 因此显示时长不等于缩略图的时长; 参数: • @return public void setDisplayDurationUs(long durationUs) 功能: • 设置显示时长; 参数: • durationUs public long getStartTimeOfComp() 功能: • 获取当前图层在播放器中的开始时间 参数: • @return public void setCutDurationUs(long startUs, long endUs) 功能: • 设置视频的裁剪时长 参数: • startUs 开始裁剪时间 • endUs 结束裁剪时间 public long getCutStartTimeUs() 功能: • 获取裁剪开始时间 参数: • @return public long getCutEndTimeUs() 功能: • 获取裁剪结束时间 参数: • @return public void setCropRect(LSORect rect) 功能: • 设置裁剪区域; 参数: • @param rect public void setCropRectToOriginal() 功能: • 恢复到不裁剪 public void setCropRectPercent(float x, float y, float width, float height) 功能: • 设置裁剪百分比.整个画面从左到右是0.0--1.0; 从上到下是0.0--1.0; 参数: • x 宽度的开始比例 • y 裁剪高的开始比例 • width 裁剪宽度的比例 • height 裁剪高度的比例 public void setLooping(boolean is) 功能: • 叠加层设置循环 参数: • is public void setStartTimeOfComp(long atCompUs) 功能: • 设置当前图层在播放器中的开始时间点; 参数: • atCompUs public void setVisibility(boolean is) 功能: • 设置是否显示 参数: • is public void setVisibility(int visibility) 功能: • 设置是否显示 • 类型是 LSOLayer.VISIBLE 和 LSOLayer.INVISIBLE 参数: • visibility public int getVisibility() 功能: • 获取是否显示 参数: • @return public void resetScaleSize() 功能: • 恢复到缩放前的大小 public void setScaleType(LSOScaleType type) 功能: • 设置缩放枚举类型. • NONE: 无缩放形式.则内部会根据不同的素材,采用默认形式; • ORIGINAL: 原始大小,直接放入, 不做任意处理; • FILL_COMPOSITION, 忽略百分比,把宽度等于容器的宽度, 高度等于容器的高度,填满整个容器,这样有些画面可能会变形; • CROP_FILL_COMPOSITION: 裁剪填满放入到容器中;把视频的中心点放到容器的中心点,然后把画面等比例提填满整个容器,把多的部分裁剪掉. • VIDEO_SCALE_TYPE:视频缩放模式,如果视频宽度大于高度, 则宽度和容器对齐, 然后等比例调整高度;如果高度大于宽度, 则反之. 参数: • type public void setScaledValue(float width, float height) 功能: • 缩放到的实际值 参数: • width • height public float getScaleWidth() 功能: • 获取缩放的宽度 参数: • @return public float getScaleHeight() 功能: • 获取缩放的高度 参数: • @return public float getRotation() 功能: • 获取旋转角度. 参数: • @return public void setRotation(float angle) 功能: • 设置旋转角度 参数: • angle public void setLayerMirror(boolean flipHorizontal, boolean flipVertical) 功能: • 设置图层是否镜像, 上下镜像, 左右镜像. 参数: • flipHorizontal 水平镜像 • flipVertical 垂直镜像 public void cancelLayerMirror() 功能: • 取消镜像 public boolean isMirrorX() 功能: • 水平是否镜像 参数: • @return public boolean isMirrorY() 功能: • 垂直是否镜像 参数: • @return public void setPosition(float xPos, float yPos) 功能: • 设置当前图层中心点的坐标, xPos是X轴的坐标,yPos是设置Y轴的坐标. • 此坐标是以播放容器的大小为参考, 比如容器的大小是1280x720, 您设置了640,360 ,则图层在播放器中居中显示 参数: • xPos • yPos public void setPosition(LSOLayerPosition position) 功能: • 设置图层的枚举位置; • 枚举类型有: 左上/左下/右上/右下/居中/上/下/左/右 public float getPositionX() 功能: • 获取当前图层中心点的位置X 参数: • @return 横向坐标中心点, 相对于播放容器本身而言; public float getPositionY() 功能: • 获取当前图层中心点的位置Y 参数: • @return 竖向坐标中心点, 相对于播放容器本身而言 public void setOpacityPercent(float percent) 功能: • 设置透明百分比; 参数: • percent 百分比范围从0--1.0; public void setBrightnessPercent2X(float percent2X) 功能: • 调节当前图层画面的亮度 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setContrastFilterPercent2X(float percent2X) 功能: • 调节当前图层画面的对比度 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setSaturationFilterPercent2X(float percent2X) 功能: • 调节画面的饱和度; 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setWhiteBalanceFilterPercent2X(float percent2X) 功能: • 调节画面的白平衡 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setHueFilterPercent2X(float percent2X) 功能: • 调节画面的色度 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setExposurePercent2X(float percent2X) 功能: • 调节画面的曝光度 参数: • percent2X 范围是0--2.0; 1.0为默认值; public void setBeautyLevel(float level) 功能: • 设置画面的磨皮级别 0.0--1.0; 参数: • level 等级 0.0是不磨皮, 1.0是最高磨皮 public void setFilter(LanSongFilter filter) 功能: • 设置滤镜, 设置时, 会把上一次设置的滤镜删除; 如果不想删除则用addFilter; 参数: • filter 滤镜对象, 此对象不可同时设置为多个图层中. public void removeFilter(LanSongFilter filter) 功能: • 移出滤镜 参数: • filter 增加的滤镜对象 public void addFilter(LanSongFilter filter) 功能: • 增加滤镜,如增加多个, 则多个滤镜是级联的关系, 即画面把执行上一个滤镜的结果, 作为下一个滤镜的输入; 参数: • filter 滤镜对象 public void removeAllFilter() 功能: • 删除所有滤镜 public void setVideoSpeed(float speed) 功能: • 设置视频速度. 参数: • speed 视频速度值, 范围0.1--10.0; public float getVideoSpeed() 功能: • 获取视频速度; 参数: • @return 返回速度值 public void setVideoReverseAsync(boolean reverse, OnVideoReverseListener listener) 功能: • 异步设置视频倒序 参数: • reverse 是否倒序 • listener 倒序后的监听; public boolean isVideoReverse() 功能: • 当前视频是否倒序 参数: • @return 是否倒序 public LSOEffect addEffectAtCompTimeUs(String jsonPath, long compUs) 功能: • 用json的形式增加特效 参数: • jsonPath 增加一个特效json路径 • compUs 从播放器的什么时间点开始增加 • @return 增加后, 返回特效对象, 可设置开始时间和播放时长; public LSOEffect addEffectAtLayerHead(String jsonPath) 功能: • 在图层的头部增加一个特效 参数: • jsonPath json路径 • @return 增加后, 返回特效对象, 可设置播放时长; public LSOEffect addEffectAtLayerEnd(String jsonPath) 功能: • 在图层的尾部增加一个特效 参数: • jsonPath 特效路径 • @return 增加后, 返回特效对象, 可设置播放时长; public List<LSOEffect> getAllEffectList() 功能: • 获取增加的所有特效 参数: • @return 所有特效数组 public void removeAllEffectList() 功能: • 移出当前图层的所有特效 public void removeEffect(LSOEffect effect) 功能: • 移出指定的特效 参数: • effect public void playEffect(LSOEffect effect) 功能: • 播放预览特效 参数: • effect 指定播放的特效对象,播放后会回到播放前的位置 public LSOAnimation addAnimationAtCompTimeUs(String jsonPath, long compUs) 功能: • 增加动画 参数: • jsonPath json格式的路径 • compUs 从播放器的时间点增加 • @return 返回动画对象, 可设置开始时间和播放时长 public LSOAnimation setAnimationAtLayerHead(String jsonPath) 功能: • 在图层的头部增加一个动画 参数: • jsonPath json动画路径 • @return 返回动画对象, 可设置播放时长 public LSOAnimation setAnimationAtLayerEnd(String jsonPath) 功能: • 在图层的尾部增加一个动画 参数: • jsonPath 动画路径 • @return 返回动画对象, 可设置播放时长 public List<LSOAnimation> getAllAnimationList() 功能: • 获取所有动画 参数: • @return 所有动画对象 public void removeAllAnimationList() 功能: • 移出所有动画 public void removeAnimation(LSOAnimation animation) 功能: • 移出指定动画 参数: • animation 指定动画对象 public void playAnimation(LSOAnimation animation) 功能: • 播放动画 参数: • animation 动画对象 public boolean setTransitionMaskPath(String maskJsonPath) 功能: • 设置转场路径 参数: • maskJsonPath 遮罩转场路径 • @return 可以设置返回true; 否则返回false public void setTransitionDurationUs(long duration) 功能: • 设置转场时长 参数: • duration 时长,范围100*100---3*1000*1000; public void playTransition() 功能: • 开始播放转场 public void cancelTransition() 功能: • 取消转场 protected long getTransitionDurationUs() 功能: • 获取转场时长; 参数: • @return public long getTransitionStartTimeOfComp() 功能: • 获取从合成的开始时间; 参数: • @return public LSOMosaicRect getMosaicRect1() 功能: • 获取一个马赛克区域, 返回马赛克对象, • 可设置马赛克区域, 是否禁止,马赛克像素点的宽度; 参数: • @return 马赛克对象 public void setAudioVolume(float volume) 功能: • 设置音频音量 public float getAudioVolume() 功能: • 获取音频音量 public void setBackGroundBlurLevel(float level) 功能: • 设置背景模糊级别 • 1.0是轻微模糊,毛玻璃模糊. 8.0f是完全,深度模糊; 0.0是删除模糊效果; 参数: • level public void setBackGroundBitmap(String bitmapPath) 功能: • 设置背景图片 参数: • bitmapPath public void setBackGroundColor(int color) 功能: • 设置背景颜色 参数: • color public float getMaxBlurLevel() 功能: • 获取最大模糊系数, 当前返回的是8.0; public void getThumbnailAsync(OnLanSongSDKThumbnailBitmapListener listener) 功能: • 异步获取缩略图 参数: • listener public List<Bitmap> getThumbnailListWithCount(int count) 功能: • 获取缩略图个数, 此方法一定在getThumbnailAsync完成后设置 参数: • count 获取的图片张数 • @return 返回bitmap数组; |
其他说明
AI人像抠图推理策略
• 因AI 抠图是智能识别推理的过程,运行在不同的设备上耗时情况不同,我们做了如下策略:
• 当前SDK内部已包含多个分辨率的模型,以方便不同的平台,不同性能差异很大的设备可以流畅运行。
• 以流畅度为先。
• 如果检测到设备性能差,会使用抠图精度低但速度快的模型,以尽可能的让画面流畅,具体如下:
• Android :
○ Android10+(包含10)且非NPU手机,第一次开启AI抠图时,先试运行一下,测试当前手机性能如何, 然后使用相关的模型, 以确保流畅运行.(试跑有进度和完毕的监听)
○ Android 10以下且非NPU手机,则直接用快的模型。
○ NPU手机,则直接用好的模型(晓龙870、880不试跑,直接用好的模型)。
○ 试跑大概在1--3秒左右, 如果检查到执行两三帧速度已经很快或很慢, 就会立即结束, 不然执行大概10次左右得到一个平均耗时,从而采用不同的模型
• iOS:
○ 会根据手机的不同型号用不同的模型, 其中iphone11, 12, 13用最好的, iphone6精度最低。
• Windows
○ 会第一次初始化的时候,会用x86指令集(CPU), OpenCL指令集(GPU),CUDA指令集(显卡),都跑一次,计算得到每个模块的执行时间,然后选择最快的模块去做推理执行(当前大部分的场景是用OpenCL推理)
○ windows在比较完模块后,为了尽可能的让画面流畅,会根据一帧的耗时,去选择对应的抠图模型,如果一帧的耗时时间大于50毫秒,则会降低抠图精度以尽可能的去适配流畅度。
• 其他
○ 我们把抠图分成10个等级, 1级是最快,但抠图效果差一些,适合性能低的设备; 10级是抠图效果最好,但速度慢,适合性能高的设备;
• 抠像的好坏,还和当前环境的光线,摄像头的成像水平有关系,成像质量越好,则抠图的越精准。
• 总结:AI人像抠图,会试跑一次评估设备性能,然后流畅为主,遇到性能差的处理器会主动降低抠像精度,如果性能相近的处理器,则摄像头成像水平高的设备会抠的精准一些。
绿幕抠图--转场动画的制作
1. 用AE或其他软件做出连续逐渐透明的动画,可以是任意效果,最终导出30张连续的PNG图片即可。
2. 分辨率要求是:544x960,时长1秒钟,帧率30帧每秒。
3. 原理是:SDK会检查每张PNG图片的透明度系数,把透明度系数映射到当前图像中: PNG图片中的像素不透明,则图层对应的像素也不透明;PNG像素透明,则图层对应的像素也透明;
Android版错误代码
Markdown ### 基本原则是:不出错. - 我们认为一个SDK在用户输入素材支持的前提下, **尽量内部都可以处理,是不出错的**, 等抛出错误码, 就已经是表示代码无法执行, 这时用户不愿意看到的. - 在用户输入的时候, 蓝松SDK会判断此素材是否支持, 如果不支持会抛出异常或回调给您设置错误, 这时仅仅提示你输入的素材不支持, 但这个不是执行的错误, 是输入的素材不支持. - 基于不出错的原则, 我们仅设计了以下少量的错误码. 并引出了错误日志Log, 您可以实时记录执行日志信息,以便出现错误码尽快定位到问题所在. - 导出失败后, 如果执行了错误回调, 则SDK内部会释放当前线程, 内部的各种图层参数都会释放, 无法再次导出. ### 1. 错误码:1200 ``` 编码配置错误. 一般是当前设备不支持编码分辨率,或编码码率导致. SDK内部用的是MediaCodec编码, 如果分辨率设置超过了MediaCodec的范围, 则抛出此错误信息. ``` ### 2. 错误码:1201 ``` 编码配置错误. 一般是当前设备不支持编码分辨率,或编码码率导致. SDK内部用的是MediaCodec编码, 如果分辨率设置超过了MediaCodec的范围,则抛出此错误信息. ``` ### 3. 错误码:1202 ``` GPU执行错误. ``` ### 4. 错误码:1203 ``` 编码器在编码一帧完成后的, 引出数据时发生错误. ``` ### 5. 错误码:1204 ``` SDK的授权文件错误. 可能是SDK过期, 或applicationID 和授权文件中的不一致, 或超出了使用时间. ``` ### 6. 错误码:1205 ``` 渲染的surface错误. 常见为:没有设置surface或surface已经被释放 ``` ### 7. 错误码:1206 ``` 容器宽高设置过低的错误. 分辨率设置小于320x320,则会抛出此错误信息 ``` ### 8. 错误码:1207 ``` 当前图层错误. 建议拿到错误信息日志后,分析是哪里的问题. ``` |
绿幕抠图SDK-调节建议
• 适用版本:4.9.6
• 2022年08月24日
• 此版本抠绿说明:
○ 当前版本的效果是以稳为主,会把绿色周边相似的颜色全部抠掉,抠的会过度一些,比如手动晃动引起的虚影也会被抠掉。
○ 好处是:抠的全面一些,几乎没有绿色的存在。
○ 缺点是:一些和绿色很接近的颜色也会抠掉或变色,比如淡淡的黄色(拖影颜色)。
○ 缺点的矫正:把绿幕抠图的最小阈值调整到80.0即可。(我们演示工程里的黄色保护,即是这个例子)
• 抠绿建议
○ 图像的原始画面质量很重要,图像的原始画面清晰度直接决定了抠像的好坏。比如你用同一个处理器的Oppo手机和别的手机对比,OPPO的抠像效果相对较好一些。(OPPO最近两年的手机普遍成像较好)
○ 聚焦:建议在摄像头调节时,尽可能的把聚焦点放到不被抠的主播或物体上,这样主播或物体就会清晰度高一些,细节展现的多一些,从而抠的好一些。
○ 分辨率:建议普通上1920x1080,如果是直播机,可以跑4k的,则建议上4k,分辨率越大,呈现的细节越多,再缩放到低分辨率时,会呈现出抠的很精细。
○ 曝光度:建议尽可能的调大一些相机的曝光度(exposure),从而获取更多的亮度。
○ 距离:建议距离绿布不低于1.5米左右,并尽量参考灯光厂家的布局参数,(比如光照度等)以尽量避免绿色反射到主播或物体上,抠绿的原理是:遇到绿色就会抠掉,如果距离太近,主播或物体上就会有大量的绿色,从而也会被抠掉。
○ 打光:建议左侧和右侧,上方都打光。
○ 衣物:不要穿着绿色服装,基本上暗绿色草绿色之类的衣服都不建议穿,会被抠掉。
• 《抠像强度》说明
○ 抠的厉害程度;越厉害,则很多相似的颜色就会被抠掉。默认是40;如果灯光偏弱,则调大一些,如果灯光很强,建议调低一些;范围是0--100;
○ 当然,值越大,如果摄像头成像能力不是很好的情况下,会出现边缘闪烁的情况,这时,降低强度会改善一些;
• 《抠绿的阈值》说明
○ 最小阈值范围:0---100;默认是0 表示抠的厉害一些,把绿色和周边的颜色都抠掉,如果您不想被抠掉,则建议调整为80.0,
○ 最大阈值范围:150---210;默认是210,表示和绿色相近的青色也会被抠掉,如果您不想把青色抠掉,则建议调整为170;
○ 【完。后续持续更新...】