gusucode.com > vision工具箱matlab源码程序 > vision/+vision/+internal/+ocr/+tool/Session.m

    classdef Session < handle
    properties
        FileName
        IsChanged
        CanTrain  
        IsTrained 
        IsInitialized
        ImageSet
        OCRLanguage
        OCRCharacterSet
        OutputDirectory
        OutputLanguage
        AutoLabel
        Font
    end    
    
    methods
        function this = Session()
            this.ImageSet = vision.internal.ocr.tool.ImageSet();            
            this.reset();
        end
        
        function reset(this)                        
            this.FileName  = '';
            this.IsChanged = false;
            this.CanTrain  = false;
            this.IsTrained = false;
            this.IsInitialized = false;
            this.AutoLabel = true;
            this.OCRLanguage = 'English';
            this.OCRCharacterSet = '';
            this.OutputDirectory = '';
            this.OutputLanguage = 'myLanguage';
            this.ImageSet.reset();
        end
        
        %------------------------------------------------------------------
        function updateFont(this, val)
            this.Font = val;
            
            % update ImageSet font too
            this.ImageSet.Font = this.Font;
        end
        
        %------------------------------------------------------------------
        function ret = hasAnyItems(this)
            if this.ImageSet.CharView
                ret = this.ImageSet.hasAnyCharacters();
            else
                ret = this.ImageSet.hasAnyImages();
            end           
        end
        
        %------------------------------------------------------------------
        function ret = hasAnyUnknowns(this)
            chars = this.ImageSet.CharMap.keys;
            if any(strcmp(char(0), chars))
                ret = true;
            else
                ret = false;
            end
        end
        
        %------------------------------------------------------------------
        function ret = hasAllUnknowns(this)
            chars = this.ImageSet.CharMap.keys;
            if all(strcmp(char(0), chars))
                ret = true;
            else
                ret = false;
            end
        end
        
        %------------------------------------------------------------------
        function ret = hasAnyImages(this)
            
            ret = this.ImageSet.hasAnyImages();
           
        end
        
        %------------------------------------------------------------------
        function checkImagePaths(this, pathname, filename)
            this.ImageSet.checkImagePaths(pathname, filename);
        end
        
        %------------------------------------------------------------------
        function [imgSet, bboxData] = getTrainingData(this)
            imgStruct = this.ImageSet.ImageStruct;
            imgfiles = {imgStruct(:).imageFilename};

            imgSet = vision.internal.ocr.tool.CustomImageSet(imgfiles);      
            imgSet.TextDetectionParams = this.ImageSet.TextDetectionParams;
            
            % Description is used as font name.
            imgSet.Description = this.OutputLanguage;
            
            for i = 1:numel(imgStruct)
                
                validBoxes = this.ImageSet.getValidBoxes(i);
                
                validText  = this.ImageSet.getValidText(i);
                
                bboxData(i).bboxes = validBoxes;
                
                bboxData(i).chars  = validText;
                
                bboxData(i).page  = repelem(0,numel(bboxData(i).chars));           
                
                % Convert from spatial coordinates to pixel coordinates.
                % In the app using spatial coordinates is simplier for
                % visualizing box patches. Pixel coordinates are only
                % required when it is time to train.
                bboxData(i).bboxes(:,1:2) = bboxData(i).bboxes(:,1:2) + 0.5;
                                         
            end
        end               
            
        %------------------------------------------------------------------
        function generateEvaluationFunction(this)
            codeGenerator = vision.internal.calibration.tool.MCodeGenerator;
            
            codeGenerator.addLine(sprintf(['%% Auto-generated by ', ...
                '%s app on %s'], 'ocrTrainer', date));
            codeGenerator.addLine(['%----------------------------------------', ...
                '---------------']);            
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% evaluateOCRTraining Evaluate OCR training');
            codeGenerator.addLine('% results = evaluateOCRTraining(I) runs OCR using the trained language model');
            codeGenerator.addLine('% and returns an image, ocrI, that has been annotated with the recognition');
            codeGenerator.addLine('% results.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% ocrI = evaluateOCRTraining(..., roi) optionally limit OCR to a');
            codeGenerator.addLine('% rectangular region of interest, roi, within I. Use this if I contains a');
            codeGenerator.addLine('% lot of non-text background, which can hinder OCR performance.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% [..., results] = evaluateOCRTraining(I) optionally returns the detailed');
            codeGenerator.addLine('% recogition results in an ocrText object.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% Notes');
            codeGenerator.addLine('% -----');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% 1) You may need to pre-process your test images to remove noise and');
            codeGenerator.addLine('%    improve text segmentation.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% 2) You may need to modify the OCR ''TextLayout'' parameter used below to');
            codeGenerator.addLine('%    something that is more suitable for your input images.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% 3) You may need to re-train your language using more training samples.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% 4) You may need to modify this function and pass a region of interest');
            codeGenerator.addLine('%    (ROI) to the OCR function. This is required if your image has a lot');
            codeGenerator.addLine('%    of non-text background. Alternatively, use IMCROP to manually crop the');
            codeGenerator.addLine('%    image before evaluating OCR.');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% Example 1 - Draw an ROI and evaluate OCR training');
            codeGenerator.addLine('% --------------------------------------------------- ');
            codeGenerator.addLine(sprintf('%%  I = imread(''%s'');', this.ImageSet.ImageStruct(1).imageFilename));
            codeGenerator.addLine('%  figure');
            codeGenerator.addLine('%  imshow(I)');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('%  % Draw a region of interest');
            codeGenerator.addLine('%  h = imrect');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('%  % Evaluate OCR within ROI');
            codeGenerator.addLine('%  roi = h.getPosition;');
            codeGenerator.addLine('%  ocrI = evaluateOCRTraining(I, roi);');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('%  % Show results');
            codeGenerator.addLine('%  figure');
            codeGenerator.addLine('%  imshow(ocrI)');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('%  Example 2 - Get all OCR results');
            codeGenerator.addLine('%  -------------------------------');
            codeGenerator.addLine(sprintf('%%  I = imread(''%s'');', this.ImageSet.ImageStruct(1).imageFilename));
            codeGenerator.addLine('%  [ocrI, results] = evaluateOCRTraining(I);');
            codeGenerator.addLine('%  results.Text');
            codeGenerator.addLine('%  results.CharacterConfidences');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('%  Example 3 - Batch OCR evaluation ');
            codeGenerator.addLine('%  --------------------------------');
            codeGenerator.addLine('%  % Save this generated function and use it in the imageBatchProcessor');
            codeGenerator.addLine('%  imageBatchProcessor');
            codeGenerator.addLine('% ');
            codeGenerator.addLine('% See also ocr, ocrTrainer, ocrText');
            codeGenerator.addLine('function [ocrI, results] = evaluateOCRTraining(I, roi)');
                        
            lang = fullfile(this.OutputDirectory,...,
                this.OutputLanguage , 'tessdata', ...
                [this.OutputLanguage '.traineddata']);
            
            codeGenerator.addComment('Location of trained OCR language data'); 
            codeGenerator.addLine(sprintf('trainedLanguage = ''%s'';', lang));
            codeGenerator.addLine('    ');
            codeGenerator.addLine('% Run OCR using trained language. You may need to modify OCR parameters or');
            codeGenerator.addLine('% pre-process your test images for optimal results. Also, consider');
            codeGenerator.addLine('% specifying an ROI input to OCR in case your images have a lot of non-text');
            codeGenerator.addLine('% background.');
            codeGenerator.addLine('layout = ''Block'';');
            codeGenerator.addLine('if nargin == 2');
            codeGenerator.addLine('    results = ocr(I, roi, ...');
            codeGenerator.addLine('       ''Language'', trainedLanguage, ...');
            codeGenerator.addLine('       ''TextLayout'', layout);  ');
            codeGenerator.addLine('else');
            codeGenerator.addLine('    results = ocr(I, ...');
            codeGenerator.addLine('       ''Language'', trainedLanguage, ...');
            codeGenerator.addLine('       ''TextLayout'', layout);  ');            
            codeGenerator.addLine('end');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('ocrI = insertOCRAnnotation(I, results);');       
            codeGenerator.addLine('    ');
            codeGenerator.addLine('%--------------------------------------------------------------------------');
            codeGenerator.addLine('% Annotate I with OCR results.');
            codeGenerator.addLine('%--------------------------------------------------------------------------');           
            codeGenerator.addLine('function J = insertOCRAnnotation(I, results)');
            codeGenerator.addLine('text = results.Text;');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('I = im2uint8(I);');
            codeGenerator.addLine('if isempty(deblank(text))');
            codeGenerator.addLine('    % Text not recognized.');
            codeGenerator.addLine('    text = ''Unable to recognize any text.'';');
            codeGenerator.addLine('    [M,N,~] = size(I);');
            codeGenerator.addLine('    J = insertText(I, [N/2 M/2], text, ...');
            codeGenerator.addLine(sprintf('        ''AnchorPoint'', ''Center'', ''FontSize'', 24, ''Font'', ''%s'');', this.Font));
            codeGenerator.addLine('    ');
            codeGenerator.addLine('else');
            codeGenerator.addLine('    location = results.CharacterBoundingBoxes;');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('    % Remove new lines from results.');
            codeGenerator.addLine('    newlines = text == char(10);');
            codeGenerator.addLine('    text(newlines) = [];');
            codeGenerator.addLine('    location(newlines, :) = [];');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('    % Remove spaces from results');
            codeGenerator.addLine('    spaces = isspace(text);');
            codeGenerator.addLine('    text(spaces) = [];');
            codeGenerator.addLine('    location(spaces, :) = [];');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('    % Convert text array into cell array of strings.');
            codeGenerator.addLine('    text = num2cell(text);');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('    % Pad the image to help annotate results close to the image border.');
            codeGenerator.addLine('    I = padarray(I, [50 50], uint8(255));');
            codeGenerator.addLine('    location(:,1:2) = location(:,1:2) + 50;');
            codeGenerator.addLine('    ');
            codeGenerator.addLine('    % Insert text annotations.');
            codeGenerator.addLine('    J  = insertObjectAnnotation(I, ''rectangle'', location, text);');
            codeGenerator.addLine('end');
               
            content = codeGenerator.CodeString;
            
            % Open template code in an untitled file in the editor           
            editorDoc = matlab.desktop.editor.newDocument(content);
                                 
            editorDoc.smartIndentContents;    
            editorDoc.goToLine(1);
        end
               
    end
    
    methods(Hidden)
        %------------------------------------------------------------------
        % Utility function to generated tesseract box files.
        %------------------------------------------------------------------
        function writeBoxFiles(this)
            
            [trainingImages, trainingData] = this.getTrainingData();
            
            fontnames = {trainingImages(:).Description};
            language  = this.OutputLanguage;
            for i = 1:numel(trainingImages) % array of imageSet, 1 per font
                
                for j = 1:trainingImages(i).Count
                    
                    I = read(trainingImages(i),j);
                    
                    baseFilename = sprintf('%s.%s.exp%d',language, fontnames{i},j);
                    
                    % write box file given training boxes.
                    fname = [baseFilename '.box'];
                    boxFile = fullfile(pwd, fname);
                    
                    vision.internal.ocr.writeBoxFile(boxFile, trainingData(j), size(I));
                    
                    [~, iname] = fileparts(trainingImages(i).ImageLocation{j});
                    fprintf('Created box file, %s, for image %s \n', fname, iname);
                end
            end
            
        end
    end
end