相机引擎技术接入文档更新时间: 2024-10-18 16:02:00

一、能力接入准备

1、注册认证

2、环境准备

在开发应用前需要在小米开放平台上上注册成为开发者并完成实名认证,详见帐号注册认证

  • 手机开发环境
    • 指定机型的小米手机
分类 型号
小米 Xiaomi MIX FOLD 1/2/3
Xiaomi Mix4
Xiaomi 14/Pro/Ultra
Xiaomi 13/Pro/Ultra
Xiaomi 12S/Pro/Ultra
Xiaomi 11/lite/Pro/Ultra
Xiaomi 10Pro
Xiaomi Civi 3
红米 Redmi K70 Pro
Redmi K60 Pro
POCO POCO X6 Pro 5G

3、申请获得相机SDK授权

如您对相机引擎能力有业务需求和接入意向,可通过联系客服,反馈、提供如下信息,小米侧将安排相关专家1个工作日内与您联系,提供支持。

需提供信息示例:
1. 公司名称:xxxx
2. APP名称:xxxx
3. 包名:xxxx
4. 应用场景:在文件扫描功能中,调用小米相机引擎,提升内容抓取精准度
5. 意向功能:拍照能力(多帧降噪)
6. 紧急程度:开发者评估该能力接入对于自身业务的紧急程度(重要性)
7. 项目计划时间:预计xxx(时间)开展接入工作,预计投入xx人力,xx(时间)完成整体接入
8. 联系方式:电话号码/微信号

二、接入开发指南

1、概述

小米相机 SDK 是基于小米视频图像基础框架(MIVI)开发,旨在开放小米系统相机的算法及硬件能力, 与三方用原有的业务代码可以完美地结合。

本 SDK 必须基于 camera api2, android p 及以上的版本。

2、接入方式

把 aar 包放到项目的 libs 目录中,然后在 project 的 build.gradle 中配置如下:

dependencies {
implementation fileTree(include: [*.aar'], dir: 'libs')
}

导入的是 jar 包的话,还需要在 AndroidManifest.xml 中配置如下:

<uses-library android: name="camerax-vendor-extensions.jar" android:required="false"/>
<queries>
<package android:name="com.android.camera" />
</queries>

3、时序图

上传文件

4、调用方法说明

//      -------------------初始化    
MiCamera mMiCamera = new MiCamera();
// -------------------步骤一
mMiCamera.getCameraIdByType(); // 选择要打开的摄像头
mMiCamera.openCamera();
// -------------------步骤二
mMiCamera.get[Preview|Capture|Video|ContiuousYUV]Size(getCurrentMode(),mCameraId) // 选择尺寸
mMiCamera.createCaptureSession(); // 创建CaptureSession
// -------------------步骤三
mMiCamera.getSupportedAlgoList(algo); // 获取支持的算法列表
mMiCamera.isAlgoSupported(algo); // 如果只用到某种算法,可以只判断某种算法是否支持
mMiCamera.isAlgoConflict(algoOne,algoTwo); // 支持的列表算法里面,有些算法是互斥的,比如bokeh与mfnr互斥
// -------------------步骤四
mMiCamera.applyCommonParam(CaptureRequest.Builder); // 设置基础参数,否则会导致后面算法不生效
mMiCamera.applyBeauty(); // 设置美颜
mMiCamera.applyFrontBokeh(); // 设置前置人像
mMiCamera.applyVideoStabilization(); // 设置防抖
mMiCamera.applyHDR(); // 设置HDR
mMiCamera.applyMFNR(); // 设置多帧降噪
mMiCamera.applyNightMode(); // 设置超级夜景

4.1 初始化

调用这个方法时会在构造方法里面初始化支持的算法列表。
示例代码:

MiCamera mMiCamera = new MiCamera(Context context);

4.2 getCameraIdByType

请尤其注意此步骤,在openCamera之前调用此方法,以获取要打开的摄像头ID。
SDK Function:

public String getCameraIdByType(@CameraLensType int cameraLensType) 

4.3 openCamera

与camera api2的流程一样,这一步打开相机。
SDK Function:

public void openCamera(@NonNull String cameraId, @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)  

4.4 getSize

为了更好的画质,我们仅提供经过测试及调教的preview,capture,video,continuousYUV(一般用于扫码,人脸识别)size。不建议用其他size,有可能会导致画质,稳定性的问题。

public List<Size> getPreviewSize(int mode, String cameraID) {  
return this.mDefaultSizeContainer.getPreviewSize(mode, cameraID);
}
public List<Size> getVideoSize(int mode, String cameraID) {
return this.mDefaultSizeContainer.getVideoSize(mode, cameraID);
}
public List<Size> getCaptureSize(int mode, String cameraID) {
return this.mDefaultSizeContainer.getCaptureSize(mode, cameraID);
}
public List<Size> getContinuousYUVSize(int mode, String cameraID) {
return this.mDefaultSizeContainer.getContinueYuvSize(mode, cameraID);
}

4.5 createCaptureSession

这个过程比camera2 API多一个参数Mode。
Mode按照场景给算法分类,createCaptureSession的时候,底层会按照Mode去加载算法,一些场景用不到的算法就先不加载,以达到节省内存功耗的目的。
SDK Function:

@RequiresApi(api = Build.VERSION_CODES.P)  
public void createCaptureSession(@Mode int mode, CameraDevice cameraDevice, int templateType,
int sessionType, @NonNull List<Surface> outputs, @Nullable Handler handler, CameraCaptureSession.StateCallback cb)

另外还提供了参数为SessionConfiguration的方法。

public void createCaptureSession(@Mode int mode, @NonNull CameraDevice cameraDevice, int templateType, SessionConfiguration config)

4.6 算法列表

获取支持的算法列表,判断算法是否支持,是否互斥。再决定是否调用该算法,做一些三方业务逻辑。

4.6.1 判断算法是否可用

/** 
* @return true if the algorithm is supported with cameraID in the mode
*/
public boolean isAlgoSupported(@Mode int mode, String cameraID, @Algo int algo)

示例代码:

if (mMiCamera.isAlgoSupported(MiCamera.Algo.BEAUTY)) {        mMiCamera.applyBeauty(builder,mBeautyLevelValue,mBeautySkinSmoothValue,mBeautyFaceThinValue); 
}

4.6.2 获取支持的算法列表

获取当前模式下的算法列表。当应用上存在多个配置选项时,需要根据相机支持的算法列表来显示配置项。
SDK Function:

/** 
* @return the supported algorithm list with cameraID in the mode
*/
public List<Integer> getSupportedALGOList(@Mode int mode, String cameraID)

示例代码:

private void refreshConfigView() {  
mTvBokeh.setVisibility(View.INVISIBLE);
mTvMfnr.setVisibility(View.INVISIBLE);
mBeautyIcon.setVisibility(View.INVISIBLE);
mBtnHdr.setVisibility(View.INVISIBLE);
List<Integer> algoList = mMiCamera.getSupportedAlgoList();
for (Integer integer : algoList) {
switch (integer){
case MiCamera.Algo.BEAUTY:
mBeautyIcon.setVisibility(View.VISIBLE);
break;
case MiCamera.Algo.MFNR:
mTvMfnr.setVisibility(View.VISIBLE);
break;
case MiCamera.Algo.BOKEH_FRONT:
mTvBokeh.setVisibility(View.VISIBLE);
break;
case MiCamera.Algo.HDR:
mBtnHdr.setVisibility(View.VISIBLE);
break;
}
}
}

4.6.3 算法互斥

例如HDR与MFNR互斥,他们就不能同时启用,以下代码就是查询first与second算法有没有存在冲突。如果存在冲突,则disable与目标算法冲突的算法。
SDK Function:

/** 
* @param mode see {@link Mode}
* @param first see {@link Algo}
* @param second see {@link Algo}
* @return true if the first is conflict with second or not in the mode
*/
public boolean isAlgoConflict(@Mode int mode, @Algo int first, @Algo int second)

4.7 设置CaptureRequest参数

下发预览,拍照参数。拍照,预览都需要调用对应的方法。有些算法只在拍照中生效,有些则拍照/预览都生效。

4.7.1 设置Preview基础参数

下发preview request之前,request必须通过sdk设置基础参数,否则后面的算法不会生效:

public void applyCommonParam(CaptureRequest.Builder builder) 

4.7.2 Beauty

生效场景: 预览/拍照/视频
Mode: Mode.CAPTURE/Mode.VIDEO_NORMAL
SDK Function:

/** 
* set the beauty parameter
* @param builder CaptureRequest.Builder
* @param beautyConfig
*/
public void applyBeauty(CaptureRequest.Builder builder, BeautyConfig beautyConfig)

此算法必须配置以下2路流:

  • 预览
Surface previewSurface1 = new Surface(texture1);
mPreviewBuilder.addTarget(previewSurface1);
surfaceList.add(previewSurface1);
  • 拍照
mImageReaderJpeg = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.JPEG, 2);
mImageReaderJpeg.setOnImageAvailableListener(reader -> {}, mBackgroundHandler);
surfaceList.add(mImageReaderJpeg.getSurface());

///////////////////////////////////////或者/////////////////////////////////////////////
mImageReaderYuv = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.YUV_420_888, 2);
surfaceList.add(mImageReaderYuv.getSurface());

4.7.3 HDR

使能HDR时,会使ZSL(零延时拍照)失效。
生效场景: 拍照
Mode: Mode.CAPTURE
SDK Function:

/** 
* call this method will also disable ZSL, because enable ZSL will disable HDR algorithm
* @param builder capture request builder
* @param enable true means enable HDR
*/
public void applyHDR(CaptureRequest.Builder builder, boolean enable)

可通过预览的TotalCaptureRequest检测当前场景是否需要开启HDR算法,算法如下:

/** 
* @param result The total output metadata from the capture, including the final capture
* parameters and the state of the camera system during capture.
* @return true if detected hdr scene
*/
public static boolean isHDRDetected(CaptureResult result)

在一些环境是不需要启动HDR的,不会启用HDR算法,拍照结果可以通过以下方法判断是否已启用HDR算法:

/**
* @param result The total output metadata from the capture, including the
* final capture parameters and the state of the camera system during capture.
* @return true if the capture contain HDR algorithm
*/
public static boolean isHDREffected(CaptureResult result)

此算法必须配置2路流,请参考4.7.2。

4.7.4 前置人像

生效场景: 预览/拍照
Mode: Mode.CAPTURE/ Mode.BOKEH
SDK Function:

/** 
* enable bokeh of not
* @param builder capture request builder
* @param enable true means enable bokeh
*/
public void applyBokehFront(CaptureRequest.Builder builder, boolean enable)

此算法必须配置2路流,请参考4.7.2。

4.7.5 人像模式

生效场景: 预览/拍照
Mode: Mode.BOKEH
获取F Number的取值范围:

/**
* @return F number
*/
public List<String> getFNubmer()

设置F Number:

/**
* set the F number of bokeh
* @param builder
* @param fnumber see {@link MiCamera#getFNubmer}}
* @apply_scene preview/capture
*/
public void applyBokehFNumber(CaptureRequest.Builder builder, String fnumber)

Bokeh算法需要实时获取设备方向,所以设备方向改变的时候需要设置方向:

/**
* update device orientation when changed
* @param builder
* @param orientation value range: [0, 90, 180, 270]
*/
public void applyDeviceOrientation(CaptureRequest.Builder builder, int orientation)

此算法必须配置2路流,请参考4.7.2。

4.7.6 夜景

启用夜景需要在createCaptureSession的时候,传入对应的Mode.SUPER_NIGHT。使能夜景拍照时,会使ZSL(零延时拍照)失效。
这个模式下不需要开闪光灯,否则对画质产生不好的影响。
生效场景: 拍照
Mode: Mode.SUPER_NIGHT
SDK Function:

/**
* call this method will also disable ZSL, because enable ZSL will disable night‘s algorithm
* effect
* @param builder CaptureRequest.Builder
* @param enable true means enable night mode
*/
public void applyNightMode(CaptureRequest.Builder builder, boolean enable)

此算法必须配置2路流,请参考4.7.2。

4.7.7 多帧降噪

生效场景: 拍照
Mode: Mode.CAPTURE
SDK Function:

/** 
* call this method will enable ZSL to prevent hang when capture
* @param builder capture request builder
* @param enable true means enable MFNR
*/
public void applyMFNR(CaptureRequest.Builder builder, boolean enable)

此算法必须配置2路流,请参考4.7.2。

4.7.8 普通视频

该模式可以设置bokeh,美颜。
生效场景: 录像
Mode: Mode.VIDEO_NORMAL
设置美颜请参照美颜“4.6.2 Beauty”
设置bokeh参数请参照下面:

/**
* applyVideoBokeh
* @param builder
* @param value range : 0-100
*/
public void applyVideoBokeh(CaptureRequest.Builder builder, float value)

此模式必须配置以下3路流:

  • 预览
Surface previewSurface1 = new Surface(texture1);
mPreviewBuilder.addTarget(previewSurface1);
surfaceList.add(previewSurface1);
  • 拍照
mImageReaderJpeg = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.JPEG, 2);
mImageReaderJpeg.setOnImageAvailableListener(reader -> {}, mBackgroundHandler);
surfaceList.add(mImageReaderJpeg.getSurface());
  • 录像
Surface recorderSurface = mMediaRecorder.getSurface();
mPreviewBuilder.addTarget(recorderSurface)
surfaceList.add(recorderSurface);
///////////////////////////////////////或者/////////////////////////////////////////////
mImageReaderYuv = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.YUV_420_888, 2);
surfaceList.add(mImageReaderYuv.getSurface());

4.7.9 视频防抖

生效场景: 录像
Mode: Mode.VIDEO_STABILIZATION
SDK Function:

/** 
* enable/disable video stabilization
* @param builder capture request builder
* @param enable true means enable antiShake
*/
public void applyVideoStabilization (CaptureRequest.Builder builder, boolean on)

4.7.10 视频防抖Pro

生效场景: 录像
Mode: Mode.VIDEO_STABILIZATION_V3
SDK Function:

/** 
* enable video stabilizationV3
* @param builder capture request builder
* @param status 0: Preview
* 1: startRecording
* 2: stopRecording
*/
public void applyVideoStabilizationV3 (CaptureRequest.Builder builder, int status)

4.7.11 视频HDR

生效场景: 录像
Mode: Mode.VIDEO_HDR
无需设置其他参数
此模式必须配置以下3路流:

  • 预览
Surface previewSurface1 = new Surface(texture1);
mPreviewBuilder.addTarget(previewSurface1);
surfaceList.add(previewSurface1);
  • 拍照
mImageReaderJpeg = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.JPEG, 2);
mImageReaderJpeg.setOnImageAvailableListener(reader -> {}, mBackgroundHandler);
surfaceList.add(mImageReaderJpeg.getSurface());
  • 录像
Surface recorderSurface = mMediaRecorder.getSurface();
mPreviewBuilder.addTarget(recorderSurface)
surfaceList.add(recorderSurface);
///////////////////////////////////////或者/////////////////////////////////////////////
mImageReaderYuv = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.YUV_420_888, 2);
surfaceList.add(mImageReaderYuv.getSurface());

4.7.12 视频夜景

生效场景: 录像
Mode: Mode.VIDEO_SUPERNIGHT
无需设置其他参数
此模式必须配置以下3路流:

  • 预览
Surface previewSurface1 = new Surface(texture1);
mPreviewBuilder.addTarget(previewSurface1);
surfaceList.add(previewSurface1);
  • 拍照
mImageReaderJpeg = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.JPEG, 2);
mImageReaderJpeg.setOnImageAvailableListener(reader -> {}, mBackgroundHandler);
surfaceList.add(mImageReaderJpeg.getSurface());
  • 录像
Surface recorderSurface = mMediaRecorder.getSurface();
mPreviewBuilder.addTarget(recorderSurface)
surfaceList.add(recorderSurface);
///////////////////////////////////////或者/////////////////////////////////////////////
mImageReaderYuv = ImageReader.newInstance(mVideoSize.getHeight(), mVideoSize.getWidth(), ImageFormat.YUV_420_888, 2);
surfaceList.add(mImageReaderYuv.getSurface());

4.8 多摄

4.8.1 判断摄像头类型

该功能需要联系小米相机,设置白名单才能获取到对应的权限,获取到权限后通过camera2的标准接口可以获取到camera ID列表。SDK提供判断camera ID类型的接口, 目前只支持物理摄像头类型的判断,其他camera的判断,请使用4.2 getCameraIdByType。其他调用遵循camera2的接口。
Function:

/** 
* @param cameraID
* @return camera lens type as below:
* RearMain : 1
* FrontMain : 2
* UltraWide : 3
*/
public int getCameraLensType(String cameraID)

4.8.2 多摄同开

因为手机的不同,有些可以支持前后同开,有些支持任意组合的同开,需要根据接口判断。

/**
* @return the operation which indicate the operation of multi camera
* {@link MultiCameraOperation}
*/
public static @MultiCameraOperation int getMultiCameraOperation()
public @interface MultiCameraOperation {
/**
* only one camera be opened at the same time
*/
int OPERATION_SINGLE = 1;
/**
* ront and rear camera can be opened at the same time
*/
int OPERATION_FRONT_REAR = 2;
/**
* Any combination of cameras can be open at the same time
*/
int OPERATION_ALL = 3;}

4.9 获取高帧率

该方法用于获取30~120FPS的高帧率列表,120FPS及以上请通过android标准高帧率接口获取。通过camera2 API的帧率设置方法设置即可。这个接口获取到的高帧率不建议与MiCamera开放的能力共用,有可能引起丢帧。
SDK Function:

/** 
* @param cameraID
* @return all high FPS ranges for cameraID
*/
public List<MiHFpsInfo> getSupportedHFpsRange(String cameraID)

4.10 获取SAT zoom范围

该方法用于获取SAT Camera的zoom范围。
SDK Function:

/** 
* @param characteris
* @return the SAT Zoom Range
*/
public Range<Float> getSATZoomRange (CameraCharacteristics characteristics)

4.11 获取SAT video zoom范围

该方法用于获取SAT Video 的zoom范围
SDK Function:

/** 
* @param characteris
* @return the Video SAT Zoom Range
*/
public Range<Float> getVideoSATZoomRange (CameraCharacteristics characteristics)

文档内容是否有帮助?
有帮助
无帮助