36 识别配置进阶:方向检测与多语言

引言

在《拍照识别文字》示例工程中,textRecognition.recognizeText 的调用看起来只有两行:组装 VisionInfo、再传入 TextRecognitionConfiguration。但正是后者这个看似简单的配置对象,决定了识别引擎对"歪图"和"异向文字"的容忍度,也直接影响一次识别的耗时。本文围绕 TextRecognitionConfiguration 的唯一个人化字段 isDirectionDetectionSupported 展开,讲清方向检测的原理、适用场景,以及当前 SDK 对多语言的支持边界,并结合工程代码给出针对证件、票据、屏幕截图三类场景的配置建议。

正文知识点

1. TextRecognitionConfiguration 只有一个字段

textRecognition(来自 @kit.CoreVisionKit,系统能力 SystemCapability.AI.OCR.TextRecognition)的配置项 TextRecognitionConfiguration 目前只有一个可选字段:

字段 类型 可选 默认值 说明

isDirectionDetectionSupported boolean true 是否开启文字朝向检测

默认值为 true,即默认开启朝向检测。官方注释给出一条非常实用的性能建议:如果能确认图片本身是正向的,可以显式将其设为 false 以提升识别性能

2. 朝向检测的原理与效果

手机拍照时,用户很少能保证画面中的文字严格水平。常见的情况有三类:

  • 图片整体旋转:竖屏拍横版票据,或手持方向不对,图片里文字是 90°/180°/270° 的;
  • 小幅倾斜:手持不稳导致的几度倾斜;
  • 透视畸变:拍摄角度与文本平面不垂直造成的"近大远小"。
开启 isDirectionDetectionSupported: true 后,识别引擎会先在图像中检测文字的整体朝向,自动将图像旋转到正向后再执行识别,因此对"旋转 90°、180°、270° 的图片"能直接输出可读文本。代价是多一次朝向判定 + 一次旋转预处理,单次识别耗时有所增加;当拍摄主体很正时,这笔开销属于浪费。

需要说明的是,方向检测解决的是"整体旋转/大角度倾斜",并不是万能。官方约束明确:拍摄角度与文本所在平面垂直方向的夹角应小于 30 度,超过这个范围属于"模糊不清或倾斜严重的图像",识别质量会明显下降,此时开启方向检测也无济于事。这类问题要靠引导用户正对拍摄来解决,而不是依赖配置项。

3. 多语言支持

当前 SDK 支持识别五种语言,且是自动检测、无需显式指定的:

  • 简体中文
  • 英文
  • 日文
  • 韩文
  • 繁体中文
也就是说,一张同时含有中文和英文的票据,recognizeText 会一次性全部识别出来,不需要像某些平台那样先选语言再识别。这也意味着应用侧不需要维护"语言切换"逻辑,识别代码可以保持与工程现状一致——一个 TextRecognitionConfiguration 走天下。

如果想在代码里查询设备支持的语言列表,可以调用 textRecognition.getSupportedLanguages() 获取支持的语言类型列表,用于在设置页展示或做能力自检(具体签名以当前 SDK 版本 API 参考为准)。

4. 三种场景的配置建议

场景 图片特点 建议 理由

证件(身份证、护照、名片) 用户会主动正对拍摄,基本正向 isDirectionDetectionSupported: false 省掉朝向检测的开销,识别更快
票据(小票、发票、快递单) 常常横放、旋转 90° isDirectionDetectionSupported: true 依赖朝向检测自动纠正横竖方向
屏幕截图 由应用生成,100% 正向 isDirectionDetectionSupported: false 无任何倾斜,开启纯属浪费

代码示例

工程中 recognizeImage 里配置的写法如下(源码参考:entry/src/main/ets/common/utils/Camera.ets):

let visionInfo: textRecognition.VisionInfo = {
  pixelMap: pixelMapInstance
};
let textConfiguration: textRecognition.TextRecognitionConfiguration = {
  isDirectionDetectionSupported: true
};
await textRecognition.recognizeText(visionInfo, textConfiguration).then((TextRecognitionResult) => {
  // ...
})

如果想把"按场景配置"落地,可以给 Camera 类增加一个识别场景枚举,再按场景返回配置:

// 按识别场景返回对应的配置(可在 Camera.ets 中扩展)
export enum RecognitionScene {
  DOCUMENT = 0,   // 证件/文档,用户正对拍摄
  RECEIPT = 1,    // 票据,可能横放
  SCREENSHOT = 2  // 屏幕截图,必然正向
}

function buildTextConfiguration(scene: RecognitionScene): textRecognition.TextRecognitionConfiguration {
  // 证件与截图场景已知图片正向,关闭朝向检测换取性能
  const needDirectionDetection: boolean = scene === RecognitionScene.RECEIPT;
  return {
    isDirectionDetectionSupported: needDirectionDetection
  };
}

调用处只需替换一行:

let textConfiguration = buildTextConfiguration(RecognitionScene.RECEIPT);
await textRecognition.recognizeText(visionInfo, textConfiguration).then((result) => {
  // ...
})

查询设备支持的语言列表:

import { textRecognition } from '@kit.CoreVisionKit';

function logSupportedLanguages(): void {
  // getSupportedLanguages 的具体调用形式以当前 SDK API 参考为准
  const languages: Array<string> = textRecognition.getSupportedLanguages();
  console.info(`[OCR] supported languages: ${JSON.stringify(languages)}`);
}

运行效果与注意事项

  • 效果验证:将一张横版小票图片旋转 90° 后分别用 true / false 识别——true 能正确输出可读文本,false 的输出往往是乱码或空白,可以直接感受到方向检测的价值。
  • 性能差异:在图片正向的前提下,关闭方向检测能明显缩短单次识别耗时,连续拍照识别的场景(如本工程的"再次识别")体感更明显。
  • 输入约束:识别能力仅支持 JPEG、JPG、PNG 格式;文本总长度不超过 10000 字符;图像尺寸需满足 100px < 高度 < 15210px、100px < 宽度 < 10000px,高宽比建议小于 10:1;建议成像质量在 720p 以上。工程中拍照输出 JPEG 并直接以 component.byteBuffer 交给 recognizeImage,完全落在约束之内。
  • 能力判断:调用前务必像工程那样用 canIUse('SystemCapability.AI.OCR.TextRecognition') 做系统能力判断,模拟器不支持该能力。

总结

TextRecognitionConfiguration 虽小,却是"又快又准"的关键杠杆:默认开启的朝向检测为"歪图"兜底,代价是额外耗时;对于已知正向的输入(证件、截图),显式置 false 即可白拿性能收益。多语言方面,五种语言自动识别、无需配置,应用侧零成本。建议把"场景 → 配置"抽象成函数,为后续扩展留下清晰的接缝。


*本系列文章基于 HarmonyOS 5.0.5 SDK(API 12)与示例工程 aicharacter-recognition 编写,文中接口以对应版本 API 参考为准。*

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐