一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

OpenAtom OpenHarmony ? 來源:未知 ? 2022-11-14 21:25 ? 次閱讀

點(diǎn)擊藍(lán)字 ╳ 關(guān)注我們

開源項(xiàng)目 OpenHarmony是每個(gè)人的 OpenHarmony 624cd338-641f-11ed-8abf-dac502259ad0.jpg

郭岳峰

深圳開鴻數(shù)字產(chǎn)業(yè)發(fā)展有限公司

OS框架開發(fā)工程師

以下內(nèi)容來自嘉賓分享,不代表開放原子開源基金會(huì)觀點(diǎn)

1.簡(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)功能。

2.效果展示

識(shí)別文字 身份信息識(shí)別 629c32ca-641f-11ed-8abf-dac502259ad0.png ? 提取文字信息到本地文件 ?62f77702-641f-11ed-8abf-dac502259ad0.png ? ?

相關(guān)代碼已經(jīng)上傳至SIG倉(cāng)庫(kù),鏈接如下:

https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/FA/OCRDemo

3.目錄結(jié)構(gòu)

6330784a-641f-11ed-8abf-dac502259ad0.png ?

4.調(diào)用流程

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

5.源碼分析

本樣例源碼的分析主要涉及到兩個(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;




/**
 * 銷毀資源
 */
exportconstdestroyOCR:()=>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);
}
通過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;
}
首先通過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) {
    //通過data來獲取數(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è)方法中通過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)類型,然后通過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)的圖片,通過點(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è)功能首先通過接口識(shí)別出圖片中的文字,然后再通過fileio的能力將文字寫入文件中。

6.總結(jié)

樣例通過Native的方式將C++的三方庫(kù)集成到應(yīng)用中,通過N-API方式提供接口給上層應(yīng)用調(diào)用。對(duì)于依賴三方庫(kù)能力的應(yīng)用,都可以使用這種方式來進(jìn)行,移植三方庫(kù)到Native,通過N-API提供接口給應(yīng)用調(diào)用。 關(guān)于樣例開發(fā),我之前還分享過《如何利用OpenHarmony ArkUI的Canvas組件實(shí)現(xiàn)涂鴉功能?》、《如何通過OpenHarmony的音頻模塊實(shí)現(xiàn)錄音變速功能?》歡迎感興趣的開發(fā)者進(jìn)行了解并與我交流樣例開發(fā)經(jīng)驗(yàn)。


原文標(biāo)題:OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取

文章出處:【微信公眾號(hào):OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2469

    瀏覽量

    43642
  • OpenHarmony
    +關(guān)注

    關(guān)注

    26

    文章

    3804

    瀏覽量

    17853

原文標(biāo)題:OpenHarmony集成OCR三方庫(kù)實(shí)現(xiàn)文字提取

文章出處:【微信號(hào):gh_e4f28cfa3159,微信公眾號(hào):OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    三方庫(kù)移植OpenHarmony過程

    戰(zhàn)碼先鋒,PR征集令(以下簡(jiǎn)稱“戰(zhàn)碼先鋒”)第二期正如火如荼地進(jìn)行中,涉及OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)主干倉(cāng)、SIG倉(cāng)、三方庫(kù),共計(jì)1
    的頭像 發(fā)表于 09-22 10:11 ?3070次閱讀

    使用OpenHarmonyNDK移植三方庫(kù)Speexdsp

    大家好,我是一名即將本科畢業(yè)的OpenHarmony開發(fā)者,去年暑假利用了兩個(gè)月時(shí)間移植了一個(gè)語(yǔ)音處理的三方庫(kù)Speexdsp到OpenHarmony標(biāo)準(zhǔn)系統(tǒng)。主要為其編寫了`buil
    的頭像 發(fā)表于 05-16 10:18 ?2549次閱讀
    使用<b class='flag-5'>OpenHarmony</b>NDK移植<b class='flag-5'>三方</b><b class='flag-5'>庫(kù)</b>Speexdsp

    快速移植OpenHarmony三方芯片平臺(tái)的方法

    移植概述本文面向希望將OpenHarmony移植到三方芯片平臺(tái)硬件的開發(fā)者,介紹一種借助三方芯片平臺(tái)自帶Linux內(nèi)核的現(xiàn)有能力,快速移植OpenHarmony
    發(fā)表于 04-12 11:08

    【PIMF】OpenHarmony啃論文俱樂部—盤點(diǎn)開源鴻蒙三方庫(kù)【1】

    OpenHarmony third_party三方庫(kù)三方開源庫(kù)是封裝的軟件功能,可以避免重復(fù)造輪子、提升軟件開發(fā)效率。
    發(fā)表于 06-17 19:48

    【PIMF】OpenHarmony啃論文俱樂部—盤點(diǎn)開源鴻蒙三方庫(kù)【2】

    OpenHarmony third_party三方庫(kù)三方庫(kù)(開源庫(kù))是封裝的軟件功能,可以避免
    發(fā)表于 06-29 16:44

    4步成功將三方庫(kù)——speexdsp移植到OpenHarmony

    歸)進(jìn)行分享,他在完成了一個(gè)三方庫(kù)OpenHarmony標(biāo)準(zhǔn)系統(tǒng)上的移植工作后,總結(jié)了以下經(jīng)驗(yàn)。四步實(shí)現(xiàn)三方
    發(fā)表于 09-27 12:02

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

    ;#125;這個(gè)功能首先通過接口識(shí)別出圖片中的文字,然后再通過fileio的能力將文字寫入文件中。6. 總結(jié)樣例通過Native的方式將C++的三方庫(kù)
    發(fā)表于 11-15 12:09

    OpenHarmony三方庫(kù)適配指南

    本文以OpenHarmony-3.2-Beta4上適配modbus編譯動(dòng)態(tài)庫(kù)為例。獲取三方庫(kù)使用之前要做好代碼溯源,確認(rèn)可用的版本,開源許可和發(fā)布方式等。通過正確的路徑獲取源碼,可以是
    發(fā)表于 04-07 09:12

    OpenAtom OpenHarmony 三方庫(kù)創(chuàng)建發(fā)布及安全隱私檢測(cè)

    三方庫(kù)進(jìn)行功能性測(cè)試,如果三方庫(kù)沒有真正的功能實(shí)現(xiàn)或其功能無法在OpenHarmony上驗(yàn)證,
    發(fā)表于 11-13 17:27

    openharmony三方組件適配移植的文字組合拆分庫(kù)

    項(xiàng)目介紹 項(xiàng)目名稱: MatchView 所屬系列: openharmony的第三方組件適配移植 功能: 是一款由進(jìn)度條來控制文字的組合和拆分的庫(kù) 項(xiàng)目移植狀態(tài): 主功能完成 調(diào)用差異
    發(fā)表于 03-30 10:59 ?0次下載

    基于openharmony實(shí)現(xiàn)綁定ability和fraction頁(yè)面切換的三方庫(kù)

    項(xiàng)目介紹 項(xiàng)目名稱:Alligator 所屬系列:openharmony的第三方組件適配移植 功能:通過注解處理器實(shí)現(xiàn)一套綁定ability和fraction頁(yè)面切換的三方
    發(fā)表于 04-08 10:21 ?1次下載

    總結(jié)移植三方庫(kù)OpenHarmony的經(jīng)驗(yàn)

    三方庫(kù)主要是基于標(biāo)準(zhǔn) Linux 系統(tǒng)的 c/c++ 開源庫(kù),所以三方庫(kù)的移植工作,首先是在標(biāo)準(zhǔn) Linux 系統(tǒng)搭建環(huán)境、編譯與驗(yàn)證,然后
    的頭像 發(fā)表于 05-07 15:52 ?6867次閱讀

    鴻蒙三方庫(kù)適配指南

    本文以 OpenHarmony-3.2-Beta4 上適配 modbus 編譯動(dòng)態(tài)庫(kù)為例。 獲取三方庫(kù) 使用之前要做好代碼溯源,確認(rèn)可用的版本,開源許可和發(fā)布方式等。 通過正確的路徑獲
    的頭像 發(fā)表于 02-14 09:33 ?4064次閱讀

    【開源三方庫(kù)】bignumber.js:一個(gè)大數(shù)數(shù)學(xué)庫(kù)

    點(diǎn)擊藍(lán)字 ╳ 關(guān)注我們 開源項(xiàng)目 OpenHarmony 是每個(gè)人的 OpenHarmony OpenAtom OpenHarmony (以下簡(jiǎn)稱“OpenHarmony”)
    的頭像 發(fā)表于 08-18 21:05 ?1091次閱讀

    【開源三方庫(kù)】crypto-js加密算法庫(kù)的使用方法

    點(diǎn)擊藍(lán)字 ╳ 關(guān)注我們 開源項(xiàng)目 OpenHarmony 是每個(gè)人的 OpenHarmony OpenAtom OpenHarmony(簡(jiǎn)稱“OpenHarmony”)
    的頭像 發(fā)表于 09-07 21:10 ?2129次閱讀