一饶唤、前言
有時候在讀電子文檔的過程中,往往會遇到圖片形式的文本贯钩,想要復(fù)制下來募狂,記個筆記甚是不便办素,需要對照著打字輸入,活生生被逼成鍵盤俠啊......
被逼無奈祸穷,何不自己造個輪子性穿,開發(fā)一款自己專屬的文字識別工具呢,于是我們找到了Matlab App Designer雷滚。
玩過 Matlab 的朋友們都知道需曾,構(gòu)建圖形用戶界面,Matlab提供了兩種工具祈远,一是用guide
構(gòu)建呆万,俗稱GUI
,在未來版本中會移除车份;二是用App Designer
谋减,俗稱App
,這是官方推薦的躬充,也是以后主流的框架逃顶。
今天我們就通過一個簡單案例來介紹如何利用App
設(shè)計一個圖片文字識別工具。
搭建的方式主要有兩種:
App設(shè)計器:靈活充甚、方便、簡單霸褒,現(xiàn)代化方法伴找;
基于
uifigure
的編程方式:靈活、重構(gòu)方便废菱,適合構(gòu)建復(fù)雜技矮、大型的圖形用戶界面,原始社會方法殊轴。
這里我們就以編程方式進(jìn)行創(chuàng)建衰倦。
二、預(yù)備
1. API接口
文字識別涉及到光學(xué)字符識別(Optical Character Recognition旁理,OCR)技術(shù)樊零,如果我們自己造這種底層的輪子,要有高精度的識別率孽文,那估計累得夠嗆驻襟。
幸運(yùn)的是市場上已經(jīng)有成熟的工具了,如百度智能云芋哭、阿里云沉衣、科大訊飛等均提供了API接口,只需借過來用就完事减牺。這里主要以百度智能云
提供的文字識別API為例豌习。
免費(fèi)申請文字識別功能后存谎,在控制臺可以查看到API Key
和Secret Key
,由這兩個參數(shù)可以獲得access_token
肥隆,它是調(diào)用API
接口的必需參數(shù)(如下圖紅色方框所示)愕贡。
通過查看文字識別的技術(shù)文檔,我們可以得到通用文字識別(標(biāo)準(zhǔn)版)
的請求接口巷屿,如下:
HTTP 方法:
POST
請求URL:
https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic
URL參數(shù):屬性名:access_token固以,值:通過
API Key
和Secret Key
獲取的access_token
,參考“Access Token獲取”Header:屬性名:Content-Type嘱巾,值:application/x-www-form-urlencoded
請求參數(shù):屬性名:image憨琳,值:圖像數(shù)據(jù),base64編碼后進(jìn)行urlencode旬昭,要求base64編碼和urlencode后大小不超過4M篙螟,最短邊至少15px,最長邊最大4096px问拘,支持jpg/jpeg/png/bmp格式
返回參數(shù):屬性名:words_result遍略,值:識別結(jié)果數(shù)組
關(guān)于具體的HTTP請求過程接下來會細(xì)聊。
2. 圖像的Base64編碼
Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)碼的編碼方式之一骤坐,它是包括小寫字母
a-z
绪杏、大寫字母A-Z
、數(shù)字0-9
纽绍、符號+
蕾久、/
共64個字符的字符集,等號=
用來作為后綴用途拌夏。任何符號都可以轉(zhuǎn)換成這個字符集中的字符僧著,該轉(zhuǎn)換過程就叫做Base64編碼。Base64編碼具有不可讀性障簿,需要解碼后才能閱讀盹愚。
許多編程語言都提供了現(xiàn)成的Base64編碼庫函數(shù),Matlab也不例外站故,大家不妨 help matlab.net.base64encode
查看細(xì)節(jié)皆怕。
下面提供三種Matlab中的實現(xiàn)方式:
- Java類---org.apache.commons.codec.binary.Base64 和 matlab.net.base64encode
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n40" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> function base64string = img2base64(fileName)
%IMG2BASE64 Coding an image to base64 file
% INPUTS:
% fileName string, an image file name
% OUTPUTS:
% base64string string, the input image's base64 code
% USAGE:
% >>base64string = img2base64('1.jpg')
% >>base64string = 'xxx'
%
try
fid = fopen(fileName, 'rb');
bytes = fread(fid);
fclose(fid);
% -------------------------------------------
% First method
% -------------------------------------------
encoder = org.apache.commons.codec.binary.Base64;
base64string = char(encoder.encode(bytes))';
% -------------------------------------------
% Second method
% -------------------------------------------
% base64string = matlab.net.base64encode(bytes);
catch
disp('The file does not exist!');
base64string = '';
end % end try
end % end function</pre>
- 使用Python
base64
模塊
Matlab中可以直接使用Python,那Python中提供的模塊base64
就可以直接使用了世蔗,源代碼如下:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n45" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> function base64string = img2base64_(fileName)
%IMG2BASE64 Coding an image to base64 file
% INPUTS:
% fileName string, an image file name
% OUTPUTS:
% base64string string, the input image's base64 code
% USAGE:
% >>base64string = img2base64('1.jpg')
% >>base64string = 'xxx'
%
try
f = py.open(fileName, 'rb');
bytes = f.read();
f.close();
temp = char(py.base64.b64encode(bytes));
temp = regexp(temp, '(?<=b'').+(?='')', 'match');
base64string = temp{1};
catch
disp('The file does not exist!');
base64string = '';
end % end try
end % end function</pre>
我們可以對如下所示的同一張圖片(500 x 500)進(jìn)行base64編碼端逼,比較一下編碼速度:
結(jié)果:'/9j/4AAQSkZ...AAAAAAD/9k='
- Java類---org.apache.commons.codec.binary.Base64 ? 0.000783 秒
- matlab.net.base64encode ? 0.017589 秒
- Python
base64
模塊 ? 0.000709 秒
可以發(fā)現(xiàn)使用Java類和Python base64
模塊的方法,速度相當(dāng)污淋,而使用matlab.net.base64encode
速度要慢20多倍顶滩,但編碼一張大小為500 x 500的圖像耗時0.02秒左右,其速度是非常之快了寸爆。
綜合一下礁鲁,我們推薦使用org.apache.commons.codec.binary.Base64
類進(jìn)行base64編碼盐欺。
3. 屏幕截圖
識別掃描版pdf文檔、視頻教程等中的文字時仅醇,我們需要對待識別文字所在區(qū)域截個圖冗美,保存為圖像再進(jìn)行后續(xù)識別操作。要實現(xiàn)上述過程析二,首先需要對屏幕進(jìn)行截圖粉洼,Matlab通過借助java.awt.Robot
這個Java類來實現(xiàn),截屏源代碼如下所示:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n61" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> function imgData = screenSnipping
%screenSnipping Capturel full-screen to an image
% Output:
% imgData, uint8, image data.
% Source code from: https://www.mathworks.com/support/search.html/answers/362358-how-do-i-take-a-screenshot-using-matlab.html?fq=asset_type_name:answer%20category:matlab/audio-and-video&page=1
% Modified: Qingpinwangzi
% Date: Apr 14, 2021.
% Take screen capture
robo = java.awt.Robot;
tk = java.awt.Toolkit.getDefaultToolkit();
rectSize = java.awt.Rectangle(tk.getScreenSize());
cap = robo.createScreenCapture(rectSize);
% Convert to an RGB image
rgb = typecast(cap.getRGB(0, 0, cap.getWidth, cap.getHeight, [], 0, cap.getWidth), 'uint8');
imgData = zeros(cap.getHeight, cap.getWidth, 3, 'uint8');
imgData(:, :, 1) = reshape(rgb(3:4:end), cap.getWidth, [])';
imgData(:, :, 2) = reshape(rgb(2:4:end), cap.getWidth, [])';
imgData(:, :, 3) = reshape(rgb(1:4:end), cap.getWidth, [])';
end</pre>
4. 調(diào)用百度API識別文字
上述第1節(jié)中我們提到過叶摄,access_token
是調(diào)用API
接口的必需參數(shù)属韧。通過閱讀技術(shù)文檔得知,需要API Key
和Secret Key
進(jìn)行http請求就可以獲得蛤吓,核心代碼如下:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n64" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> url = ['https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=', apiKey, '&client_secret=', secretKey];
res = webread(url, options);
access_token = res.access_token;</pre>
有了access_token
我們就可以調(diào)用文字識別API進(jìn)行文字識別了宵喂,這里再分享下識別文字的源代碼:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n66" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> function result = getWordsByBaiduOCR(fileName, apiKey, secretKey, accessToken, apiURL, outType)
%GETWORDSBYBAIDUOCR return recognition words
% INPUTS:
% fileName string, an image file name
% apiKey string, the API Key of the application
% secretKey string, The Secret Key of the application
% accessToken string, default is '', get the Access Token by API
% Key and Secret Key.
% apiURL string, such as:
% 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate'
% 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic'
% 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic'
% outType, 'MultiLine|SingleLine'
% OUTPUTS:
% result []|struct
% USAGE:
% >>result = getWordsByBaiduOCR(fileName, apiKey, secretKey, accessToken, apiURL)
% Date: Mar 18, 2021.
% Author: 清貧王子
%
options = weboptions('RequestMethod', 'post');
if isempty(outType)
outType = 'MultiLine';
end
if isempty(accessToken)
url = ['https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=', apiKey, '&client_secret=', secretKey];
res = webread(url, options);
access_token = res.access_token;
else
access_token = accessToken;
end % end if
url = [apiURL, '?access_token=', access_token];
options.HeaderFields = { 'Content-Type', 'application/x-www-form-urlencoded'};
imgBase64String = img2base64(fileName);
if isempty(imgBase64String)
result = '';
return
end % end if
res = webwrite(url, 'image', imgBase64String, options);
wordsRsult = res.words_result;
data.ocrResultChar = '';
if strcmp(outType, 'SingleLine')
for ii = 1 : size(wordsRsult, 1)
data.ocrResultChar = [data.ocrResultChar, wordsRsult(ii,1).words];
end % end for
elseif strcmp(outType, 'MultiLine')
for ii = 1 : size(wordsRsult, 1)
data.ocrResultChar{ii} = wordsRsult(ii,1).words;
end % end for
end
result = data.ocrResultChar;
end % end function</pre>
簡單測試下這個函數(shù),輸入下面所示的圖片会傲,我們進(jìn)行圖片(截圖地址:https://ww2.mathworks.cn/products/matlab/app-designer.html)中的文字識別锅棕。
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n69" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> >> result =
1×7 cell 數(shù)組
列 1 至 4
{'App設(shè)計工具幫助您…'} {'開發(fā)專業(yè)背景。您只…'} {'面(GUI)設(shè)計布局,…'} {'編程淌山。'}
列 5 至 7
{'要共享App,您可以使…'} {' MATLAB Compile…'} {'桌面App或 Web App'}
result{1}
ans =
'App設(shè)計工具幫助您創(chuàng)建專業(yè)的App,同時并不要求軟件'</pre>
識別結(jié)果中共有7個cell
裸燎,代表識別了圖片中的7行
文字,即1個cell
對應(yīng)1行
識別的文字艾岂,如result{1}
的結(jié)果顺少。
三、工具搭建
以基于uifigure
的編程方式創(chuàng)建APP王浴,我們推薦面向?qū)ο螅∣OP)方法編程,簡單起見梅猿,這里主要封裝一個類來實現(xiàn)所需的功能氓辣。當(dāng)然更標(biāo)準(zhǔn)的做法是利用MVC
等設(shè)計模式將界面和邏輯分離,能達(dá)到對擴(kuò)展開放袱蚓,對修改封閉
的軟件設(shè)計原則钞啸。
1. 功能需求
我們的功能需求非常簡單,主要有以下兩個功能:
識別已經(jīng)存在的圖像中的文字
識別掃描版pdf文檔喇潘、視頻教程等中的文字
實現(xiàn)第1個功能体斩,我們只需要加載圖像,然后調(diào)用識別函數(shù)進(jìn)行識別颖低,將識別結(jié)果顯示到文本區(qū)域就可以了絮吵;而實現(xiàn)第2個功能,首先需要屏幕截圖忱屑,選取待識別文字所在的區(qū)域蹬敲,存儲為圖像暇昂,后續(xù)處理和實現(xiàn)第1個功能的一樣。
根據(jù)上述描述伴嗡,我們需要的控件有:加載圖像按鈕急波,截圖按鈕,圖像顯示器瘪校,識別結(jié)果顯示文本域澄暮。另外,需要一個清理按鈕阱扬,用于清除顯示的圖像和識別結(jié)果泣懊;還需要一個設(shè)置按鈕,用于配置API Key
和Secret Key
价认。
便于敘述嗅定,我們先展示下最終設(shè)計的結(jié)果,如下圖所示:
image
|
image
|
---|---|
文字識別工具主界面 | 設(shè)置界面 |
在設(shè)置界面中用踩,需要兩個標(biāo)簽和兩個文本框渠退,兩外需要兩個按鈕。據(jù)此脐彩,我們需要的控件都清楚了碎乃,接下來讓我們一起來創(chuàng)建他們吧!
2. 實現(xiàn)細(xì)節(jié)
主要封裝一個類來實現(xiàn)所需的功能惠奸,我們給這個類起個名:ReadWords
梅誓,這個類需要繼承matlab.apps.AppBase
,它的屬性就是界面中的所有控件,那么這個類看上去應(yīng)該是這樣的:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n93" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> classdef ReadWords < matlab.apps.AppBase
%%
properties
UIFig matlab.ui.Figure
ContainerForMain matlab.ui.container.GridLayout
ThisTB matlab.ui.container.Toolbar
SnippingToolBtn matlab.ui.container.toolbar.PushTool
ImgLoadToolBtn matlab.ui.container.toolbar.PushTool
SetupToolBtn matlab.ui.container.toolbar.PushTool
CleanToolBtn matlab.ui.container.toolbar.PushTool
ImgShow matlab.ui.control.Image
WordsShowTA matlab.ui.control.TextArea
ContainerForSetup matlab.ui.container.GridLayout
APIKeyText matlab.ui.control.EditField
SecrectKeyText matlab.ui.control.EditField
ResetBtn matlab.ui.control.Button
SaveBtn matlab.ui.control.Button
end % end properties
%%
properties(Hidden, Dependent)
APIKeyVal
SecrectKeyVal
end % end properties
%%
properties(Access = protected)
HasSetup = false
end % end properties
end % end classdef</pre>
下面說明下一些重要的屬性
公有屬性:
UIFig 必須是
matlab.ui.Figure
類的屬性佛南,通過uifigure
構(gòu)造梗掰,這是整個工具的主窗口ContainerForMain 必須是
matlab.ui.container.GridLayout
類的屬性,通過uigridlayout
構(gòu)造嗅回,這是主窗口的布局容器ThisTB 必須是
matlab.ui.container.Toolbar
類的屬性及穗,通過uitoolbar
構(gòu)造,這是工具欄的容器绵载,用于放置SnippingToolBtn
埂陆、ImgLoadToolBtn
、SetupToolBtn
娃豹、CleanToolBtn
這4個工具按鈕ImgShow 必須是
matlab.ui.control.Image
類的屬性焚虱,通過uiimage
構(gòu)造,用于顯示加載或者截圖后的圖像WordsShowTA 必須是
matlab.ui.control.TextArea
類的屬性懂版,通過uitextarea
構(gòu)造鹃栽,用于顯示文字識別結(jié)果ContainerForSetup 設(shè)置界面中的網(wǎng)格容器
APIKeyText和SecrectKeyText 主要用于輸入
APIKey
和SecrectKey
ResetBtn和SaveBtn兩個按鈕分別用來實現(xiàn)重置和保存
APIKey
和SecrectKey
從屬灭将、隱藏屬性:
APIKeyVal 用于接收APIKeyText中輸入的
APIKey
的值SecrectKeyVal 用于接收SecrectKeyText中輸入的
SecrectKey
的值
受保護(hù)屬性:
-
HasSetup 用于標(biāo)識是否配置了
APIKey
和SecrectKey
咧最,默認(rèn)為false
至此脊岳,我們設(shè)置好了所有的屬性包个,然后進(jìn)行構(gòu)造方法、析構(gòu)方法以及類方法的編寫摹察。
加上構(gòu)造方法恩掷、析構(gòu)方法以及從屬屬性APIKeyVal
和SecrectKeyVal
的get
方法的代碼后看上去是這樣的:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n125" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> classdef ReadWords < matlab.apps.AppBase
%%
properties
UIFig matlab.ui.Figure
ContainerForMain matlab.ui.container.GridLayout
ThisTB matlab.ui.container.Toolbar
SnippingToolBtn matlab.ui.container.toolbar.PushTool
ImgLoadToolBtn matlab.ui.container.toolbar.PushTool
SetupToolBtn matlab.ui.container.toolbar.PushTool
CleanToolBtn matlab.ui.container.toolbar.PushTool
ImgShow matlab.ui.control.Image
WordsShowTA matlab.ui.control.TextArea
ContainerForSetup matlab.ui.container.GridLayout
APIKeyText matlab.ui.control.EditField
SecrectKeyText matlab.ui.control.EditField
ResetBtn matlab.ui.control.Button
SaveBtn matlab.ui.control.Button
end % end properties
%%
properties(Hidden, Dependent)
APIKeyVal
SecrectKeyVal
end % end properties
%%
properties(Access = protected)
HasSetup = false
end % end properties
%%
methods
% --------------------------------------
% % Constructor
% --------------------------------------
function app = ReadWords
% Create UIFigure and components
app.buildApp();
% Register the app with App Designer
registerApp(app, app.UIFig)
if nargout == 0
clear app
end
end % end Constructor
% --------------------------------------
% % Destructor
% --------------------------------------
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFig)
end % end Constructor
% --------------------------------------
% % Get/Set methods
% --------------------------------------
% get.APIKeyVal
function apiKeyVal = get.APIKeyVal(app)
apiKeyVal = app.APIKeyText.Value;
end
% get.SecrectKeyVal
function secrectKeyVal = get.SecrectKeyVal(app)
secrectKeyVal = app.SecrectKeyText.Value;
end
end % end methods
end % end classdef</pre>
析構(gòu)方法(Destructor)的寫法是固定的,構(gòu)造方法中的registerApp(app, app.UIFig)
也是固定的供嚎,另外的buildApp()
方法就用來創(chuàng)建界面黄娘、注冊各個控件。
我們將后續(xù)的方法都創(chuàng)建為私有方法克滴,添加了buildApp()
方法后的整個ReadWords
類是下面這樣的:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n128" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> classdef ReadWords < matlab.apps.AppBase
%%
properties
UIFig matlab.ui.Figure
ContainerForMain matlab.ui.container.GridLayout
ThisTB matlab.ui.container.Toolbar
SnippingToolBtn matlab.ui.container.toolbar.PushTool
ImgLoadToolBtn matlab.ui.container.toolbar.PushTool
SetupToolBtn matlab.ui.container.toolbar.PushTool
CleanToolBtn matlab.ui.container.toolbar.PushTool
ImgShow matlab.ui.control.Image
WordsShowTA matlab.ui.control.TextArea
ContainerForSetup matlab.ui.container.GridLayout
APIKeyText matlab.ui.control.EditField
SecrectKeyText matlab.ui.control.EditField
ResetBtn matlab.ui.control.Button
SaveBtn matlab.ui.control.Button
end % end properties
%%
properties(Hidden, Dependent)
APIKeyVal
SecrectKeyVal
end % end properties
%%
properties(Access = protected)
HasSetup = false
end % end properties
%%
methods
% --------------------------------------
% % Constructor
% --------------------------------------
function app = ReadWords
% Create UIFigure and components
app.buildApp();
% Register the app with App Designer
registerApp(app, app.UIFig)
if nargout == 0
clear app
end
end % end Constructor
% --------------------------------------
% % Destructor
% --------------------------------------
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFig)
end % end Constructor
% --------------------------------------
% % Get/Set methods
% --------------------------------------
% get.APIKeyVal
function apiKeyVal = get.APIKeyVal(app)
apiKeyVal = app.APIKeyText.Value;
end
% get.SecrectKeyVal
function secrectKeyVal = get.SecrectKeyVal(app)
secrectKeyVal = app.SecrectKeyText.Value;
end
end % end methods
%%
methods(Access = private)
% buildApp
function buildApp(app)
%
% --------------------------------------
% % Main Figure
% --------------------------------------
app.UIFig = uifigure();
app.UIFig.Icon = 'icons/img2text.png';
app.UIFig.Name = 'ReadWords';
app.UIFig.Visible = 'off';
app.UIFig.Position = [app.UIFig.Position(1), app.UIFig.Position(2), 745, 420];
app.UIFig.AutoResizeChildren = 'on';
app.UIFig.Units = 'Normalized';
app.setAutoResize(app.UIFig, true);
% --------------------------------------
% % Toolbar
% --------------------------------------
app.ThisTB = uitoolbar(app.UIFig);
% SetupToolBtn
app.SetupToolBtn = uipushtool(app.ThisTB);
app.SetupToolBtn.Icon = 'icons/setup.png';
app.SetupToolBtn.Tooltip = 'Setup';
% SnippingToolBtn
app.SnippingToolBtn = uipushtool(app.ThisTB);
app.SnippingToolBtn.Icon = 'icons/snip.png';
app.SnippingToolBtn.Tooltip = 'Screenshot';
% ImgLoadToolBtn
app.ImgLoadToolBtn = uipushtool(app.ThisTB);
app.ImgLoadToolBtn.Icon = 'icons/load.png';
app.ImgLoadToolBtn.Tooltip = 'Load image';
% CleanToolBtn
app.CleanToolBtn = uipushtool(app.ThisTB);
app.CleanToolBtn.Icon = 'icons/clean.png';
app.CleanToolBtn.Tooltip = 'Clean';
% --------------------------------------
% % ContainerForMain
% --------------------------------------
app.ContainerForMain = uigridlayout(app.UIFig, [1, 2]);
% ContainerForMain
imgShowPanel = uipanel(app.ContainerForMain, 'Title', 'Original');
resultShowPanel = uipanel(app.ContainerForMain, 'Title', 'Result');
% ImgShow
imgShowPanelLay = uigridlayout(imgShowPanel, [1, 1]);
imgShowPanelLay.RowSpacing = 0;
imgShowPanelLay.ColumnSpacing = 0;
app.ImgShow = uiimage(imgShowPanelLay);
% WordsShowTA
resultShowPanelLay = uigridlayout(resultShowPanel, [1, 1]);
resultShowPanelLay.RowSpacing = 0;
resultShowPanelLay.ColumnSpacing = 0;
app.WordsShowTA = uitextarea(resultShowPanelLay);
app.WordsShowTA.FontSize = 22;
% --------------------------------------
% % ContainerForSetup
% --------------------------------------
app.ContainerForSetup = uigridlayout(app.UIFig, [4, 3]);
app.ContainerForSetup.RowHeight = {22, 22, 22, '1x'};
app.ContainerForSetup.ColumnWidth = {'1x', '1x', '2.5x'};
app.ContainerForSetup.Visible = 'off';
apiKeyLabel = uilabel(app.ContainerForSetup, 'Text', 'API Key');
apiKeyLabel.HorizontalAlignment = 'right';
apiKeyLabel.Layout.Row = 1;
apiKeyLabel.Layout.Column = 1;
% APIKeyText
app.APIKeyText = uieditfield(app.ContainerForSetup);
app.APIKeyText.Layout.Row = 1;
app.APIKeyText.Layout.Column = 2;
secrectKeyLabel = uilabel(app.ContainerForSetup, 'Text', 'Secrect Key');
secrectKeyLabel.HorizontalAlignment = 'right';
secrectKeyLabel.Layout.Row = 2;
secrectKeyLabel.Layout.Column = 1;
% SecrectKeyText
app.SecrectKeyText = uieditfield(app.ContainerForSetup);
app.SecrectKeyText.Layout.Row = 2;
app.SecrectKeyText.Layout.Column = 2;
% ResetBtn
app.ResetBtn = uibutton(app.ContainerForSetup, 'Text', 'Reset');
app.ResetBtn.Layout.Row = 3;
app.ResetBtn.Layout.Column = 1;
% SaveBtn
app.SaveBtn = uibutton(app.ContainerForSetup, 'Text', 'Save');
app.SaveBtn.Layout.Row = 3;
app.SaveBtn.Layout.Column = 2;
% Set visibility for UIFig
movegui(app.UIFig, 'center');
app.UIFig.Visible = 'on';
% --------------------------------------
% % RunstartupFcn
% --------------------------------------
app.runStartupFcn(@startupFcn);
end % end buildApp
end % methods
end % end classdef</pre>
需要注意的是逼争,工具欄按鈕和窗口的圖標(biāo)來源于:https://www.easyicon.cc/。一些常見的圖標(biāo)素材都可以從中免費(fèi)下載劝赔。我們已經(jīng)將圖標(biāo)下載完畢誓焦,需要的朋友可以點擊下方鏈接來下載:
鏈接:https://pan.baidu.com/s/11kIvt4SX-MhQ2ltEeC18ZA 提取碼:5i3k
另外,app.runStartupFcn(@startupFcn);
語句調(diào)用的是父類matlab.apps.AppBase
的方法着帽,我們將各個控件的注冊任務(wù)放在startupFcn
這個方法中完成杂伟。這里不妨先注釋掉這個語句,直接運(yùn)行ReadWords.m
便可以顯示出我們剛才在buildApp
方法中構(gòu)造的界面了仍翰,動圖演示如下:
可以看到赫粥,我們在點擊工具欄各個按鈕時,沒有反應(yīng)予借,這是因為到目前為止我們還沒有給各個控件注冊回調(diào)方法越平,那接下來將會在startupFcn
這個方法中完成各個控件的注冊任務(wù),代碼如下:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n135" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> classdef ReadWords < matlab.apps.AppBase
%%
properties
UIFig matlab.ui.Figure
ContainerForMain matlab.ui.container.GridLayout
ThisTB matlab.ui.container.Toolbar
SnippingToolBtn matlab.ui.container.toolbar.PushTool
ImgLoadToolBtn matlab.ui.container.toolbar.PushTool
SetupToolBtn matlab.ui.container.toolbar.PushTool
CleanToolBtn matlab.ui.container.toolbar.PushTool
ImgShow matlab.ui.control.Image
WordsShowTA matlab.ui.control.TextArea
ContainerForSetup matlab.ui.container.GridLayout
APIKeyText matlab.ui.control.EditField
SecrectKeyText matlab.ui.control.EditField
ResetBtn matlab.ui.control.Button
SaveBtn matlab.ui.control.Button
end % end properties
%%
properties(Hidden, Dependent)
APIKeyVal
SecrectKeyVal
end % end properties
%%
properties(Access = protected)
HasSetup = false
end % end properties
%%
methods
% --------------------------------------
% % Constructor
% --------------------------------------
function app = ReadWords
% Create UIFigure and components
app.buildApp();
% Register the app with App Designer
registerApp(app, app.UIFig)
if nargout == 0
clear app
end
end % end Constructor
% --------------------------------------
% % Destructor
% --------------------------------------
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFig)
end % end Constructor
% --------------------------------------
% % Get/Set methods
% --------------------------------------
% get.APIKeyVal
function apiKeyVal = get.APIKeyVal(app)
apiKeyVal = app.APIKeyText.Value;
end
% get.SecrectKeyVal
function secrectKeyVal = get.SecrectKeyVal(app)
secrectKeyVal = app.SecrectKeyText.Value;
end
end % end methods
%%
methods(Access = private)
% buildApp
function buildApp(app)
%
% --------------------------------------
% % Main Figure
% --------------------------------------
app.UIFig = uifigure();
app.UIFig.Icon = 'icons/img2text.png';
app.UIFig.Name = 'ReadWords';
app.UIFig.Visible = 'off';
app.UIFig.Position = [app.UIFig.Position(1), app.UIFig.Position(2), 745, 420];
app.UIFig.AutoResizeChildren = 'on';
app.UIFig.Units = 'Normalized';
app.setAutoResize(app.UIFig, true);
% --------------------------------------
% % Toolbar
% --------------------------------------
app.ThisTB = uitoolbar(app.UIFig);
% SetupToolBtn
app.SetupToolBtn = uipushtool(app.ThisTB);
app.SetupToolBtn.Icon = 'icons/setup.png';
app.SetupToolBtn.Tooltip = 'Setup';
% SnippingToolBtn
app.SnippingToolBtn = uipushtool(app.ThisTB);
app.SnippingToolBtn.Icon = 'icons/snip.png';
app.SnippingToolBtn.Tooltip = 'Screenshot';
% ImgLoadToolBtn
app.ImgLoadToolBtn = uipushtool(app.ThisTB);
app.ImgLoadToolBtn.Icon = 'icons/load.png';
app.ImgLoadToolBtn.Tooltip = 'Load image';
% CleanToolBtn
app.CleanToolBtn = uipushtool(app.ThisTB);
app.CleanToolBtn.Icon = 'icons/clean.png';
app.CleanToolBtn.Tooltip = 'Clean';
% --------------------------------------
% % ContainerForMain
% --------------------------------------
app.ContainerForMain = uigridlayout(app.UIFig, [1, 2]);
% ContainerForMain
imgShowPanel = uipanel(app.ContainerForMain, 'Title', 'Original');
resultShowPanel = uipanel(app.ContainerForMain, 'Title', 'Result');
% ImgShow
imgShowPanelLay = uigridlayout(imgShowPanel, [1, 1]);
imgShowPanelLay.RowSpacing = 0;
imgShowPanelLay.ColumnSpacing = 0;
app.ImgShow = uiimage(imgShowPanelLay);
% WordsShowTA
resultShowPanelLay = uigridlayout(resultShowPanel, [1, 1]);
resultShowPanelLay.RowSpacing = 0;
resultShowPanelLay.ColumnSpacing = 0;
app.WordsShowTA = uitextarea(resultShowPanelLay);
app.WordsShowTA.FontSize = 22;
% --------------------------------------
% % ContainerForSetup
% --------------------------------------
app.ContainerForSetup = uigridlayout(app.UIFig, [4, 3]);
app.ContainerForSetup.RowHeight = {22, 22, 22, '1x'};
app.ContainerForSetup.ColumnWidth = {'1x', '1x', '2.5x'};
app.ContainerForSetup.Visible = 'off';
apiKeyLabel = uilabel(app.ContainerForSetup, 'Text', 'API Key');
apiKeyLabel.HorizontalAlignment = 'right';
apiKeyLabel.Layout.Row = 1;
apiKeyLabel.Layout.Column = 1;
% APIKeyText
app.APIKeyText = uieditfield(app.ContainerForSetup);
app.APIKeyText.Layout.Row = 1;
app.APIKeyText.Layout.Column = 2;
secrectKeyLabel = uilabel(app.ContainerForSetup, 'Text', 'Secrect Key');
secrectKeyLabel.HorizontalAlignment = 'right';
secrectKeyLabel.Layout.Row = 2;
secrectKeyLabel.Layout.Column = 1;
% SecrectKeyText
app.SecrectKeyText = uieditfield(app.ContainerForSetup);
app.SecrectKeyText.Layout.Row = 2;
app.SecrectKeyText.Layout.Column = 2;
% ResetBtn
app.ResetBtn = uibutton(app.ContainerForSetup, 'Text', 'Reset');
app.ResetBtn.Layout.Row = 3;
app.ResetBtn.Layout.Column = 1;
% SaveBtn
app.SaveBtn = uibutton(app.ContainerForSetup, 'Text', 'Save');
app.SaveBtn.Layout.Row = 3;
app.SaveBtn.Layout.Column = 2;
% Set visibility for UIFig
movegui(app.UIFig, 'center');
app.UIFig.Visible = 'on';
% --------------------------------------
% % RunstartupFcn
% --------------------------------------
app.runStartupFcn(@startupFcn);
end % end buildApp
% startupFcn
function startupFcn(app, ~, ~)
% Setup APIKeyText and SecrectKeyText
if exist('apikey.mat', 'file')
temp = load('apikey.mat');
app.APIKeyText.Value = temp.key.apiKeyVal;
app.APIKeyText.Editable = 'off';
app.SecrectKeyText.Value = temp.key.secrectKeyVal;
app.SecrectKeyText.Editable = 'off';
end
% Register callback
app.SnippingToolBtn.ClickedCallback = @app.clickedSnippingToolBtn;
app.ImgLoadToolBtn.ClickedCallback = @app.clickedImgLoadToolBtn;
app.SetupToolBtn.ClickedCallback = @app.clickedSetupToolBtn;
app.CleanToolBtn.ClickedCallback = @app.clickedCleanToolBtn;
app.ResetBtn.ButtonPushedFcn = @app.callbackResetBtn;
app.SaveBtn.ButtonPushedFcn = @app.callbackSaveBtn;
end % end function
end % methods
end % end classdef</pre>
由此灵迫,我們總共為6個按鈕注冊了6個回調(diào)方法秦叛,需要都進(jìn)行實現(xiàn),不然觸發(fā)按鈕時瀑粥,該按鈕不會做出響應(yīng)书闸。簡單起見,這里我們以實現(xiàn)設(shè)置界面中的SaveBtn
的回調(diào)方法callbackSaveBtn
為例子來說明利凑。
在沒有設(shè)置APIKey
或SecrectKey
前,觸發(fā)SnippingToolBtn
或者ImgLoadToolBtn
會有先進(jìn)行設(shè)置的提示:
callbackSaveBtn
方法實現(xiàn)的邏輯:首先由HasSetup
屬性判斷是否進(jìn)行了APIKey
和SecrectKey
的設(shè)置(初始默認(rèn)是false
沒有設(shè)置)嫌术,如果沒有設(shè)置哀澈,會提示沒有APIKey
或SecrectKey
,則需要輸入APIKey
和SecrectKey
的值度气,然后點擊保存按鈕割按,那么后臺會將獲取到的值存儲下來(.mat文件),更新HasSetup
的值為true
磷籍,后續(xù)我們就不必要再次輸入了适荣,要想更換值的話现柠,點擊重置按鈕重新配置即可;如果進(jìn)行了設(shè)置(HasSetup
屬性為true
)弛矛,直接保存即可够吩。
具體的代碼如下:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n141" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> % --------------------------------------
% % Callback functions
% --------------------------------------
% callbackSaveBtn
function callbackSaveBtn(app, ~, ~)
if ~isempty(app.SecrectKeyText.Value) && ~isempty(app.APIKeyText.Value)
key.apiKeyVal = app.APIKeyText.Value;
key.secrectKeyVal = app.SecrectKeyText.Value;
if exist('apikey.mat', 'file')
delete('apikey.mat');
end
save('apikey.mat', 'key');
!attrib +s +h apikey.mat
uialert(app.UIFig, 'Save successfully!', 'Confirm', 'Icon', 'success');
app.APIKeyText.Editable = 'off';
app.SecrectKeyText.Editable = 'off';
else
uialert(app.UIFig, 'API Key or Secrect Key is empty!', 'Confirm', 'Icon', 'warning');
end % end if
end % callbackSaveBtn</pre>
實現(xiàn)了保存按鈕的功能后,就可以得到如下動圖所示的效果了丈氓。
其他的回調(diào)函數(shù)源代碼:
<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="matlab" cid="n145" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.8rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: var(--codeboxes); position: relative !important; border-radius: 0.3rem; color: rgb(255, 255, 255); padding: 8px 1.5rem 6px 0px; margin-bottom: 1.5rem; margin-top: 1.5rem; width: inherit; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> % clickedSnippingToolBtn
function clickedSnippingToolBtn(app, ~, ~)
if ~isempty(app.SecrectKeyText.Value) && ~isempty(app.APIKeyText.Value)
app.UIFig.Visible = 'off';
pause(0.1);
outFileName = 'temp.png';
cropImg(outFileName);
!attrib +s +h temp.png
%
app.ImgShow.ImageSource = imread(outFileName);
app.UIFig.Visible = 'on';
%
apiURL = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic';
words = getWordsByBaiduOCR(outFileName, app.APIKeyVal, app.SecrectKeyVal, '', apiURL, 'MultiLine');
app.WordsShowTA.Value = words;
else
msg = {'API Key or Secrect Key is empty!'; 'Please set it up first!'};
uialert(app.UIFig, msg, 'Confirm', 'Icon', 'warning');
end
end % end clickedSnippingToolBtn
% clickedImgLoadToolBtn
function clickedImgLoadToolBtn(app, ~, ~)
if ~isempty(app.SecrectKeyText.Value) && ~isempty(app.APIKeyText.Value)
[fName, fPath] = uigetfile({'.png'; '.jpg'; '.bmp'; '.tif'}, 'Open image');
if ~isequal(any([fName, fPath]), 0)
img = imread(strcat(fPath, fName));
outFileName = 'temp.png';
if exist(outFileName, 'file')
delete(outFileName)
end
imwrite(img, outFileName);
!attrib +s +h temp.png
%
app.ImgShow.ImageSource = imread(outFileName);
app.UIFig.Visible = 'on';
%
apiURL = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic';
words = getWordsByBaiduOCR(outFileName, app.APIKeyVal, app.SecrectKeyVal, '', apiURL, 'MultiLine');
app.WordsShowTA.Value = words;
else
return
end % end if
else % end if
msg = {'API Key or Secrect Key is empty!'; 'Please set it up first!'};
uialert(app.UIFig, msg, 'Confirm', 'Icon', 'warning');
end
end % end clickedImgLoadToolBtn
% clickedSetupToolBtn
function clickedSetupToolBtn(app, ~, ~)
if ~app.HasSetup
app.ContainerForMain.Visible = 'off';
app.ContainerForSetup.Visible = 'on';
app.HasSetup = true;
else
app.ContainerForMain.Visible = 'on';
app.ContainerForSetup.Visible = 'off';
app.HasSetup = false;
end
end % end clickedSetupToolBtn
% clickedCleanToolBtn
function clickedCleanToolBtn(app, ~, ~)
app.WordsShowTA.Value = '';
app.ImgShow.ImageSource = '';
end % end clickedCleanToolBtn
% callbackResetBtn
function callbackResetBtn(app, ~, ~)
app.APIKeyText.Value = '';
app.APIKeyText.Editable = 'on';
app.SecrectKeyText.Value = '';
app.SecrectKeyText.Editable = 'on';
end % callbackResetBtn</pre>
四周循、使用演示
現(xiàn)在讓我們來測試一下搭建的圖像識別工具吧,比如万俗,某麻子同學(xué)是一名研究生湾笛,在閱讀那種掃描版的pdf文獻(xiàn)時,想把其中的一段語句復(fù)制下來用于記錄筆記或者做PPT用闰歪,這時我們的工具就派上用場了:
剎那間嚎研,某麻子同學(xué)得到了想要的結(jié)果,露出了久違的幸福的一笑库倘!
五临扮、結(jié)語
至此,我們完成了一個比較完整的文字識別工具于樟!希望您喜歡公条,并且可以從中獲得有用的東西。
本文完整代碼迂曲,請在GZH內(nèi)回復(fù)“文字識別工具”進(jìn)行下載靶橱。
【往期推薦】