gusucode.com > vision工具箱matlab源码程序 > vision/+vision/+internal/+rcnn/ImageRegionDispatcher.m

    classdef ImageRegionDispatcher < nnet.internal.cnn.DataDispatcher
    %   ImageRegionDispatcher class to dispatch image regions cropped and
    %   resized from a single image. This is used to form input batches
    %   for the CNN. The batches are made up of resized image regions.
   
    %   Copyright 2015 The MathWorks, Inc.
    
    %----------------------------------------------------------------------
    properties
      % MiniBatchSize (int)   Number of images in a mini batch
        MiniBatchSize
        
        % EndOfEpoch    Strategy for how to cope with the last mini-batch
        % when the number of observations is not divisible by the number of
        % mini batches.
        %
        % Allowed values: 'truncateLast'
        EndOfEpoch
        
        Precision
    end
    
    %----------------------------------------------------------------------
    properties (SetAccess = private)

        % ImageSize  (1x3 int) Size of each image to be dispatched
        ImageSize
        
        % Image
        Image
        
        Boxes
        
        ClassNames

    end
    
    %----------------------------------------------------------------------
    properties (SetAccess = private, Dependent)
        % NumObservations (int) Number of observations in the data set
        NumObservations 
        
        % IsDone (logical)     True if there is no more data to dispatch
        IsDone              
    end
    
    %----------------------------------------------------------------------
    properties (Access = private)
                
        NumRegions
        NumMiniBatches
        
        DispatchedMiniBatches
        
        % CurrentIndex  (int)   Current index of image to be dispatched
        CurrentIndex
        CurrentImage
        
        % ExampleResponse   An example of the kind of response to
        % preallocate the response array
        ExampleResponse                
               
        NumObservationsDispatched
        
        % Object to crop and resize images.
        RegionResizer
    end
    
    methods
              
        %------------------------------------------------------------------
        function this = ImageRegionDispatcher(I, bboxes, miniBatchSize, ...
                endOfEpoch, precision, imageSize, resizer)
            % ImageDatastoreDispatcher   Constructor for array data dispatcher
            %
            % imageDatastore    - An ImageDatastore containing the images
            % miniBatchSize     - Size of a mini batch express in number of
            %                   images
            % endOfEpoch        - Strategy to choose how to cope with a
            %                   number of observation that is not divisible
            %                   by the desired number of mini batches
            %                   Allowed values:
            %                   'truncateLast' to truncate the last mini
            %                   batch
            % precision         - What precision to use for the dispatched
            %                   data                                   
                   
            this.NumRegions = size(bboxes,1);
            this.Boxes = bboxes;
                                
            this.MiniBatchSize = miniBatchSize;           
            this.EndOfEpoch = endOfEpoch;
            this.Precision = precision;                       
           
            % Set the expected image size
            this.ImageSize = imageSize;              
            
            % Convert image to RGB or grayscale if required.
            isNetImageRGB = numel(this.ImageSize) == 3 && this.ImageSize(end) == 3;
            isImageRGB    = ~ismatrix(I);
            
            if isImageRGB && ~isNetImageRGB
                I = rgb2gray(I);
                
            elseif ~isImageRGB && isNetImageRGB
                I = repmat(I,1,1,3);
            end
            
            % Cast image to single as required by region resizer. This
            % saves multiple casts while calling the resizer.
            this.Image = single(I);
            
            this.RegionResizer = resizer;
        end                           
        
        %------------------------------------------------------------------
        function n = get.NumObservations( this )
            n = this.NumRegions;
        end
        
        %------------------------------------------------------------------
        function tf = get.IsDone(this)
            tf = this.NumRegions - this.NumObservationsDispatched == 0 ;          
        end
        
        %------------------------------------------------------------------
        function [miniBatchData, miniBatchResponse, miniBatchIndices] = next(this)
            % next   Get the data and response for the next mini batch and
            % correspondent indices
                                             
            currentMiniBatchSize = min(this.MiniBatchSize, this.NumRegions - this.NumObservationsDispatched);
              
            miniBatchData = this.Precision.cast( zeros([this.ImageSize currentMiniBatchSize], 'like', this.Image) );
            miniBatchIndices = zeros(currentMiniBatchSize,1);
            miniBatchResponse = [];

            
            i = 1;
            while i <= currentMiniBatchSize                                                            
                
                miniBatchData(:,:,:,i) = this.RegionResizer.cropAndResize(this.Image, this.Boxes(this.CurrentIndex,:));
                miniBatchIndices(i,1) = this.nextIndex();
                i = i+1;
            end
            
            miniBatchData = this.Precision.cast(miniBatchData);
            
        end
        
        %------------------------------------------------------------------
        function start(this)
            % start     Set the next the mini batch to be the first mini
            % batch in the epoch
            
            this.CurrentIndex = 1;
            this.CurrentImage = 1;
            this.NumObservationsDispatched = 0;
        end
        
        %------------------------------------------------------------------
        function shuffle(~)
            % shuffle   Shuffle the data            
           assert(false)
        end
    end
    
    %----------------------------------------------------------------------
    methods (Access = private)
        function i = nextIndex( this )
            % nextIndex     Advance current index and return it
            
            this.NumObservationsDispatched = this.NumObservationsDispatched + 1;
            i = this.NumObservationsDispatched; 
            
            this.CurrentIndex = this.CurrentIndex + 1;                                                    
            
        end              
    end
end