自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取

系統(tǒng) OpenHarmony
本樣例基于Tesseract 庫(kù)進(jìn)行適配,使其可以運(yùn)行在 OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)上,并新增N-API接口供上層應(yīng)用調(diào)用,這樣上層應(yīng)用就可以使用Tesseract提供的相關(guān)功能。

??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??

一、簡(jiǎn)介

Tesseract (Apache 2.0 License)是一個(gè)可以進(jìn)行圖像OCR識(shí)別的C++庫(kù),可以跨平臺(tái)運(yùn)行 。本樣例基于Tesseract 庫(kù)進(jìn)行適配,使其可以運(yùn)行在 OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)上,并新增N-API接口供上層應(yīng)用調(diào)用,這樣上層應(yīng)用就可以使用Tesseract提供的相關(guān)功能。

二、效果展示

動(dòng)物圖片識(shí)別文字

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取-開源基礎(chǔ)軟件社區(qū)

身份信息識(shí)別:

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取-開源基礎(chǔ)軟件社區(qū)

提取文字信息到本地文件:

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取-開源基礎(chǔ)軟件社區(qū)

相關(guān)代碼已經(jīng)上傳至SIG倉(cāng)庫(kù),鏈接如下:
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/FA/OCRDemo。

三、目錄結(jié)構(gòu)

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取-開源基礎(chǔ)軟件社區(qū)

四、調(diào)用流程

OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取-開源基礎(chǔ)軟件社區(qū)


調(diào)用過(guò)程主要涉及到三方面,首先應(yīng)用層實(shí)現(xiàn)樣例的效果,包括頁(yè)面的布局和業(yè)務(wù)邏輯代碼;中間層主要起橋梁的作用,提供N-API接口給應(yīng)用調(diào)用,再通過(guò)三方庫(kù)的接口去調(diào)用具體的實(shí)現(xiàn);Native層使用了三方庫(kù)Tesseract提供具體的實(shí)現(xiàn)功能。

五、源碼分析

本樣例源碼的分析主要涉及到兩個(gè)方面,一方面是N-API接口的實(shí)現(xiàn),另一方面是應(yīng)用層的頁(yè)面布局和業(yè)務(wù)邏輯。

N-API實(shí)現(xiàn)

1、首先在index.d.ts文件中定義好接口

/**
* 初始化文字識(shí)別引擎
* @param lang 識(shí)別的語(yǔ)言, eg:eng、chi_sim、 eng+chi_sim,為Null或不傳則為中英文(eng+chi_sim)
* @param trainDir 訓(xùn)練模型目錄,為Null或不傳則為默認(rèn)目錄
*
* @return 初始化是否成功 0=>成功,-1=>失敗
*/
export const initOCR: (lang: string, trainDir: string) => Promise<number>;

export const initOCR: (lang: string, trainDir: string, callback: AsyncCallback<number>) => void;

/**
* 開始識(shí)別
* @param imagePath 圖片路徑(當(dāng)前支持的圖片格式為png, jpg, tiff)
*
* @return 識(shí)別結(jié)果
*/
export const startOCR: (imagePath: string) => Promise<string>;
export const startOCR: (imagePath: string, callback: AsyncCallback<string>) => void;


/**
* 銷毀資源
*/
export const destroyOCR: () => void;

代碼中可以看出N-API接口initOCR和startOCR都采用了兩種方式,一種是Promise,一種是Callback的方式。在樣例的應(yīng)用層,使用的是它們的Callback方式。

2、注冊(cè)N-API模塊和接口

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{
"initOCR", nullptr, InitOCR, nullptr, nullptr, nullptr, napi_default, nullptr
},
{
"startOCR", nullptr, StartOCR, nullptr, nullptr, nullptr, napi_default, nullptr
},
{
"destroyOCR", nullptr, DestroyOCR, nullptr, nullptr, nullptr, napi_default, nullptr
},
{
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END

static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "tesseract",
.nm_priv = ((void *)0),
.reserved = {
0
},
};

extern "C" __attribute__((constructor)) void RegisterHelloModule(void) {
napi_module_register(& demoModule);
}

通過(guò)nm_modname定義模塊名,nm_register_func注冊(cè)接口函數(shù),在Init函數(shù)中指定了JS中initOCR,startOCR,destroyOCR對(duì)應(yīng)的本地實(shí)現(xiàn)函數(shù),這樣就可以在對(duì)應(yīng)的本地實(shí)現(xiàn)函數(shù)中調(diào)用三方庫(kù)Tesseract的具體實(shí)現(xiàn)了。

3、以startOCR的Callback方式為例介紹N-API中的具體實(shí)現(xiàn)

static napi_value StartOCR(napi_env env, napi_callback_info info) {
OH_LOG_ERROR(LogType::LOG_APP, "OCR StartOCR 111");
size_t argc = 2;
napi_value args[2] = { nullptr };//1. 獲取參數(shù)
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);


//2. 共享數(shù)據(jù)
auto addonData = new StartOCRAddOnData{
.asyncWork = nullptr,
};
//3. N-API類型轉(zhuǎn)成C/C++類型
char imagePath[1024] = { 0 };
size_t length = 0;
napi_get_value_string_utf8(env, args[0], imagePath, 1024, &length);

addonData->args0 = string(imagePath);

napi_create_reference(env, args[1], 1, &addonData->callback);

//4. 創(chuàng)建async work
napi_value resourceName = nullptr;
napi_create_string_utf8(env, "startOCR", NAPI_AUTO_LENGTH, &resourceName);
napi_create_async_work(env, nullptr, resourceName, executeStartOCR, completeStartOCRForCallback, (void *)addonData, &addonData->asyncWork);

//將創(chuàng)建的async work加到隊(duì)列中,由底層調(diào)度執(zhí)行
napi_queue_async_work(env, addonData->asyncWork);

napi_value result = 0;
napi_get_null(env, &result);

return result;
}

首先通過(guò)napi_get_cb_info方法獲取JS側(cè)傳入的參數(shù)信息,將參數(shù)轉(zhuǎn)成C++對(duì)應(yīng)的類型,然后創(chuàng)建異步工作,異步工作的方法參數(shù)中包含,執(zhí)行的函數(shù)以及函數(shù)執(zhí)行完成的回調(diào)函數(shù)。
我們看一下執(zhí)行函數(shù):

static void executeStartOCR(napi_env env, void* data) {
//通過(guò)data來(lái)獲取數(shù)據(jù)
StartOCRAddOnData * addonData = (StartOCRAddOnData *)data;
napi_value resultValue;
try {
if (api != nullptr) {
//調(diào)用具體的實(shí)現(xiàn),讀取圖片像素
PIX * pix = pixRead((const char*)addonData->args0.c_str());
//設(shè)置api的圖片像素
api->SetImage(pix);

//調(diào)用文字提取接口,獲取圖片中的文字
char * result = api->GetUTF8Text();
addonData->result = result;

//釋放資源
pixDestroy (& pix);
delete[] result;
}
} catch (std::exception e) {
std::string error = "Error: ";
if (initResult != 0) {
error += "please first init tesseractocr.";
} else {
error += e.what();
}
addonData->result = error;
}
}

這個(gè)方法中通過(guò)data獲取JS傳入的參數(shù),然后調(diào)用Tesseract庫(kù)中提供的接口,調(diào)用具體的文字提取功能,獲取圖片中的文字。

執(zhí)行完成后,會(huì)回調(diào)到completeStartOCRForCallback,在這個(gè)方法中會(huì)將執(zhí)行函數(shù)中返回的結(jié)果轉(zhuǎn)換為JS的對(duì)應(yīng)類型,然后通過(guò)Callback的方式返回。

static void completeStartOCRForCallback(napi_env env, napi_status status, void * data) {
StartOCRAddOnData * addonData = (StartOCRAddOnData *)data;
napi_value callback = nullptr;
napi_get_reference_value(env, addonData->callback, &callback);
napi_value undefined = nullptr;
napi_get_undefined(env, &undefined);
napi_value result = nullptr;
napi_create_string_utf8(env, addonData->result.c_str(), addonData->result.length(), &result);
//執(zhí)行回調(diào)函數(shù)
napi_value returnVal = nullptr;
napi_call_function(env, undefined, callback, 1, &result, &returnVal);
//刪除napi_ref對(duì)象
if (addonData->callback != nullptr) {
napi_delete_reference(env, addonData->callback);
}
//刪除異步工作項(xiàng)
napi_delete_async_work(env, addonData->asyncWork);
delete addonData;
}

應(yīng)用層實(shí)現(xiàn)

應(yīng)用層主要分為三個(gè)模塊:動(dòng)物圖片文字識(shí)別,身份信息識(shí)別,提取文字到本地文件

1、動(dòng)物圖片文字識(shí)別

build() {
Column() {
Row() {
Text('點(diǎn)擊圖片進(jìn)行文字提取 提取結(jié)果 : ').fontSize('30fp').fontColor(Color.Blue)
Text(this.ocrResult).fontSize('50fp').fontColor(Color.Red)
}.margin('10vp').height('10%').alignItems(VerticalAlign.Center)

Grid() {
ForEach(this.images, (item, index) => {
GridItem() {
AnimalItem({
path1: item[0],
path2: item[1]
});
}
})
}
.padding({left: this.columnSpace, right: this.columnSpace})
.columnsTemplate("1fr 1fr 1fr") // Grid寬度均分成3份
.rowsTemplate("1fr 1fr") // Grid高度均分成2份
.rowsGap(this.rowSpace) // 設(shè)置行間距
.columnsGap(this.columnSpace) // 設(shè)置列間距
.width('100%')
.height('90%')
}
.backgroundColor(Color.Pink)
}

布局主要使用了Grid的網(wǎng)格布局,每個(gè)Item都是對(duì)應(yīng)的圖片,通過(guò)點(diǎn)擊圖片可以對(duì)點(diǎn)擊圖片進(jìn)行文字提取,將提取出的文字顯示在標(biāo)題欄。

2、身份信息識(shí)別

build() {
Row() {
Column() {
Image('/common/idImages/aobamao.jpg')
.onClick(() => {
//點(diǎn)擊圖片進(jìn)行信息識(shí)別
console.log('OCR begin dialog open 111');
this.ocrDialog.open();
ToolUtils.ocrResult(ToolUtils.aobamao, (result) => {
console.log('111 OCR result = ' + result);
this.result = result;
this.ocrDialog.close();
});
})
.margin('10vp')
.objectFit(ImageFit.Auto)
.height('50%')
Image('/common/idImages/weixiaobao.jpg')
.onClick(() => {
//點(diǎn)擊圖片進(jìn)行信息識(shí)別
this.ocrDialog.open();
ToolUtils.ocrResult(ToolUtils.weixiaobao, (result) => {
console.log('111 OCR result = ' + result);
this.result = result;
this.ocrDialog.close();
});
})
.margin('10vp')
.objectFit(ImageFit.Auto)
.height('50%')
}
.width(this.screenWidth/2)
.padding('20vp')
Column() {
Text(this.title).height('10%').fontSize('30fp').fontColor(this.titleColor)

Column() {
Text(this.result)
.fontColor('#0000FF')
.fontSize('50fp')
}.justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).height('90%')
}
.justifyContent(FlexAlign.Start)
.width('50%')
}
.width('100%')
.height('100%')
}

身份信息識(shí)別的布局最外層是一個(gè)水平布局,分為左右兩部分,左邊的子布局是垂直布局,里面是兩張不同的身份證圖片,右邊子布局也是垂直布局,主要是標(biāo)題區(qū)和識(shí)別結(jié)果的內(nèi)容顯示區(qū)。

3、提取文字到本地文件

Row() {
Column() {
Image('/common/save2FileImages/testImage1.png')
.onClick(() => {
//點(diǎn)擊圖片進(jìn)行信息識(shí)別
ToolUtils.ocrResult(ToolUtils.testImage1, (result) => {
let path = this.dir + 'ocrresult1.txt';
try {
let fd = fileio.openSync(path, 0o100 | 0o2, 0o666);
fileio.writeSync(fd, result);
fileio.closeSync(fd);
this.displayText = '文件寫入' + path;
} catch (e) {
console.log('OCR fileio error = ' + e);
}
});
})
Image('/common/save2FileImages/testImage2.png')
.onClick(() => {
//點(diǎn)擊圖片進(jìn)行信息識(shí)別
ToolUtils.ocrResult(ToolUtils.testImage2, (result) => {
let path = this.dir + 'ocrresult2.txt';
let fd = fileio.openSync(path, 0o100 | 0o2, 0o666);
fileio.writeSync(fd, result);
fileio.closeSync(fd);
this.displayText = '文件寫入' + path;
});
})
}
Column() {
Text(this.title)
Column() {
Text(this.displayText)
}
}
}

這個(gè)功能首先通過(guò)接口識(shí)別出圖片中的文字,然后再通過(guò)fileio的能力將文字寫入文件中。

六、總結(jié)

樣例通過(guò)Native的方式將C++的三方庫(kù)集成到應(yīng)用中,通過(guò)N-API方式提供接口給上層應(yīng)用調(diào)用。對(duì)于依賴三方庫(kù)能力的應(yīng)用,都可以使用這種方式來(lái)進(jìn)行,移植三方庫(kù)到Native,通過(guò)N-API提供接口給應(yīng)用調(diào)用。

??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??。

責(zé)任編輯:jianghua 來(lái)源: 51CTO開源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-02-07 15:43:13

三方庫(kù)適配鴻蒙

2022-10-11 15:04:28

NAPI開發(fā)鴻蒙

2022-04-25 09:00:46

npm包管理器

2022-01-14 09:57:14

鴻蒙HarmonyOS應(yīng)用

2023-03-22 09:09:21

鴻蒙Speexdsp

2019-07-30 11:35:54

AndroidRetrofit庫(kù)

2021-09-26 10:43:08

注冊(cè)Istio集成

2022-11-21 16:15:41

ArkUI鴻蒙

2015-04-27 19:32:16

Moxtra

2014-07-22 10:56:45

Android Stu第三方類庫(kù)

2014-07-25 09:33:22

2014-04-08 15:16:00

2015-11-05 16:44:37

第三方登陸android源碼

2011-05-07 14:20:25

加密方案Transcoder BlackBerry

2011-07-25 14:14:49

iPhone SQLITE Pldatabase

2010-03-03 15:10:49

第三方Python庫(kù)

2013-08-14 09:50:32

iOS類庫(kù)

2021-10-11 06:38:52

Go開源庫(kù)語(yǔ)言

2020-06-04 07:48:08

Istio服務(wù)注冊(cè)API Server

2022-10-25 15:05:17

NAPI開發(fā)鴻蒙
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)