跳转至

免标定指尖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 -- 免标定

目前图灵针对翻读,指读,查词,查句,查拼音,查段等AI能力具有两套解决方案,分别是标定和免标定,在售前阶段需要售前同事根据客户的具体产品来推荐合适的方案。 核心的参考指标有两个:图像的清晰度设备性能图像清晰度: 指设备采集图片的清晰程度,影响因素有很多,例如:多少万像素,客户是否针对摄像头进行过调优等 图灵针对客户的图灵质量建立了标准并具体相应的工具,可以方便评估客户的设备是否支持查词,查句等。 设备性能: 设备性能主要用于评估设备是否满足免标定方案,相对于标定方案,免标定方案需要前端具体一定的算力来满足算法要求,目前根据手头设备的具体情况,也建立了基本的标准,但这一指标仅具有参考意义,因为最终的响应时间,还和客户采用的分辨率,系统的内存管理,图片渲染等多因素影响,但低于图灵标准,则不建议用免标定方案

集成前提

进入摄像头参数设置页面,选取合适的分辨率。

●   确定摄像头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初始化详情见《Android 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识别

调用方法前先设置参数,见【集成步骤】中【参数配置】

流程图

start=>start: 开始
init=>operation: 设置appMode选择模式
startFinger=>operation: 启动预览startFingerOcr
postParam=>operation: 动态设置参数postFingerParams
deal=>operation: 处理回调onSuccecc
release=>end: 释放资源release
start->init->startFinger->postParam->deal->release

方法

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. 开启指尖定位识别

只进行指尖定位识别,不识别指尖区域的文本。

方法

  1. 先初始化

    java /** * 初始化,单独识别指尖时需要调用 * 与fingerDetect配合使用 * * @param param 初始化参数,详情见 FingerDetectParam * 预览图坐标是倒向图片上的坐标,矫正后的坐标是正向坐标。 * @param listener Point指尖坐标 * @return */ void initFingerDetect(FingerDetectParam param, TuringListenerPro<Point> listener);

  2. 再传输图片进行识别

    ```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字段说明:

  1. 如果使用 initFingerDetect()、fingerDetect() 方法进行检测,字段为必填项。
  2. SDK 根据rotation、mirror将图片处理为正向无镜像图片。

请求示例

  1. 先初始化

    ```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)
            }
        }
    })
    

    } ```

  2. 再传输图片开启识别指尖

    ```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) ```