HarmonyOS翻译,在HarmonyOS中用AI识别图中文字

f0b9b1944003bae40f3d340cdb89b175.png

1. 介绍

AI的通用文字识别可以对文档翻拍、街景翻拍等图片来源的文字检测和识别,可以集成在其他应用中,提供文字检测、识别的功能,并根据识别结果提供翻译、搜索等相关服务。该功能在一定程度上支持文本倾斜、拍摄角度倾斜、复杂光照条件以及复杂文本背景等场景的文字识别。通用文字识别详细介绍可参考AI-通用文字识别,分词详细介绍可参考AI-分词。

🕮 说明

● 分词文本限制在500字以内,编码格式必须为utf-8。

● 分词目前只支持中文语境。

● 支持处理的图片格式包括JPEG、JPG、PNG、GIF、BMP。

● 目前支持的语言有:中文、英文、日语、韩语、俄语、意大利语、西班牙语、葡萄牙语、德语,以及法语(将来会增加更多语种),但不支持手写字体识别。

本教程将通过以下内容为您展示如何实现基于AI的通用文字识别功能。

2. 代码结构解读

基于AI的通用文字识别示例教程主要内容包括:图片列表展示、输入文本、分词、通用文字识别、结果展示等功能,可在7 完整示例代码中查看工程代码。DevEco Studio工程代码结构如下:

09c06a2323a1baef5ed1ad930b7ca131.png

● provider:PictureProvider图片适配类,获取所有图片,并将图片放到图片列表中。

● slice:MainAbilitySlice本示例教程主页面。

● util:工具类

○ LogUtil是日志打印类,对HiLog日志进行了封装。

○ WordRecognition是通用文字识别类,对图片中的文字进行识别并保存。

○ WordSegment是分词类,对输入文本进行分词。

● MainAbility:主程序入口,DevEco Studio生成,未添加逻辑,不需变更。

● MyApplication:DevEco Studio生成,不需变更。

● resources:存放工程使用到的资源文件

○ resources\base\element中存放DevEco studio自动生成的配置文件string.json,不用变更。

○ resources\base\graphic中存放页面样式文件:

◼ ️background_ability_page.xml用于设置界面背景颜色。

◼ ️background_ability_main.xml用于设置界面布局样式。

◼ ️button_element.xml用于设置按钮样式。

○ resources\base\layout中布局文件:

◼ ️ability_main.xml用于展示图片和输入文本。

◼ ️item_image_layout.xml用于设置图片滑动区域图片。

resources\base\media下存放图片资源(本教程使用了8张.jpg图片,开发者自行准备;icon.png由DevEco Studio生成不需变更)。

● config.json:配置文件。

3. 添加并展示图片

(1)在"resources\base\media"目录下添加8张jpg图片(分别命名为1-8.jpg),并加载图片id数组,代码如下:

privateint[] pictureLists = newint[]{ResourceTable.Media_1, ResourceTable.Media_2,

ResourceTable.Media_3, ResourceTable.Media_4, ResourceTable.Media_5,

ResourceTable.Media_6, ResourceTable.Media_7, ResourceTable.Media_8};

1.

(2)获取图片id数组和MainAbilitySlice对象,代码如下:

publicPictureProvider(int[] pictureLists, Context context) {

this.pictureLists = pictureLists;

this.context = context;

}

(3)展示图片到页面,代码如下:

@Override

publicComponent getComponent(intvar1, Component var2, ComponentContainer var3) {

ViewHolder viewHolder = null;// Component中展示图片类

Component component = var2;

if (component == null) {

component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_image_layout,

null,false);

viewHolder = new ViewHolder();

Component componentImage = component.findComponentById(ResourceTable.Id_select_picture_list);

if (componentImage instanceof Image) {

viewHolder.image = (Image) componentImage;

}

component.setTag(viewHolder);//设置需要展示的图片

} else{

if (component.getTag() instanceof ViewHolder) {

viewHolder = (ViewHolder) component.getTag();

}

}

if (viewHolder != null) {

viewHolder.image.setPixelMap(pictureLists[var1]);

}

returncomponent;

}

(4)定义ViewHolder类,用于列表中展示图片,代码如下:

privatestaticclass ViewHolder {

Image image;

}

4. 识别图片中的文字

(1)调用文字识别方法对图片文字进行识别,代码如下:

wordRecognition(slice, pictureLists[index], handle); //index为待识别图片下标

publicvoid wordRecognition(Context context,intresId, MainAbilitySlice.MyEventHandle myEventHandle) {

mediaId = resId;

// 实例化ITextDetector接口

textDetector = VisionManager.getTextDetector(context);

// 实例化VisionImage对象image,并传入待检测图片pixelMap

pixelMap = getPixelMap(resId);

VisionImage image = VisionImage.fromPixelMap(pixelMap);

// 定义VisionCallback回调,异步模式下用到

VisionCallback visionCallback = getVisionCallback();

// 定义ConnectionCallback回调,实现连接能力引擎成功与否后的操作

ConnectionCallback connectionCallback = getConnectionCallback(image, visionCallback);

// 建立与能力引擎的连接

VisionManager.init(context, connectionCallback);

}

(2)异步模式下回调方法,将图片中文字识别结果通过sendResult()方法发送到主线程,代码如下:

private VisionCallback getVisionCallback() {

returnnew VisionCallback() {

@Override

publicvoid onResult(Text text) {

sendResult(text.getValue());

}

};

}

(3)连接引擎成功后进行文字识别,并将识别结果通过sendResult()方法发送到主线程,代码如下:

private ConnectionCallback getConnectionCallback(VisionImage image, VisionCallback visionCallback) {

returnnew ConnectionCallback() {

@Override

publicvoid onServiceConnect() {

// 实例化Text对象text

Text text = new Text();

// 通过TextConfiguration配置textDetector()方法的运行参数

TextConfiguration.Builder builder = new TextConfiguration.Builder();

builder.setProcessMode(VisionConfiguration.MODE_IN);

builder.setDetectType(TextDetectType.TYPE_TEXT_DETECT_FOCUS_SHOOT); // 此处变量名将会被调整

builder.setLanguage(TextConfiguration.AUTO);

TextConfiguration config = builder.build();

textDetector.setVisionConfiguration(config);

// 调用ITextDetector的detect()方法

if (!IS_ASYNC) {

intresult2 = textDetector.detect(image, text,null); // 同步

sendResult(text.getValue());

} else{

intresult2 = textDetector.detect(image,null, visionCallback); // 异步

}

}

@Override

publicvoid onServiceDisconnect() {

// 释放 成功:同步结果码为0,异步结果码为700

if ((!IS_ASYNC && (result == 0)) || (IS_ASYNC && (result == IS_ASYNC_CODE))) {

textDetector.release();

}

if (pixelMap != null) {

pixelMap.release();

pixelMap = null;

}

VisionManager.destroy();

}

};

}

🕮 说明

(1)引擎使用TextDetectType.TYPE_TEXT_DETECT_FOCUS_SHOOT(聚焦拍照OCR)。

(2)同步模式调用成功时,该函数返回结果码0。异步模式调用请求发送成功时,该函数返回结果码700。

(3)同步模式下visionCallback为null,结果码由方法返回,检测识别结果由text中返回。

(4)异步模式下visionCallback不为null,函数返回时text中的值无效(即:text参数为null),实际识别结果由回调函数visionCallback返回。

(5)IS_ASYNC为boolean变量,同步模式时该值为false,异步模式时该值为true。

将文字识别结果发送到主线程(MainAbilitySlice类中接收),代码如下:

publicvoid sendResult(String value) {

if (textDetector != null) {

textDetector.release();

}

if (pixelMap != null) {

pixelMap.release();

pixelMap = null;

VisionManager.destroy();

}

if (value != null) {

maps.put(mediaId, value);

}

if ((maps != null) && (maps.size() == pictureLists.length)) {

InnerEvent event = InnerEvent.get(1, 0, maps);

handle.sendEvent(event);

} else{

wordRecognition(slice, pictureLists[index], handle);

index++;

}

}

5. 提取用户输入的关键词

(1)获取MainAbilitySlice传递的环境参数并进行分词操作,同步方式调用sendResult()方法将分词结果发送到主线程,代码如下:

publicvoid wordSegment(Context context, String requestData, MainAbilitySlice.MyEventHandle myEventHandle) {

slice = context; // MainAbilitySlice.this

handle = myEventHandle; // MyEventHandle对象

// 使用NluClient静态类进行初始化,通过异步方式获取服务的连接。

NluClient.getInstance().init(context, new OnResultListener() {

@Override

publicvoid onResult(IntegerresultCode) {

if (!IS_ASYNC) {

// 分词同步方法

ResponseResult responseResult = NluClient.getInstance().getWordSegment(requestData,

NluRequestType.REQUEST_TYPE_LOCAL);

sendResult(responseResult.getResponseResult());

release();

} else{

// 分词异步方法

wordSegmentAsync(requestData);

}

}

}, true);

}

🕮 说明

(1)IS_ASYNC为boolean变量,同步模式时该值为false,异步模式时该值为true。

(2)responseResult对象中code属性为0表示分词成功。

(3)异步请求回调此方法,通过sendResult()方法将分词结果发送到主线程,代码如下:

private void wordSegmentAsync(String requestData) {

ResponseResult responseResult = NluClient.getInstance().getWordSegment(requestData,

NluRequestType.REQUEST_TYPE_LOCAL, new OnResultListener() {

@Override

publicvoid onResult(ResponseResult asyncResult) {

sendResult(asyncResult.getResponseResult());

release();

}

});

}

1.

(4)将分词结果发送到主线程中(MainAbilitySlice类中接收),代码如下:

private void sendResult(String result) {

List lists = null;// 分词识别结果

// 将result中分词结果转换成list

if (result.contains("\"message\":\"success\"")) {

String words = result.substring(result.indexOf(WORDS) + STEP,

result.lastIndexOf("]")).replaceAll("\"","");

if ((words == null) || ("".equals(words))) {

lists = new ArrayList(1);// 未识别到分词结果,返回"no keywords"

lists.add("no keywords");

} else{

lists = Arrays.asList(words.split(","));

}

}

InnerEvent event = InnerEvent.get(TWO, ZERO, lists);

handle.sendEvent(event);

}

6. 根据关键词匹配图片

(1)根据关键词匹配待识别图片,代码如下:

private void matchImage(List list) {

Set matchSets = new HashSet<>();

for(String str: list) { // 遍历分词结果

// imageInfos待识别图片通用文字识别结果

for(Integerkey: imageInfos.keySet()) {

if (imageInfos.get(key).indexOf(str) != NEG_ONE) {

matchSets.add(key);

}

}

}

// 获得匹配的图片

matchPictures = new int[matchSets.size()];

inti = 0;

for(intmatch: matchSets) {

matchPictures[i] = match;

i++;

}

// 展示图片

setSelectPicture(matchPictures, LIST_CONTAINER_ID_MATCH);

}

(2)展示结果图片到页面,代码如下:

private void setSelectPicture(int[] pictures,intid) {

// 获取图片

PictureProvider newsTypeAdapter = new PictureProvider(pictures, this);

Component componentById = findComponentById(id);

if (componentById instanceof ListContainer) {

ListContainer listContainer = (ListContainer) componentById;

listContainer.setItemProvider(newsTypeAdapter);

}

}

最终实现效果

在"请输入关键词"下面的输入框中输入需要分词的关键词,点击【开始通用文字识别】按钮进行关键词搜索图片,您将会在"搜索结果"下方看到包含关键词的图片。

● 垃圾分类人人做 做好分类为人人

● 可回收物 其他垃圾

ae66b787a3aafb9b4f7b465dc514b2f5.png

7. 完整示例代码

编写布局与样式

(1)base/graphic/background_ability_main.xml

ohos:shape="rectangle">

ohos:color="#FFFFFF"/>

(2)base/graphic/background_ability_page.xml

ohos:shape="rectangle">

ohos:color="#FFFAF0"/>

(3)base/graphic/button_element.xml

xmlns:ohos="http://schemas.huawei.com/res/ohos"

ohos:shape="rectangle">

ohos:radius="100"/>

ohos:color="#FF007DFE"/>

(4)base/layout/ability_main.xml

xmlns:ohos="http://schemas.huawei.com/res/ohos"

ohos:height="match_parent"

ohos:width="match_parent"

ohos:orientation="vertical"

ohos:background_element="$graphic:background_ability_page"

>

ohos:id="$+id:text_helloworld"

ohos:height="match_content"

ohos:width="match_content"

ohos:background_element="$graphic:background_ability_main"

ohos:layout_alignment="horizontal_center"

ohos:text="关键词搜索图片"

ohos:text_size="30fp"

ohos:top_margin="5vp"

/>

ohos:id="$+id:picture_list"

ohos:height="match_content"

ohos:width="match_content"

ohos:background_element="$graphic:background_ability_main"

ohos:layout_alignment="horizontal_center"

ohos:text="图片列表"

ohos:text_size="20fp"

ohos:top_margin="15vp"

/>

ohos:id="$+id:picture_list_show"

ohos:height="200vp"

ohos:width="match_parent"

ohos:orientation="horizontal"

ohos:left_margin="5vp"

ohos:right_margin="5vp"

/>

ohos:id="$+id:word_seg_title"

ohos:height="match_content"

ohos:width="match_content"

ohos:background_element="$graphic:background_ability_main"

ohos:left_margin="5vp"

ohos:text="请输入关键词:"

ohos:text_size="25fp"

ohos:top_margin="10vp"

/>

ohos:id="$+id:word_seg_text"

ohos:height="match_content"

ohos:width="match_parent"

ohos:background_element="$graphic:background_ability_main"

ohos:hint="Enter a statement."

ohos:left_padding="5vp"

ohos:right_padding="5vp"

ohos:text_alignment="vertical_center"

ohos:text_size="20fp"

ohos:top_margin="5vp"/>

ohos:id="$+id:button_search"

ohos:width="match_content"

ohos:height="match_content"

ohos:text_size="20fp"

ohos:text="开始通用文字识别"

ohos:layout_alignment="horizontal_center"

ohos:top_margin="10vp"

ohos:top_padding="1vp"

ohos:bottom_padding="1vp"

ohos:right_padding="20vp"

ohos:left_padding="20vp"

ohos:text_color="white"

ohos:background_element="$graphic:button_element"

ohos:center_in_parent="true"

ohos:align_parent_bottom="true"

ohos:bottom_margin="5vp"/>

ohos:id="$+id:picture_list_result"

ohos:height="match_content"

ohos:width="match_content"

ohos:background_element="$graphic:background_ability_main"

ohos:layout_alignment="horizontal_center"

ohos:text="搜索结果"

ohos:text_size="20fp"

ohos:top_margin="5vp"

/>

ohos:id="$+id:picture_list_match"

ohos:height="200vp"

ohos:width="match_parent"

ohos:orientation="horizontal"

ohos:left_margin="5vp"

ohos:right_margin="5vp"

/>

(5)base/layout/item_image_layout.xml

ohos:height="200vp"

ohos:width="205vp">

ohos:id="$+id:select_picture_list"

ohos:height="200vp"

ohos:width="200vp"

ohos:layout_alignment="horizontal_center"

ohos:top_margin="1vp"

ohos:scale_mode="stretch"

/>

功能逻辑代码

(1)com/huawei/searchimagebykeywords/provider/PictureProvider

import com.huawei.searchimagebykeywords.ResourceTable;

import ohos.agp.components.BaseItemProvider;

import ohos.agp.components.Component;

import ohos.agp.components.ComponentContainer;

import ohos.agp.components.Image;

import ohos.agp.components.LayoutScatter;

import ohos.app.Context;

import java.util.Optional;

publicclass PictureProvider extends BaseItemProvider {

private int[] pictureLists;

private Context context;

/**

*  picture provider

*

* @param pictureLists pictureLists

* @param context context

*/

publicPictureProvider(int[] pictureLists, Context context) {

this.pictureLists = pictureLists;

this.context = context;

}

@Override

publicintgetCount() {

returnpictureLists ==null? 0 : pictureLists.length;

}

@Override

publicObject getItem(intposition) {

returnOptional.of(this.pictureLists[position]);

}

@Override

publiclong getItemId(intposition) {

returnposition;

}

@Override

publicComponent getComponent(intvar1, Component var2, ComponentContainer var3) {

ViewHolder viewHolder = null;

Component component = var2;

if (component == null) {

component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_image_layout,

null,false);

viewHolder = new ViewHolder();

Component componentImage = component.findComponentById(ResourceTable.Id_select_picture_list);

if (componentImage instanceof Image) {

viewHolder.image = (Image) componentImage;

}

component.setTag(viewHolder);

} else{

if (component.getTag() instanceof ViewHolder) {

viewHolder = (ViewHolder) component.getTag();

}

}

if (viewHolder != null) {

viewHolder.image.setPixelMap(pictureLists[var1]);

}

returncomponent;

}

private staticclass ViewHolder {

Image image;

}

}

(2)com/huawei/searchimagebykeywords/slice/MainAbilitySlice

import com.huawei.searchimagebykeywords.ResourceTable;

import com.huawei.searchimagebykeywords.provider.PictureProvider;

import com.huawei.searchimagebykeywords.util.WordRecognition;

import com.huawei.searchimagebykeywords.util.WordSegment;

import ohos.aafwk.ability.AbilitySlice;

import ohos.aafwk.content.Intent;

import ohos.agp.components.Button;

import ohos.agp.components.Component;

import ohos.agp.components.ListContainer;

import ohos.agp.components.TextField;

import ohos.app.Context;

import ohos.eventhandler.EventHandler;

import ohos.eventhandler.EventRunner;

import ohos.eventhandler.InnerEvent;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

publicclass MainAbilitySlice extends AbilitySlice {

private staticfinalintLIST_CONTAINER_ID_SHOW = ResourceTable.Id_picture_list_show;

private staticfinalintLIST_CONTAINER_ID_MATCH = ResourceTable.Id_picture_list_match;

private staticfinalintNEG_ONE = -1;

private staticfinalintZERO = 0;

private staticfinalintONE = 1;

private staticfinalintTWO = 2;

private Context slice;

private EventRunner runner;

private MyEventHandle myEventHandle;

private int[] pictureLists = newint[]{ResourceTable.Media_1, ResourceTable.Media_2,

ResourceTable.Media_3, ResourceTable.Media_4, ResourceTable.Media_5,

ResourceTable.Media_6, ResourceTable.Media_7, ResourceTable.Media_8};

private Component selectComponent;

private intselectPosition;

private Button button;

private TextField textField;

private Map imageInfos;

private int[] matchPictures;

@Override

publicvoid onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(ResourceTable.Layout_ability_main);

slice = MainAbilitySlice.this;

// 展示图片列表

setSelectPicture(pictureLists, LIST_CONTAINER_ID_SHOW);

// 所有图片通用文字识别

wordRecognition();

// 设置需要分词的语句

Component componentText = findComponentById(ResourceTable.Id_word_seg_text);

if (componentText instanceof TextField) {

textField = (TextField) componentText;

}

// 点击按钮进行文字识别

Component componentSearch = findComponentById(ResourceTable.Id_button_search);

if (componentSearch instanceof Button) {

button = (Button) componentSearch;

button.setClickedListener(listener -> wordSegment());

}

}

@Override

publicvoid onActive() {

super.onActive();

}

@Override

publicvoid onForeground(Intent intent) {

super.onForeground(intent);

}

// 设置图片选择区域

private void setSelectPicture(int[] pictures,intid) {

// 获取图片

PictureProvider newsTypeAdapter = new PictureProvider(pictures, this);

Component componentById = findComponentById(id);

if (componentById instanceof ListContainer) {

ListContainer listContainer = (ListContainer) componentById;

listContainer.setItemProvider(newsTypeAdapter);

}

}

// 通用文字识别

private void wordRecognition() {

initHandler();

WordRecognition wordRecognition = new WordRecognition();

wordRecognition.setParams(slice, pictureLists, myEventHandle);

wordRecognition.sendResult(null);

}

// 分词

private void wordSegment() {

// 组装关键词,作为分词对象

String requestData = "{\"text\":"+ textField.getText() +",\"type\":0}";

initHandler();

new WordSegment().wordSegment(slice, requestData, myEventHandle);

}

// 匹配图片

private void matchImage(List list) {

Set matchSets = new HashSet<>();

for(String str: list) {

for(Integerkey: imageInfos.keySet()) {

if (imageInfos.get(key).indexOf(str) != NEG_ONE) {

matchSets.add(key);

}

}

}

// 获得匹配的图片

matchPictures = new int[matchSets.size()];

inti = 0;

for(intmatch: matchSets) {

matchPictures[i] = match;

i++;

}

// 展示图片

setSelectPicture(matchPictures, LIST_CONTAINER_ID_MATCH);

}

private void initHandler() {

runner = EventRunner.getMainEventRunner();

if (runner == null) {

return;

}

myEventHandle = new MyEventHandle(runner);

}

publicclass MyEventHandle extends EventHandler {

MyEventHandle(EventRunner runner) throws IllegalArgumentException {

super(runner);

}

@Override

protected void processEvent(InnerEvent event) {

super.processEvent(event);

inteventId = event.eventId;

if (eventId == ONE) {

// 通用文字识别

if (event.object instanceof Map) {

imageInfos = (Map) event.object;

}

}

if (eventId == TWO) {

// 分词

if (event.object instanceof List) {

List lists = (List) event.object;

if ((lists.size() > ZERO) && (!"no keywords".equals(lists.get(ZERO)))) {

// 根据输入关键词 匹配图片

matchImage(lists);

}

}

}

}

}

}

(3)com/huawei/searchimagebykeywords/util/LogUtil

import ohos.hiviewdfx.HiLog;

import ohos.hiviewdfx.HiLogLabel;

publicclass LogUtil {

private staticfinal String TAG_LOG ="LogUtil";

private staticfinal HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, LogUtil.TAG_LOG);

private staticfinal String LOG_FORMAT ="%{public}s: %{public}s";

private LogUtil() {

}

publicstaticvoid info(String tag, String msg) {

HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg);

}

publicstaticvoid error(String tag, String msg) {

HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg);

}

}

(4)com/huawei/searchimagebykeywords/util/WordRecognition

import com.huawei.searchimagebykeywords.slice.MainAbilitySlice;

import ohos.ai.cv.common.ConnectionCallback;

import ohos.ai.cv.common.VisionCallback;

import ohos.ai.cv.common.VisionConfiguration;

import ohos.ai.cv.common.VisionImage;

import ohos.ai.cv.common.VisionManager;

import ohos.ai.cv.text.ITextDetector;

import ohos.ai.cv.text.Text;

import ohos.ai.cv.text.TextConfiguration;

import ohos.ai.cv.text.TextDetectType;

import ohos.app.Context;

import ohos.eventhandler.InnerEvent;

import ohos.global.resource.NotExistException;

import ohos.global.resource.Resource;

import ohos.global.resource.ResourceManager;

import ohos.media.image.ImageSource;

import ohos.media.image.PixelMap;

import ohos.media.image.common.PixelFormat;

import ohos.media.image.common.Rect;

import ohos.media.image.common.Size;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

publicclass WordRecognition {

private staticfinal boolean IS_ASYNC =false;

private staticfinalintIS_ASYNC_CODE = 700;

private Context slice;

private ITextDetector textDetector;

private PixelMap pixelMap;

private MainAbilitySlice.MyEventHandle handle;

private int[] pictureLists;

private intmediaId;

private Map maps = new HashMap<>();

private intindex;

private intresult;

publicvoid setParams(Context context,int[] pictureIds, MainAbilitySlice.MyEventHandle myEventHandle) {

slice = context;

pictureLists = pictureIds;

handle = myEventHandle;

}

publicvoid wordRecognition(Context context,intresId, MainAbilitySlice.MyEventHandle myEventHandle) {

mediaId = resId;

// 实例化ITextDetector接口

textDetector = VisionManager.getTextDetector(context);

// 实例化VisionImage对象image,并传入待检测图片pixelMap

pixelMap = getPixelMap(resId);

VisionImage image = VisionImage.fromPixelMap(pixelMap);

// 定义VisionCallback回调,异步模式下用到

VisionCallback visionCallback = getVisionCallback();

// 定义ConnectionCallback回调,实现连接能力引擎成功与否后的操作

ConnectionCallback connectionCallback = getConnectionCallback(image, visionCallback);

// 建立与能力引擎的连接

VisionManager.init(context, connectionCallback);

}

private VisionCallback getVisionCallback() {

returnnew VisionCallback() {

@Override

publicvoid onResult(Text text) {

sendResult(text.getValue());

}

@Override

publicvoid onError(inti) {

}

@Override

publicvoid onProcessing(floatv) {

}

};

}

private ConnectionCallback getConnectionCallback(VisionImage image, VisionCallback visionCallback) {

returnnew ConnectionCallback() {

@Override

publicvoid onServiceConnect() {

// 实例化Text对象text

Text text = new Text();

// 通过TextConfiguration配置textDetector()方法的运行参数

TextConfiguration.Builder builder = new TextConfiguration.Builder();

builder.setProcessMode(VisionConfiguration.MODE_IN);

builder.setDetectType(TextDetectType.TYPE_TEXT_DETECT_FOCUS_SHOOT);

builder.setLanguage(TextConfiguration.AUTO);

TextConfiguration config = builder.build();

textDetector.setVisionConfiguration(config);

// 调用ITextDetector的detect()方法

if (!IS_ASYNC) {

intresult2 = textDetector.detect(image, text,null); // 同步

sendResult(text.getValue());

} else{

intresult2 = textDetector.detect(image,null, visionCallback); // 异步

}

}

@Override

publicvoid onServiceDisconnect() {

// 释放

if ((!IS_ASYNC && (result == 0)) || (IS_ASYNC && (result == IS_ASYNC_CODE))) {

textDetector.release();

}

if (pixelMap != null) {

pixelMap.release();

pixelMap = null;

}

VisionManager.destroy();

}

};

}

publicvoid sendResult(String value) {

if (textDetector != null) {

textDetector.release();

}

if (pixelMap != null) {

pixelMap.release();

pixelMap = null;

VisionManager.destroy();

}

if (value != null) {

maps.put(mediaId, value);

}

if ((maps != null) && (maps.size() == pictureLists.length)) {

InnerEvent event = InnerEvent.get(1, 0, maps);

handle.sendEvent(event);

} else{

wordRecognition(slice, pictureLists[index], handle);

index++;

}

}

// 获取图片

private PixelMap getPixelMap(intresId) {

ResourceManager manager = slice.getResourceManager();

byte[] datas = new byte[0];

try {

Resource resource = manager.getResource(resId);

datas = readBytes(resource);

resource.close();

} catch (IOException | NotExistException e) {

LogUtil.error("get pixelmap failed, read resource bytes failed, ", e.getLocalizedMessage());

}

ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();

srcOpts.formatHint = "image/jpg";

ImageSource imageSource;

imageSource = ImageSource.create(datas, srcOpts);

ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();

decodingOpts.desiredSize = new Size(0, 0);

decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);

decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;

pixelMap = imageSource.createPixelmap(decodingOpts);

returnpixelMap;

}

private staticbyte[] readBytes(Resource resource) {

final intbufferSize = 1024;

final intioEnd = -1;

ByteArrayOutputStream output= new ByteArrayOutputStream();

byte[] buffers = new byte[bufferSize];

byte[] results = new byte[0];

while (true) {

try {

intreadLen = resource.read(buffers, 0, bufferSize);

if (readLen == ioEnd) {

results = output.toByteArray();

break;

}

output.write(buffers, 0, readLen);

} catch (IOException e) {

LogUtil.error("OrcAbilitySlice.getPixelMap","read resource failed ");

break;

} finally {

try {

output.close();

} catch (IOException e) {

LogUtil.error("OrcAbilitySlice.getPixelMap","close output failed");

}

}

}

returnresults;

}

}

(5)com/huawei/searchimagebykeywords/util/WordSegment

import com.huawei.searchimagebykeywords.slice.MainAbilitySlice;

import ohos.ai.nlu.NluClient;

import ohos.ai.nlu.NluRequestType;

import ohos.ai.nlu.OnResultListener;

import ohos.ai.nlu.ResponseResult;

import ohos.app.Context;

import ohos.eventhandler.InnerEvent;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

publicclass WordSegment {

private staticfinal boolean IS_ASYNC =true;

private staticfinal String WORDS ="words";

private staticfinalintZERO = 0;

private staticfinalintTWO = 2;

private staticfinalintSTEP = 8;

private Context slice;

private MainAbilitySlice.MyEventHandle handle;

publicvoid wordSegment(Context context, String requestData, MainAbilitySlice.MyEventHandle myEventHandle) {

slice = context;

handle = myEventHandle;

// 使用NluClient静态类进行初始化,通过异步方式获取服务的连接。

NluClient.getInstance().init(context, new OnResultListener() {

@Override

publicvoid onResult(IntegerresultCode) {

if (!IS_ASYNC) {

// 同步

ResponseResult responseResult = NluClient.getInstance().getWordSegment(requestData,

NluRequestType.REQUEST_TYPE_LOCAL);

sendResult(responseResult.getResponseResult());

release();

} else{

// 异步

wordSegmentAsync(requestData);

}

}

}, true);

}

private void wordSegmentAsync(String requestData) {

ResponseResult responseResult = NluClient.getInstance().getWordSegment(requestData,

NluRequestType.REQUEST_TYPE_LOCAL, new OnResultListener() {

@Override

publicvoid onResult(ResponseResult asyncResult) {

sendResult(asyncResult.getResponseResult());

release();

}

});

}

private void sendResult(String result) {

List lists = null; // 分词识别结果

// 将result中分词结果转换成list

if (result.contains("\"message\":\"success\"")) {

String words = result.substring(result.indexOf(WORDS) + STEP,

result.lastIndexOf("]")).replaceAll("\"","");

if ((words == null) || ("".equals(words))) {

lists = new ArrayList(1);

lists.add("no keywords"); // 未识别到分词结果,返回"no keywords"

} else{

lists = Arrays.asList(words.split(","));

}

}

InnerEvent event = InnerEvent.get(TWO, ZERO, lists);

handle.sendEvent(event);

}

private void release() {

NluClient.getInstance().destroy(slice);

}

}

(6)com/huawei/searchimagebykeywords/MainAbility

import com.huawei.searchimagebykeywords.slice.MainAbilitySlice;

import ohos.aafwk.ability.Ability;

import ohos.aafwk.content.Intent;

publicclass MainAbility extends Ability {

@Override

publicvoid onStart(Intent intent) {

super.onStart(intent);

super.setMainRoute(MainAbilitySlice.class.getName());

}

}

(7)com/huawei/searchimagebykeywords/MyApplication

import ohos.aafwk.ability.AbilityPackage;

publicclass MyApplication extends AbilityPackage {

@Override

publicvoid onInitialize() {

super.onInitialize();

}

}

🕮 说明

以上代码仅demo演示参考使用,产品化的代码需要考虑数据校验和国际化。

8. 恭喜您

通过本教程的学习,您已学会如何使用AI能力中的通用文字识别和分词。

【编辑推荐】

【责任编辑:jianghua TEL:(010)68476606】

点赞 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值