免标定指尖OCR识别接入说明文档
文档状态
| 文件标识: | TuringOS-fingerpro-V1.0 |
|---|---|
| 系统版本: | SDK |
| 完成日期: | 2023年01月09日 |
文档修订记录
| 文档版本号 | 修订日期 | 修订原因 | 备注 |
|---|---|---|---|
| V1.0 | 2023.1.9 | 创建文档 | |
| V1.1 | 2023.4.13 | 新增模型状态的回调事件(MessageEvent.CODE_CV_MODEL) | |
| V1.2 | 2023.5.10 | 新增ocrRes 返回相近文本 | |
| V1.3 | 2023.6.20 | 更新配置文件说明,见【参数配置】 | SDK V2.5.4.1 开始: ① finger-move字段不生效,采用指尖+相似的综合检测方式,故motionSensitivity、moveSimi都要填写。 ② turing_config.json 新增 brandModel,获取免标定云端参数,填写则使用云端配置参数,不填写则使用本地参数。 |
| V1.4 | 2023.6.29 | 支持动态切换分辨率 | TuringFingerPro#updateCameraSize(),详情见使用示例 |
概述
指尖OCR识别支持指尖定位、查词、查句、查拼音、查段功能
能力硬件要求
基于对摄像头拍摄清晰程度的要求,分类如下:
- 高端要求:查拼音、查句子、查段落:属于高端OCR 能力,一般需要客户产品的前摄像头具备800W及以上像素
- 中端要求:查词,一般需要客户产品的前摄像头具备500W及以上像素
- 低端要求:翻读、指读对客户产品的前摄要求较低。
| 能力名称 | 可支持摄像头 | 内存 | CPU | 分类 |
|---|---|---|---|---|
| 标定版指尖查词 | 500W | 2GB | -- | 标定版 |
| 标定版指尖查句 | 800W | 4GB | -- | 标定版 |
| 免标定指尖查词 | 500W | 4GB | -- | 免标定 |
| 免标定指尖查句 | 800W | 4GB | -- | 免标定 |
| 免标定指尖查拼音 | 800W | 4GB | -- | 免标定 |
| 免标定指尖查段 | 800W | 4GB | -- | 免标定 |
影响指尖准确率维度:图像清晰度和设备性能
- 图像清晰度: 指设备采集图片的清晰程度,影响因素有很多,例如:多少万像素,客户是否针对摄像头进行过调优等 图灵针对客户的图灵质量建立了标准并具体相应的工具,可以方便评估客户的设备是否支持查词,查句等。
- 设备性能: 设备性能主要用于评估设备是否满足免标定方案,相对于标定方案,免标定方案需要前端具体一定的算力来满足算法要求,目前根据手头设备的具体情况,也建立了基本的标准,但这一指标仅具有参考意义,因为最终的响应时间,还和客户采用的分辨率,系统的内存管理,图片渲染等多因素影响,但低于图灵标准,则不建议用免标定方案。
集成前提
进入摄像头参数设置页面,选取合适的分辨率。
● 确定摄像头ID:0=后置;1=前置。
● 获取相机参数:预览分辨率、拍照分辨率。
● 选择高的预览分辨率(例如 1920*1080),适中的拍照分辨率和预览分辨率接近的 (ps: 高拍照分辨率不一定图片高清,所以需要折中选择和预览分辨率接近的)。
● 生成图片并预览此配置下的图片清晰度。
● 多次预览确定最佳摄像头,参数配置写入 assets/turing_config.json 中。
集成步骤
1. 添加依赖库
//必须依赖库
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation "org.java-websocket:Java-WebSocket:1.4.0"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.11'//SDKV2.4.1.25 以后需加入
// 指尖&绘本
implementation 'net.sourceforge.jexcelapi:jxl:2.6.12'
// 免标定指尖&绘本
def room_version = "2.4.2"
def corotine_version ="1.3.9"
api "androidx.room:room-runtime:${version["room_version"]}"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:${version["corotine_version"]}"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:${version["corotine_version"]}"
kapt "androidx.room:room-compiler:${rootProject.ext.version["room_version"]}"
// 指尖&词典
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
2. AndroidManifest配置
添加权限
<!--网络-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--文件读写-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--deviceID-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--绘本、指尖查词-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!-- 读取手机状态,获取IMEI -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- android 10 在application节点添加以下适配高版本 -->
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
3. 代码混淆
代码混淆文件proguard-project.txt,添加如下内容
-keep class com.turing.**{ *;}
-dontwarn com.turing.**
-keep class com.tuling.**{ *;}
-dontwarn com.tuling.**
-keep class com.sdk.finger.**{ *;}
-dontwarn com.sdk.finger.**
-keep class org.java_websocket.**{*;}
-dontwarn org.java_websocket.**
-keep class org.slf4j.**{*;}
-dontwarn org.slf4j.**
-keep class org.eclipse.** { *; }
-dontwarn org.eclipse.**
4. SDK 初始化
使用指尖OCR识别功能前调用,请先调用SDK初始化代码。(SDK初始化详情见《接入指南说明文档》)
TuringInitializer.getInstance().initV3XXX()
5. 参数配置
需要在 turing_config.json 中添加 globalConfig.camer、finger 节点。finger 参数如下
| 参数 | 类型 | 是否必须 | 取值范围 | 说明 |
|---|---|---|---|---|
| previewWidth | int | Y | - | 预览宽度 |
| previewHeight | int | Y | - | 预览高度 |
| pictureWidth | int | Y | - | 拍照预览宽度 |
| pictureHeight | int | Y | - | 拍照预览高度 |
| showPoint | boolean | N | - | 是否显示指尖坐标点,默认false |
| horMirror | boolean | N | - | 左右镜像,默认false |
| verMirror | boolean | N | - | 上下镜像,默认false |
| pointColor | String | N | 颜色值 | 坐标点颜色,如"#FC0202" |
| pointWidth | int | N | - | 坐标点宽 |
| appMode | int | N | - | 0-查字/词(默认) 1-查句 2-查段 3-查题 |
| ocrMode | Integer | N | - | 0通用模式(默认) 1中文模式 2英文模式 3拼音模式 |
| selectType | String | N | - | charV-字优先 wordV-词优先 normalV-通用 |
| optMode | Integer | N | - | 1-平板 0-台灯 |
| ~~moveMode~~ | ~~int~~ | ~~N~~ | - | ~~1-相似运动 0-指尖运动(默认)~~ SDK V2.5.4.1 开始,此字段不生效,采用指尖+相似的综合运动静止检测方式 |
| motionSensitivity | double | N | [8,64] 8的倍数 | 指尖移动阈值。 查词/查句建议使用16,查段建议使用64 |
| moveSimi | double | N | [0.9800,0.9975] | 相似度阈值 |
| wordMinPixel | Integer | N | - | 裁切图最小像素宽 |
| wordRatio | Double | N | [0,1] | 裁切图比例 |
| cropRatio | List | N | [0,1] | 裁切区域比例[左,右,上,下] |
motionSensitivity 和 moveSimi 值解释
moveSimi:
-
越高则 运动 判断越灵敏;相邻移动(即静止判断)越不灵敏。
-
越低则 运动 判断越不灵敏;相邻移动(即静止判断)越灵敏。
motionSensitivity: 越高则越不灵敏,越低则越容易多次响应。
示例如下
{
"authorization": {
"apikey": "您的apikey",
"secret": "您的secret"
},
"globalConfig": {
"brandModel":"您的品牌型号",
"camera": {
"cameraId": 1,
"cameraApi": 2,
"turingCameraId": 118,
"preMirror": false,
"mirror": true,
"zoom": 0,
"preRotation": -1,
"rotation": 180
}
},
"ability": {
"finger": {
"showPoint": true,
"horMirror": false,
"verMirror": false,
"pointColor": "#FC0202",
"pointWidth": 10,
"appMode": 0,
"maxLen": 4,
"selectType": "wordV",
"dictType": "tuling",
"ocrMode": 0,
"optMode": 1,
"openTts": true,
"motionSensitivity": 64.0,
"previewWidth": 640,
"previewHeight": 480,
"pictureWidth": 2560,
"pictureHeight": 1920,
"cropRatio": [0.0,1,0.0,1]
},
}
}
修改参数值的几种方式:
方式一:在清单文件 turing_config.json 中赋值
方式二:修改全局变量值
调用 TuringConfig.getInstance(this).configData 动态设置入参,参数同 turing_config.json。(注:需要在 startFingerOcr() 前调用 )
val configData: ConfigData = TuringConfig.getInstance(this).configData
configData.ability.finger.selectType = "wordV"
configData.ability.finger.appMode = 0
configData.ability.finger.isShowPoint = true
configData.ability.finger.pictureWidth = 2560
configData.ability.finger.pictureHeight = 1920
configData.ability.finger.previewWidth = 640
configData.ability.finger.previewHeight = 480
configData.ability.finger.ocrMode = 0
方式三:动态调整
仅对本次识别生效,可设置参数有限,如下所示:
| 参数 | 类型 | 说明 | 备注 |
|---|---|---|---|
| FingerConfig.KEY_APP_MODE | int | 查询模式 | 0- 查字/词 1-查句 2-查段 3-查题 |
| FingerConfig.KEY_OCR_MODE | int | 识别模式 | 0- 通用(默认) 1-中文模式 2-英文模式 3-拼音模式 |
| FingerConfig.KEY_SELECT_TYPE | String | 优化查询 | charV-字优先 wordV-词优先 normalV-通用 |
| FingerConfig.KEY_ERR_CORRECTION | boolean | 教材纠错 | true-开启纠错 false-不开启 |
| FingerConfig.KEY_OPT_MODE | int | 场景模式 | 0-台灯 1-平板 |
| FingerConfig.KEY_MOTION_SENSITIVITY | int | 灵敏度 | 指尖移动阈值。 查词/查句建议使用16,查段建议使用64。 取值范围:[8,64] 8的倍数 |
| FingerConfig.KEY_WORD_RATIO | double | 查词裁图比例 | |
| FingerConfig.KEY_WORD_MIN_PIXEL | int | 查词最小像素 |
(注:需要在模型初始化成功( 成功事件见 【开启指尖OCR识别】输出说明中【MessageEvent 说明】 )后,才能调用postFingerConfig。)
示例代码:
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
config[FingerConfig.KEY_OCR_MODE] = 3
fingerPro.postFingerConfig(config) // 在模型初始化成功后调用
6. 开启功能集成
使用说明见下面【功能集成】描述。
实例化
var fingerPro = TuringFingerPro.getInstance(this)
功能集成
1. 开启指尖OCR识别
调用方法前先设置参数,见【集成步骤】中【参数配置】。
方法
void startFingerOcr(ViewGroup layout, FingerProListener<FingerOCRResult> listener, boolean... isPicMode)
输入说明
| 参数 | 类型 | 说明 |
|---|---|---|
| layout | ViewGroup | 预览界面的布局,建议使用FrameLayout |
| listener | FingerProListener |
回调接口 |
| isPicMode | boolean | 是否使用拍照模式 true: 拍照(推荐) false: 预览(默认) |
当使用拍照模式时:建议降低预览分辨率(例如640*480,320*240)来提高运动检测速度,拍照分辨率为符合要求的值。
输出说明
-
FingerProListener 说明
```kotlin public interface FingerProListener
{ /* * OCR识别结果 * * @param result / void onSuccess(FingerOCRResult result); /** * 返回原始图片 * 暂无作用 * * @param image */ void onImageData(byte[] image); /** * 返回裁切图片 * * @param image */ void onOcrImageData(byte[] image); /** * 错误回调 * * @param errorCode * @param errMsg */ void onError(int errorCode, String errMsg); /** * 事件回调 * * @param event */ void onEvent(MessageEvent event); /** * 手指坐标 * * @param fingerPosX * @param fingerPosY */ void onFinger(float fingerPosX, float fingerPosY);} ```
-
FingerOCRResult 说明
| 参数 | 类型 | 是否返回 | 说明 |
|---|---|---|---|
| appMode | int | Y | 0-查字/词, 1-查句,2-查段 |
| word | String | N | 字/词。 appMode=0返回 |
| sentence | String | N | 句。 appMode=1返回 |
| paragraph | String | N | 段。appMode=2返回 |
| ocrRes | json | Y | 相近文本。appMode=0返回 |
ocrRes 字段说明
| 参数 | 类型 | 是否返回 | 说明 |
|---|---|---|---|
| useIndex | int | Y | 推荐相近字的下标 |
| content | List< String > | Y | 只返回相近字,不返回相近词 |
- MessageEvent 说明
类具体包名:com.turing.book.eventbus.MessageEvent
- MessageEvent.CODE_START_ORC 开始识别,即检测到运动
- MessageEvent.CODE_RECOGNIZE_FINGER 识别手指
- MessageEvent.CODE_START_QUERY 开始查词查句
- MessageEvent.CODE_OCR_RESULT 识别结果(包含未识别到字符、识别到字符事件)
- MessageEvent.CODE_TIPS 提示信息
- MessageEvent.CAMERA_STATES_OPENING 时机:调用了开启相机方法
- MessageEvent.CAMERA_STATES_OPENED 时机:CameraDevice.StateCallback#onOpened
- MessageEvent.CAMERA_STATES_CLOSEING 时机:调用了关闭相机方法
- MessageEvent.CAMERA_STATES_DISCONNECTED 时机:CameraDevice.StateCallback#onDisconnected
- MessageEvent.CAMERA_STATES_CLOSED 时机:CameraDevice.StateCallback#onClosed
- MessageEvent.CAMERA_STATES_ERROR 时机:CameraDevice.StateCallback#onError
- MessageEvent.CODE_CV_MODEL 算法模型状态的回调事件
code = MessageEvent.CODE_CV_MODEL 详解:
event.arg1:表示模型状态(-1: 未初始化 1: 开始初始化 2: 初始化成功 3: 初始化失败 4: 开始释放 5: 释放成功 6: 释放失败)。
event.arg2:表示模型初始化失败(arg1=3)、释放失败(arg1=6)的具体原因。
TuringFingerPro#postFingerConfig() 方法,需要在event.arg1==2时用才生效。
请求示例
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onSuccess(result: FingerOCRResult?) {
result?.let{
if(it.appMode == 0){ // 0-查字/词, 1-查句 2-查段
// 拿到ocr识别文本请求词典
queryDict(it.word)
}else(it.appMode == 1){
/**
* 这里演示拿着ocr识别文本分别请求tts、翻译、分词、口语评测。
* 根据实际需求,自行请求
*/
queryTTS(it.sentence)
queryTrans(it.sentence)
querySplit(it.sentence)
querySpeech(it.sentence)
}else{
// 拿到OCR识别文本,拆分成一句一句
handleParagraph(it.paragraph)
}
}
}
override fun onImageData(image: ByteArray?) {
}
override fun onOcrImageData(image: ByteArray?) {
}
override fun onError(errorCode: Int, errMsg: String?) {
}
override fun onEvent(event: MessageEvent?) {
}
override fun onFinger(fingerPosX: Float, fingerPosY: Float) {
}
},isPicMode)
2. 开启指尖查词
调用方法、输入参数、输出结果同【1、开启指尖OCR识别】,区别在于 输入参数 appMode 值为0。
请求示例
// 这里演示开始ocr识别后,切换为指尖查词。其他调整参数值的方式,见【集成步骤】->【5.参数配置】
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onEvent(event: MessageEvent?) {
if (event == null) {
return
}
when (event.code) {
MessageEvent.CODE_CV_MODEL -> {
if (event.arg1 == 2) {
val config = HashMap<String, Any>()
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
config[FingerConfig.KEY_OCR_MODE] = 1 // 中文模式
fingerPro.postFingerConfig(config) // 需要在模型初始化成功后调用
}
}
}
}
...
},isPicMode)
3. 开启指尖查句
调用方法、输入参数、输出结果同【1、开启指尖OCR识别】,区别在于 输入参数 appMode 值为1。
请求示例
// 这里演示开始ocr识别后,切换为指尖查句。其他调整参数值的方式,见【集成步骤】->【5.参数配置】
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onEvent(event: MessageEvent?) {
if (event == null) {
return
}
when (event.code) {
MessageEvent.CODE_CV_MODEL -> {
if (event.arg1 == 2) {
val config = HashMap<String, Any>()
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_SENTENCE
fingerPro.postFingerConfig(config) // 需要在模型初始化成功后调用
}
}
}
}
...
},isPicMode)
4. 开启指尖查段
调用方法、输入参数、输出结果同【1、开启指尖OCR识别】,区别在于 输入参数 appMode 值为2。
请求示例
// 这里演示开始ocr识别后,切换为指尖查段。其他调整参数值的方式,见【集成步骤】->【5.参数配置】
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onEvent(event: MessageEvent?) {
if (event == null) {
return
}
when (event.code) {
MessageEvent.CODE_CV_MODEL -> {
if (event.arg1 == 2) {
val config = HashMap<String, Any>()
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_PARAGRAPH
fingerPro.postFingerConfig(config) // 需要在模型初始化成功后调用
}
}
}
}
...
},isPicMode)
5. 开启指尖查拼音
调用方法、输入参数、输出结果同【1、开启指尖OCR识别】,区别在于 输入参数 appMode 值为0,ocrMode=3。
请求示例
// 这里演示开始ocr识别后,切换为指尖查拼音。其他调整参数值的方式,见【集成步骤】->【5.参数配置】
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onEvent(event: MessageEvent?) {
if (event == null) {
return
}
when (event.code) {
MessageEvent.CODE_CV_MODEL -> {
if (event.arg1 == 2) {
val config = HashMap<String, Any>()
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
config[FingerConfig.KEY_OCR_MODE] = 3
fingerPro.postFingerConfig(config) // 需要在模型初始化成功后调用
}
}
}
}
...
},isPicMode)
6. 开启指尖切题
调用方法、输入参数同【1、开启指尖OCR识别】,区别在于 输入参数 appMode 值为3。
切题结果目前只返回图片,回调方法onOcrImageData()。
请求示例
// 这里演示开始ocr识别后,切换为指尖切题。其他调整参数值的方式,见【集成步骤】->【5.参数配置】
fingerPro.startFingerOcr(binding.frameLayer,object :FingerProListener<FingerOCRResult>{
override fun onEvent(event: MessageEvent?) {
if (event == null) {
return
}
when (event.code) {
MessageEvent.CODE_CV_MODEL -> {
if (event.arg1 == 2) {
val config = HashMap<String, Any>()
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_PROBLEM
fingerPro.postFingerConfig(config) // 需要在模型初始化成功后调用
}
}
}
}
override fun onOcrImageData(data: ByteArray?) {
data?.let {
runOnUiThread {
if (!isRelease) {
Glide.with(this@FingerActivity).load(data).into(inflate.ivOcrImage)
// 请求题库
if (appMode != 3 || data == null || data.isEmpty() || !inflate.switchSearchQuestion.isChecked) {
return@runOnUiThread
}
// 拿切题图片去请求题库
fingerTextUtil.requestSearchQuestion(this@FingerActivity,data,inflate,this@FingerActivity)
}
}
}
}
...
},isPicMode)
7. 动态调整参数值
可调整参数字段,见【集成步骤】->【5.参数配置】。
方法
void postFingerConfig(HashMap<String, Object> config);
(注:需要在模型初始化成功( 成功事件见 【开启指尖OCR识别】输出说明中【MessageEvent 说明】 )后,才能调用postFingerConfig。)
示例代码:
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
config[FingerConfig.KEY_OCR_MODE] = 3
fingerPro.postFingerConfig(config) // 在模型初始化成功后调用
8. 切换分辨率
支持在不重启相机的情况下切换分辨率,需要在 startFingerOcr() 后并且相机开启成功(MessageEvent#CAMERA_STATES_OPENED),才能调用。
注:切换时预览界面停止属于正常现象。
方法
void updateCameraSize(Size preSize, Size picSize);
请求示例
// 下面为切换功能模块时调整分辨率
var fingerPro = TuringFingerPro.getInstance(this)
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
fingerPro.postFingerConfig(config)
fingerPro.updateCameraSize(Size(1280,960),Size(1280,960)) // 预览分辨率和拍照分辨率都调整
// 仅调整预览分辨率
fingerPro.updateCameraSize(Size(1280,960),null)
// 仅调整预览分辨率
fingerPro.updateCameraSize(null,Size(1280,960))
9. 获取当前已开启相机的参数
获取当前相机的信息,用于其他用途。例如:指尖切题时绘制主体框时,需要用到相机的信息。
请在 startFingerOcr() 后并且相机开启成功(MessageEvent#CAMERA_STATES_OPENED),才能调用。
方法
CameraDeviceInfo getCameraInfo()
输出说明
| 参数 | 类型 | 说明 |
|---|---|---|
| preImgSize | Size | 预览图分辨率 |
| picImgSize | Size | 拍照图分辨率 |
| preViewRotation | int | 预览画面旋转角度 |
| imgRotation | int | 图片旋转角度 |
| preViewMirror | boolean | 预览画面是否镜像 |
| imgMirror | boolean | 图片是否镜像 |
请求示例
var fingerPro = TuringFingerPro.getInstance(this)
var _cameraInfo = fingerPro.cameraInfo
val ratiox = binding.problemOverlap.width * 1.0f /
(if (_cameraInfo.imgRotation == 90 || _cameraInfo.imgRotation == 270) _cameraInfo.preImgSize.height
else _cameraInfo.preImgSize.width) * 1.0f
val ratioy = binding.problemOverlap.height * 1.0f /
(if (_cameraInfo.imgRotation == 90 || _cameraInfo.imgRotation == 270) _cameraInfo.preImgSize.width
else _cameraInfo.preImgSize.height) * 1.0f
10. 停止/启动识别
调用 pause() 只会停止识别,预览画面会实时显示。 调用resume() 恢复识别。
方法
/**
* 暂停识别
*/
void pause();
/**
* 重新开始识别
*/
void resume();
11. 停止预览识别/ 重新开始预览识别
此方法影响预览画面,调用了stopPreView() 后画面不会实时刷新。若想恢复请调用 resumePreview()。
方法
/**
* 暂停预览
*/
void stopPreview();
/**
* 重新开始预览
*/
void resumePreview();
12. 开启指尖定位识别
只进行指尖定位识别,不识别指尖区域的文本。
方法
-
先初始化
java /** * 初始化,单独识别指尖时需要调用 * 与fingerDetect配合使用 * * @param param 初始化参数,详情见 FingerDetectParam * 预览图坐标是倒向图片上的坐标,矫正后的坐标是正向坐标。 * @param listener Point指尖坐标 * @return */ void initFingerDetect(FingerDetectParam param, TuringListenerPro<Point> listener); -
再传输图片进行识别
```java /* * 离线手指模型检测手指,识别到手指后,会在initFingerDetect中的TuringListenerPro#onEvent中回调原图 * 为了区分指尖查词和指尖定位的参数,指尖识别定位使用initFingerDetect中的参数 * * @param srcData 图片数据,传入图片原始数据,请在FingerDetectParam中设置参数,比如:旋转、镜像等。 * @param format 图片格式,仅支持ImageFormat.NV21、 ImageFormat.YUV_420_888 / void fingerDetect(byte[] srcData, int format);
/* * 离线手指模型检测手指,识别到手指后,会在initFingerDetect中的TuringListenerPro#onEvent中回调原图 * * @param bitmap 图片Bitmap,图片自行处理角度及镜像,需要传入正向且非镜像图片 * @return / void fingerDetect(Bitmap bitmap); ```
输入参数
FingerDetectParam
| 参数名称 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| isNeedImg | boolean | 否 | 是否需要返回图片。默认true:返回图片数据,图片在onSuccess中的拓展字段 |
| isStructDetect | boolean | 否 | 是否做主体检测,默认true。 false:不做主体检测,只返回预览坐标。 true:返回预览坐标、校正图片及校正图上的坐标。 预览坐标在onEvent(event)返回,当event.code=MessageEvent.CODE_RECOGNIZE_FINGER时,event.obj为预览坐标(Point 类型)。 校正坐标在onSuccess(point,extObject) 返回,point为校正坐标(Point 类型),extObject 为校正图片(Bitmap 类型)。 |
| width | int | 是 | 图片宽 |
| height | int | 是 | 图片高 |
| rotation | int | 是 | 图片角度 |
| isMirror | boolean | 是 | 图片是否镜像 |
| isPad | boolean | 否 | true:平板 false:台灯 |
| cropRatio | List | 否 | 裁切区域比例,方向为左右上下 取值范围[0.0,1.0] |
FingerDetectParam 中的width、height、rotation、isMirror字段说明:
- 如果使用 initFingerDetect()、fingerDetect() 方法进行检测,字段为必填项。
- SDK 根据rotation、mirror将图片处理为正向无镜像图片。
请求示例
-
先初始化
```kotlin private fun initFinger() { val param = FingerDetectParam.Builder() .setHeight(1920) .setWidth(1080) .setRotation(180) .setMirror(true) .build() fingerPro?.initFingerDetect(param, object : TuringListenerPro
{ override fun onError(p0: Int, p1: String?) { // 错误回调 } override fun onEvent(event: MessageEvent?) { if (event?.code == MessageEvent.CODE_RECOGNIZE_FINGER) { //预览指尖坐标回调,如果param#isStructDetect=false,则不会有此回调,直接回调onSuccess,返回最终指尖坐标,即预览图坐标 //如果param#isStructDetect=true,则在onSuccess中会回调主体校正图坐标 if (event.obj == null) return val point = event.obj as Point // Point 指尖位置,可用来绘制小红点 Log.d(TAG, "onEvent(): preFingerPosX = ${point.x}, preFingerPosY = ${point.y}") }else if (event?.code == MessageEvent.CODE_STRUCK_RESULT){ //主体检测回调,如果param#isStructDetect=false 则不会回调此事件 if (event.obj == null) return val maResult = event.obj as MAResult maResult.let { if (it.hasMA) { // 可用于绘制主体框 } } } else if (event?.code == MessageEvent.CODE_FINGER_MOVING) { // 移动中 } } override fun onSuccess(p0: Point?, ext: Any?) { Log.e(TAG, "onSuccess Point.X:${p0?.x} Point.X${p0?.y}") if (ext != null && ext is Bitmap) { maBitmap = BitmapTool.copy(ext as Bitmap) } } })} ```
-
再传输图片开启识别指尖
```kotlin // SDK不包含CameraView,下面给出客户端自定义相机开发调用方法示例 // //注意: 相机previewWidth、previewHeight 需与 FingerDetectParam 中的 width、height 保持一致。 private fun initCamera(cameraId: Int) { cameraView = CameraView( this,binding.frameLayout.width,binding.frameLayout.height, binding.frameLayout,cameraId,"16:9", previewWidth,previewHeight,1920,1080,0,true,180,false) cameraView?.setOnFrameListener(object : OnFrameListener { override fun onError(code: Int, error: String?) { Log.e(TAG, "code:$code Msg:$error") }
override fun onFrameData(data: ByteArray?, length: Int) { isShowPoint = true // 识别指尖位置 fingerPro?.fingerDetect(data, ImageFormat.NV21) } override fun onCameraEvent(event: Int) { } override fun onPicture(data: ByteArray?, length: Int) { }}) } ```
13. 资源释放
不使用时及时调用方法释放资源。
方法
void release();
常见问题
1. 调用 startFingerOcr 方法时提示: “ 获取Device ID异常!”
需要保证鉴权成功之后,调用startFingerOcr ,否则会出现上述报错。
鉴权成功的回调 InitializeInterface.TuringInitListener-->onSucess( )。
2. 如何动态配置指尖参数?
可以参考【集成步骤】->【5.参数集成】中参数动态配置,发生在 startFingerOcr 方法之前。
val configData: ConfigData = TuringConfig.getInstance(this).configData
configData.authorization.apikey ="*******"
configData.authorization.secret ="*******"
configData.globalConfig.camera.turingCameraId ="118"
TuringInitializer.getInstance(this).setGlobalConfig(configData)
3. 如何切换查词、查句或来回切换两个功能?
方式一: 先 release(),再 startFingerOcr()
① 先调用release(需要保证这个方法在startFingerOcr前调用)
② 动态配置模块参数 (如果不需要动态设置可以忽略这个步骤)
③ startFingerOcr 方法
方式二:在使用过程中动态修改 appMode 参数,实现相机不重启进行切换。
config[FingerConfig.KEY_APP_MODE] = FingerConfig.VALUE_PRO_APP_MODE_WORD
fingerPro.postFingerConfig(config)
4. ocr识别成功,如何请求查词典、TTS、翻译等功能
指尖OCR识别模块不包含词典、TTS、翻译等原子能力,需要客户端自行请求。
-
词典、分词调用方式见《在线查询词典接入文档》
-
TTS 调用方式见《TTS接入文档》
-
翻译调用方式见《语音对话接入文档》
-
口语评测调用方式见《口语评测接入文档》
5. 指尖识别问题
5.1 如何停止指尖识别
不调用 TuringFingerPro#fingerDetect() 就能停止指尖识别。
5.2 无法识别出指尖问题确定
指尖识别需要确保 GlobalParams#debugPath下fingerTip.jpg 这张图片为 正向非镜像,开启图片存储方法如下:
在初始化方法中配置存储路径及开关,此方法为调试期间使用,正式上线的话,可以关闭该配置。
val isDebug = spUtil.getBoolean(Constants.SP_KEY_DEBUG, true)
val globalParams = GlobalParams.Builder()
.setDebugPath("/sdcard/turingos")
.setOpenLog(isDebug)
.setWriteFingerTip(true)
.build()
turingInitializer.setDebugParams(globalParams)
6. 获取设备支持的分辨率
SDK 封装了 获取设备支持分辨率的工具类:com.turing.common.util.CameraDeviceUtil,可直接使用。
注:指尖OCR识别,Camera2拍照使用 ImageFormat.YUV_420_888 格式。
-
Camera2 使用方法
-
预览支持图片格式:ImageFormat.YUV_420_888。
- 拍照支持图片格式:ImageFormat.YUV_420_888、ImageFormat.JPEG。
java
/**
* 指定摄像头id、图片格式,支持的分辨率
* 预览仅支持ImageFormat.YUV_420_888。拍照仅支持ImageFormat.YUV_420_888、ImageFormat.JPEG。
* @param context
* @param imageFormat 图片格式。例如:ImageFormat.YUV_420_888,ImageFormat.JPEG。
* @param cameraId 摄像头id。一般 0:后置,1:前置
* @return
*/
public static Size[] getCamera2SupportSize(Context context, int imageFormat, int cameraId) {
- Camera1 使用方法
```java // 摄像头支持的拍照分辨率 CameraDeviceUtil#getCamera1SupportPicSize(cameraId)
// 摄像头支持的预览分辨率 CameraDeviceUtil#getCamera1SupportPreviewSize(cameraId) ```