Learn how to use Matlab App Designer to design text recognition tools

[TOC]

One, foreword

Sometimes in the process of reading electronic documents, often meet the text in the form of pictures, want to copy down, write down a note is very inconvenient, need to control the typing input, live was forced into the keyboard……

We had no choice but to build a wheel and develop our own text recognition tool, so we found Matlab App Designer.

Matlab to build graphical user interface, Matlab provides two tools, one is to use guide to build, commonly known as GUI, will be removed in the future version; The second is to use App Designer, commonly known as App, which is officially recommended and the mainstream framework in the future.

Today we will introduce how to use App to design a picture text recognition tool through a simple case.

There are two main ways to build:

  1. App designer: flexible, convenient, simple, modern method;
  2. Based on theuifigureThe programming method: flexible, convenient reconstruction, suitable for the construction of complex, large graphical user interface, primitive social methods.

Here we create it programmatically.

Second, prepare

1. The API interface

Text Recognition involves Optical Character Recognition (OCR) technology, and if we build the underlying wheel ourselves, it will be very tiring to have a high Recognition rate.

Fortunately, there are mature tools on the market, such as Baidu Intelligent cloud, Ali Cloud, IFLYtek and so on, all provide API interfaces, just borrow it and use it. Here we mainly take the text recognition API provided by Baidu Intelligent cloud as an example.

After applying for the free text recognition function, you can view the API Key and Secret Key on the console. These two parameters can obtain the access_token, which is the required parameter to invoke the API interface (as shown in the red box below).

By looking at the text recognition technical documentation, we can get the general text recognition (standard version) request interface, as follows:

HTTP method: POST

The requested URL: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic

URL Parameter: Attribute Name: access_token, value: Access_token obtained by API Key and Secret Key. For details, see “Access Token”.

Header: Attribute name: Content-Type, value: Application /x-www-form-urlencoded

Request parameters: Attribute name: image, value: image data, base64 encoding and urlencode, the size of base64 encoding and urlenCode must not exceed 4M, the shortest edge must be at least 15px, the longest edge must be at least 4096px, support JPG, JPEG, PNG, and BMP formats

Returns parameters: Property name: words_result, value: recognition result array

Details of the HTTP request process will follow.

2. Base64 encoding of images

Base64 is one of the most common encoding methods for transmitting 8-bit bytecodes on the network. It is a 64-character set including lowercase letters A-Z, uppercase letters A-z, digits 0-9, symbols +, and /. Equal = is used as a suffix. Any symbol can be converted to a character in this character set, a process called Base64 encoding. Base64 encoding is unreadable and requires decoding to be read.

Many programming languages provide ready-made Base64 encoding library functions, Matlab is no exception, you might as well help matlab.net.base64encode to view the details.

The following three implementation methods in Matlab are provided:

  • Java classes – org.apache.com mons. Codec.. Binary Base64 and matlab.net.base64encode
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
Copy the code
  • Using the Pythonbase64The module

Matlab can be directly used in Python, that Python module base64 can be directly used, the source code is as follows:

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
Copy the code

We can compare the encoding speed by base64 encoding the same image (500 x 500) shown below:

Results: ‘/ 9 j / 4 aaqskz… AAAAAAD/9k=’

  • Java classes – org.apache.com mons. Codec.. Binary Base64: timer_clock: 0.000783 seconds
  • Matlab.net.base64encode: timer_clock: 0.017589 seconds
  • Python base64Module :timer_clock: 3009 seconds

It can be found that using Java classes and Python base64 module method, the speed is similar, and using matlab.net.base64encode speed is more than 20 times slower, but encoding a 500 x 500 image takes about 0.02 seconds, its speed is very fast.

Comprehensive, we recommend using org.apache.com mons. Codec.. Binary Base64 encoding algorithm based on Base64 groups.

3. Screen capture

When identifying text in scanned PDF documents and video tutorials, we need to take a screenshot of the area where the text is identified and save it as an image for subsequent recognition operations. To achieve the above process, first need to take a screenshot of the screen, Matlab by using the Java class java.awt.Robot to achieve the screenshot source code is as follows:

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
Copy the code

4. Call Baidu API to identify text

As mentioned in Section 1 above, access_token is a required parameter to invoke the API interface. According to the technical documents, API Key and Secret Key can be obtained by HTTP request. The core code is as follows:

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;
Copy the code

With access_token we can call the text recognition API for text recognition, here to share the text recognition source code:

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: Poor prince
%

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
Copy the code

Simple test under the function, input as shown in the pictures below, our images (screenshots address: ww2. Mathworks. Cn/products/ma…

>> result =

  1x7The cell array column14

    {'App design tools help you... '}    {'Development background. You only... '}    {'Face (GUI) design layout,... '}    {'programming. '} column57

    {'To share an App, you can make... '}    {'MATLAB Compile... '}    {'Desktop App or Web App'}
>> result{1}

ans =

    'App Design Tools help you create professional apps without requiring software '
Copy the code

There are altogether 7 cells in the recognition result, representing 7 lines of text in the image. That is, one cell corresponds to one line of text identified, such as result{1}.

3. Tool building

To create an APP programmatically based on Uifigure, we recommend object-oriented (OOP) programming. For simplicity, we encapsulate a class to implement the desired functionality. Of course, the more standard approach is to use MVC and other design patterns to separate the interface and logic, can achieve open to expansion, to modify closed software design principles.

1. Functional requirements

Our functional requirements are very simple, mainly including the following two functions:

  • Recognize text in an existing image
  • Recognize text in scanned PDF documents, video tutorials, etc

To achieve the first function, we only need to load the image, and then call the recognition function for recognition, the recognition results will be displayed in the text area; To realize the second function, first of all, screen shots are required to select the area where the text is to be recognized and store it as an image. The subsequent processing is the same as that of the first function.

According to the above description, the controls we need are: load image button, screenshot button, image display, recognition result display text field. In addition, a clean button is required to clear the displayed images and identify the results; You also need a setup button to configure the API Key and Secret Key.

For the sake of description, let’s first show the final design result, as shown below:

Text recognition tool main interface Set the interface

In the Settings screen, you need two labels and two text boxes, and two buttons on the outside. Now that we know what controls we need, let’s create them together.

2. Implementation details

This class needs to inherit matlab.apps.AppBase, and its properties are all the controls in the interface. This class should look like this:

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
Copy the code

Here are some important attributes

Public attributes:

  • UIFigIt must bematlab.ui.FigureClass property, passeduifigureConstruct, which is the main window of the entire tool
  • ContainerForMainIt must bematlab.ui.container.GridLayoutClass property, passeduigridlayoutStructure, which is the layout container for the main window
  • ThisTBIt must bematlab.ui.container.ToolbarClass property, passeduitoolbarConstruct, which is the container for the toolbar to be placed inSnippingToolBtn,ImgLoadToolBtn,SetupToolBtn,CleanToolBtnThese four tool buttons
  • ImgShowIt must bematlab.ui.control.ImageClass property, passeduiimageStructure to display images after loading or taking a screenshot
  • WordsShowTAIt must bematlab.ui.control.TextAreaClass property, passeduitextareaStructure to display text recognition results
  • ContainerForSetup Sets the grid container in the interface
  • APIKeyTextandSecrectKeyTextMainly used for inputAPIKeyandSecrectKey
  • ResetBtnandSaveBtnTwo buttons are used to reset and save, respectivelyAPIKeyandSecrectKey

Dependent, hidden properties:

  • APIKeyValUsed to receiveAPIKeyTextEntered in theAPIKeyThe value of the
  • SecrectKeyValUsed to receiveSecrectKeyTextEntered in theSecrectKeyThe value of the

Protected attributes:

  • HasSetupIndicates whether it is configuredAPIKeyandSecrectKeyBy default,false

At this point, we have all the properties set up, and then we write the constructors, destructors, and class methods.

Adding the code for the constructor, destructor, and get methods for the dependent attributes APIKeyVal and SecrectKeyVal looks like this:

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
Copy the code

The Destructor method (Destructor) is written fixed, as is the registerApp(app, app.uifig) constructor, and the buildApp() method is used to create interfaces and register controls.

We made the subsequent methods private, and the entire ReadWords class after adding the buildApp() method looks like this:

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.5 x'};
            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
Copy the code

Note that the toolbar buttons and window ICONS come from: www.easyicon.cc/. Some common icon materials are…

Link: pan.baidu.com/s/11kIvt4SX… Extraction code: 5I3K

In addition, the app. RunStartupFcn (@ startupFcn); Statement is called the parent class matlab.apps.AppBase method, we put each control registration task in the startupFcn method to complete. We’ll comment out this statement and run readwords. m to display the interface we just built in the buildApp method.

StartupFcn = startupFcn = startupFcn = startupFcn = startupFcn = startupFcn

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.5 x'};
            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
Copy the code

As a result, we registered a total of six callback methods for six buttons, all of which need to be implemented otherwise the button will not respond when fired. For simplicity, we use callbackSaveBtn as an example to illustrate the callbackSaveBtn callback that implements SaveBtn in the setup interface.

If the SnippingToolBtn or ImgLoadToolBtn is triggered before the APIKey or SecrectKey is set, it will prompt you to set it first:

CallbackSaveBtn method implementation logic: APIKey and SecrectKey are set (default is false). If no APIKey or SecrectKey is set, enter the APIKey and SecrectKey values. Then click the save button, the background will store the value (.mat file), update HasSetup to true, we do not need to enter the value again, to change the value, click the reset button to reconfigure; If set (HasSetup property is true), save.

The specific code is as follows:

% -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
% % 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
Copy the code

Once you’ve implemented the save button function, you’ll get something like the GIF below.

Other callback function source code:

% 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)
            endimwrite(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
Copy the code

Four, use demonstration

Now let’s test the image recognition tool we built. For example, some pockmarked student is a graduate student. When reading the scanned PDF document, he wants to copy a paragraph of the sentence for taking notes or making PPT.

In a flash, some pockmarked students got the result they wanted, revealing a long-lost smile of happiness!

Five, the conclusion

At this point, we have completed a relatively complete word recognition tool! I hope you enjoy it and get something useful from it.

This article complete code, please reply in GH “word recognition tool” to get.

【 Previous recommendation 】

  • Vectorization Method for Matrix 2-Normalizing (QQ.com)
  • TexStudio Theme Configuration (QQ.com)
  • Giving benefits (QQ.com)
  • How to use Matlab to download STATION B HD video with one click (part 2)
  • Decorators in Python (qq.com)
  • MATLAB Style Guide 2.0 (QQ.com)
  • (qq.com)
  • Guess what today’s dry goods are? (qq.com)
  • Share to climb Matlab Chinese forum basic discussion source code (qq.com)
  • How to use Matlab to download HIGH-DEFINITION video of STATION B (PART 1)
  • Crawl the literature on a scholar’s homepage (QQ.com)