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

    % ImageTransformer Object for applying an arbitrary transformation to an image.
%
% transformer = ImageTransformer returns an image transformer object.
%
% ImageTransformer methods:
% -------------------------
% transformImage - Apply a transformation to an image.
% needToUpdate   - Returns true if the map needs to be updated.
% update         - Recompute the map.

% Copyright 2012-2013 MathWorks, Inc.

%#codegen

classdef ImageTransformer < handle
    
    properties (GetAccess=public, SetAccess=private)
        % the map
        Xmap = 0;
        Ymap = 0;
        
        XmapSingle = single(0);
        YmapSingle = single(0);
        
        NewOrigin = [0 0];
    end
    
    properties(Access=private)
        % needed for lazy evaluation
        SizeOfImage = [0 0];
        ClassOfImage = 'a';        
        
        % Output bounds
        OutputView = 'same';
        XBounds = [-1 -1];
        YBounds = [-1 -1];    
        
        IsIppOn = 1;
    end
    
    methods(Access=public)        
        
        function this = ImageTransformer()
            % make variables var-size for codegen.
            this.SizeOfImage = [0 0];
            this.SizeOfImage = [0 0 0];
            this.ClassOfImage = 'a';
            this.ClassOfImage = 'uint8';
            this.OutputView = 'a';
            this.OutputView = 'same';
            
            this.Xmap = zeros(2);
            this.Ymap = zeros(2);
            
            this.XmapSingle = zeros(2, 'single');
            this.YmapSingle = zeros(2, 'single');            
        end
        
        % needToUpdate Returns true if the image has changed and the map 
        % needs to be recomputed.
        function tf = needToUpdate(this, I, outputView)  
           sameSize = isequal(this.SizeOfImage, size(I));
           sameClass = strcmp(class(I), this.ClassOfImage);
           sameOutputView = isequal(this.OutputView, outputView);
           sameIpp = ~isempty(coder.target) || (this.IsIppOn == ippl());
           
           tf = ~(sameSize && sameClass && sameOutputView && sameIpp);
        end
                
        % update Recompute the map if the image has changed
        function this = update(this, I, intrinsicMatrix, radialDist,...
                tangentialDist, outputView, ...
                xBounds, yBounds, H)

            if isempty(coder.target)
                this.IsIppOn = ippl();
            end
            
            this.SizeOfImage  = size(I);
            this.ClassOfImage = class(I);
            this.OutputView = outputView;
            this.XBounds = xBounds;
            this.YBounds = yBounds;
            this.NewOrigin = [this.XBounds(1), this.YBounds(1)] - 1;
            
            if nargin > 8
                computeMap(this, intrinsicMatrix, radialDist, tangentialDist, H);
            else
                computeMap(this, intrinsicMatrix, radialDist, tangentialDist);
            end            
        end
        
        % transformImage Apply the transformation to an image
        % [J, newOrigin] = transformImage(this, I, interp, inversFcn, fillValues) 
        % transforms image I. 
        function [J, newOrigin] = transformImage(this, I, interp, fillValues)            
            if isempty(coder.target)
                if isa(I, 'double')
                    J = vision.internal.calibration.interp2d(I, this.Xmap, this.Ymap, ...
                        interp, fillValues);
                else
                    J = vision.internal.calibration.interp2d(I, this.XmapSingle, ...
                        this.YmapSingle, interp, fillValues);
                end
            else
                if isa(I, 'double')
                    J = images.internal.coder.interp2d(I, this.Xmap, this.Ymap, ...
                        interp, fillValues, false);
                else
                    J = images.internal.coder.interp2d(I, this.XmapSingle, ...
                        this.YmapSingle, interp, fillValues, false);
                end
            end
            
            newOrigin = [this.XBounds(1), this.YBounds(1)] - 1;
        end
    end
    
    methods(Access=private)                                      
        %------------------------------------------------------------------
        % Compute the map for image transformation.
        %------------------------------------------------------------------
        function computeMap(this, intrinsicMatrix, radialDist, tangentialDist, H)
            [X, Y] = meshgrid(this.XBounds(1):this.XBounds(2),...
                this.YBounds(1):this.YBounds(2));
            ptsIn = [X(:) Y(:)]; % remapmex requires singles
            
            if nargin > 4
                ptsIn = H.transformPointsInverse(ptsIn);
            end
            
            if isempty(coder.target)
                ptsOut = visionDistortPoints(ptsIn, ...
                    intrinsicMatrix', radialDist, tangentialDist);
            else
                ptsOut = vision.internal.calibration.distortPoints(ptsIn, ...
                    intrinsicMatrix, radialDist, tangentialDist);                
            end
            
            clear ptsIn; % be careful with memory
            
            m = this.YBounds(2) - this.YBounds(1) + 1;
            n = this.XBounds(2) - this.XBounds(1) + 1;
            
            if isempty(coder.target)
                if ippl()
                    pad = -1;
                else
                    pad = 0;
                end
            else
                pad = 0;
            end
            
            if strcmp(this.ClassOfImage, 'double')
                this.Xmap = reshape(ptsOut(:,1),[m n]) + pad;
                this.Ymap = reshape(ptsOut(:,2),[m n]) + pad;
            else
                this.XmapSingle = cast(reshape(ptsOut(:,1),[m n]), 'single') + ...
                    single(pad);
                this.YmapSingle = cast(reshape(ptsOut(:,2),[m n]), 'single') + ...
                    single(pad);
            end                        
        end
    end
end