matlab之disparity函数实现

    xiaoxiao2021-04-17  35

    function disparityMap = disparity(I1,I2,varargin) % DISPARITY Compute disparity map. %   disparityMap = DISPARITY(I1,I2) returns the disparity map for a pair of  %   stereo images, I1 and I2. I1 and I2 must have the same size and must be %   rectified(校正) such that the corresponding points are located on the same %   rows. This rectification can be performed using the rectifyStereoImages %   function. The returned disparity map has the same size as I1 and %   I2. % %   The disparity function implements two different algorithms: Block %   Matching and Semi-Global Block Matching. These algorithms consist of %   the following steps: % %    (1) Compute a measure of contrast of the image by using the Sobel filter. % %    (2) Compute the disparity for each pixel in I1. % %    (3) Mark the elements of d for which disparity was not computed %         reliably with -REALMAX('single'). % %   disparityMap = DISPARITY(...,Name,Value) specifies additional name-value pairs %   described below: % %   'Method'  'BlockMatching' for basic Block Matching or 'SemiGlobal' for %             Semi-Global Block Matching. In the Block Matching method the %             function computes disparity by comparing the sum of absolute %             differences (SAD) of each block of pixels in the image. In %             the Semi-Global Block Matching method the function %             additionally forces similar disparity on neighboring blocks. %             This additional constraint results in a more complete %             disparity estimate than in Block Matching. % %             Default: 'SemiGlobal' % %   'DisparityRange'       A two-element vector, [MinDisparity %                          MaxDisparity], defining the range of disparity. %                          MinDisparity and MaxDisparity must be integers %                          and their difference must be divisible by 16. % %                          Default: [0 64] % %   'BlockSize'            An odd integer, 5 <= BlockSize <= 255. The width %                          of each square block of pixels used for %                          comparison between I1 and I2. % %                          Default: 15 % %   'ContrastThreshold'    A scalar value, 0 < ContrastThreshold <= 1, %                          defining the acceptable range of contrast %                          values. Increasing this parameter results in %                           fewer pixels being marked as unreliable. % %                          Default: 0.5 % %   'UniquenessThreshold'  A non-negative integer defining the minimum %                          value of uniqueness. If a pixel is less unique, %                          the disparity computed for it is less reliable. %                           Increasing this parameter will result in marking %                           more pixels unreliable. You can set this %                          parameter to 0 to disable it. % %                          Default: 15 % %   'DistanceThreshold'    A non-negative integer defining the maximum %                          distance for left-right checking. Increasing this %                           parameter results in fewer pixels being marked %                          as unreliable. You can also set this parameter %                          to an empty matrix [] to disable it. % %                          Default: [] (disabled) % %   'TextureThreshold'     A scalar value, 0 <= TextureThreshold <= 1, %                          defining the minimum texture. If a block of %                          pixels is less textured, the computed disparity %                          is less reliable. Increasing this parameter %                          results in more pixels being marked as %                           unreliable. Set this parameter to 0 to disable it. % %                          This parameter is used only with the %                          'BlockMatching' method. % %                          Default: 0.0002 % % Class Support % ------------- %   All inputs must be real, finite, and nonsparse. I1 and I2 must have the %   same class and must be uint8, uint16, int16, single, or double. % %   Example %   ------- %     % Load the images and convert them to grayscale. %     I1 = rgb2gray(imread('scene_left.png')); %     I2 = rgb2gray(imread('scene_right.png')); % %     figure; imshowpair(I1,I2,'ColorChannels','red-cyan'); %     title(' Red-cyan composite view of the stereo images'); % %     % Compute the disparity map. %     disparityMap = disparity(I1, I2, 'BlockSize', 15, ... %       'DisparityRange', [-6 10]); % %     % For the purpose of visualizing the disparity, replace %     % the -realmax('single') marker with the minimum disparity value. %     marker_idx = (disparityMap == -realmax('single')); %     disparityMap(marker_idx) = min(disparityMap(~marker_idx)); % %     % Show the disparity map. Brighter pixels indicate意味着 objects which are %     % closer to the camera. %     figure; imshow(mat2gray(disparityMap)); %     colormap jet; colorbar; % % See also rectifyStereoImages, reconstructScene, % estimateCameraParameters, estimateUncalibratedRectification % References: % ----------- % [1] K. Konolige, "Small Vision Systems: Hardware and Implementation," %     Proceedings of the 8th International Symposium in Robotic Research, %     pages 203-212, 1997. % % [2] G. Bradski and A. Kaehler, "Learning OpenCV : Computer Vision with %     the OpenCV Library," O'Reilly, Sebastopol, CA, 2008. % % [3] Hirschmuller, Heiko. "Accurate and Efficient Stereo Processing by %     Semi-Global Matching and Mutual Information." International Conference %     on Computer Vision and Pattern Recognition, 2005. % % Copyright 2011-2012 The MathWorks, Inc. %#codegen %#ok<*EMCA> %-------------------------------------------------------------------------- % Parse the inputs %-------------------------------------------------------------------------- r = parseInputs(I1, I2, varargin{:}); % Two structures with overlapping fields are required for code generation % BlockMatching method parameters % ------------------------------- optBM.preFilterCap        = int32(floor(63 * r.ContrastThreshold)); optBM.preFilterCap        = int32(floor(63 * r.ContrastThreshold)); optBM.SADWindowSize       = int32(r.BlockSize); optBM.minDisparity        = int32(r.DisparityRange(1)); optBM.numberOfDisparities = int32(r.DisparityRange(2) - r.DisparityRange(1)); optBM.uniquenessRatio     = int32(r.UniquenessThreshold); % parameters unique to block matching optBM.roi1                = int32(r.ROI1) - int32([1 1 0 0]); optBM.roi2                = int32(r.ROI2) - int32([1 1 0 0]); optBM.textureThreshold    = int32(255 * r.TextureThreshold * r.BlockSize^2); % OpenCV parameters that are not exposed as optional parameters optBM.preFilterType       = int32(1);    % Fixed to CV_STEREO_BM_XSOBEL optBM.preFilterSize       = int32(15); optBM.trySmallerWindows   = int32(0); % SemiGlobal method parameters % ---------------------------- optSGBM.preFilterCap        = int32(floor(63 * r.ContrastThreshold)); optSGBM.preFilterCap        = int32(floor(63 * r.ContrastThreshold)); optSGBM.SADWindowSize       = int32(r.BlockSize); optSGBM.minDisparity        = int32(r.DisparityRange(1)); optSGBM.numberOfDisparities = int32(r.DisparityRange(2) - r.DisparityRange(1)); optSGBM.uniquenessRatio     = int32(r.UniquenessThreshold); % OpenCV parameters that are not exposed as optional parameters optSGBM.P1                  = int32(8 * r.BlockSize^2); optSGBM.P2                  = int32(32 * r.BlockSize^2); optSGBM.fullDP              = 0; % false if isempty(r.DistanceThreshold)     optBM.disp12MaxDiff       = int32(-1);     optSGBM.disp12MaxDiff     = int32(-1); else     % in codegen, r.DistanceThreshold is never empty     optBM.disp12MaxDiff       = int32(r.DistanceThreshold);     optSGBM.disp12MaxDiff     = int32(r.DistanceThreshold); end %-------------------------------------------------------------------------- % Other OpenCV parameters which are not exposed in the main interface %-------------------------------------------------------------------------- optBM.speckleWindowSize   = int32(0); optBM.speckleRange        = int32(0); optSGBM.speckleWindowSize   = int32(0); optSGBM.speckleRange        = int32(0); %-------------------------------------------------------------------------- % Compute disparity %-------------------------------------------------------------------------- I1_u8 = im2uint8(I1); I2_u8 = im2uint8(I2); if isSimMode()     if strcmpi(r.Method,'SemiGlobal')         disparityMap = ocvDisparitySGBM(I1_u8, I2_u8, optSGBM);     else         disparityMap = ocvDisparityBM(I1_u8, I2_u8, optBM);     end else     if strcmpi(r.Method,'SemiGlobal')         disparityMap = vision.internal.buildable.disparitySGBMBuildable.disparitySGBM_compute(...             I1_u8, I2_u8, optSGBM);     else         disparityMap = vision.internal.buildable.disparityBMBuildable.disparityBM_compute(...             I1_u8, I2_u8, optBM);     end end %========================================================================== % Parse and check inputs %========================================================================== function r = parseInputs(I1, I2, varargin) vision.internal.inputValidation.validateImagePair(I1, I2, 'I1', 'I2', 'grayscale'); imageSize = size(I1); r = parseOptionalInputs(imageSize, varargin{:}); %-------------------------------------------------------------------------- % Check if ROI1 and ROI2 have the same size %-------------------------------------------------------------------------- errIf(any(r.ROI1(3:4) ~= r.ROI2(3:4)), 'vision:disparity:ROISizeMismatch'); errIf(~isa(r.ROI1, class(r.ROI2)), 'vision:disparity:ROIClassMismatch'); %-------------------------------------------------------------------------- % Check if BlockSize is smaller than both image size and the ROI size. %-------------------------------------------------------------------------- if all(r.ROI1(3:4) > 0)     checkBlockSize(r.BlockSize, r.ROI1([4,3])); end checkBlockSize(r.BlockSize, imageSize); %========================================================================== function r = parseOptionalInputs(imageSize, varargin) if isSimMode()     % inline the following function     r = vision.internal.disparityParser(imageSize, getDefaultParameters(),...         varargin{:}); else     r = parseOptionalInputs_cg(imageSize, varargin{:}); end %========================================================================== function r = parseOptionalInputs_cg(imageSize, varargin) % Optional value: ROI1, ROI2 % Optional Name-Value pair: 6 pairs (see help section) defaults = getDefaultParameters(); defaultsNoVal = getDefaultParametersNoVal(); properties    = getEmlParserProperties(); if nargin==1 % only imageSize     r = defaults;     return; end firstArg  = varargin{1}; numargs = length(varargin); if isnumeric(firstArg)          errIf((numargs<2) || (~isnumeric(varargin{2})), ...         'vision:disparity:ROIClassMismatch');     pvPairStartIdx = 3; else     ROI1 = defaults.ROI1;     ROI2 = defaults.ROI2;     pvPairStartIdx = 1; end %varargin{pvPairStartIdx:end} = varargin{pvPairStartIdx:end}; optarg = eml_parse_parameter_inputs(defaultsNoVal, properties, varargin{pvPairStartIdx:end}); Method = eml_get_parameter_value(optarg.Method, ...     defaults.Method, varargin{pvPairStartIdx:end}); ContrastThreshold = (eml_get_parameter_value( ...     optarg.ContrastThreshold, defaults.ContrastThreshold, varargin{pvPairStartIdx:end})); BlockSize = (eml_get_parameter_value( ...     optarg.BlockSize, defaults.BlockSize, varargin{pvPairStartIdx:end})); DisparityRange = (eml_get_parameter_value( ...     optarg.DisparityRange, defaults.DisparityRange, varargin{pvPairStartIdx:end})); TextureThreshold = (eml_get_parameter_value( ...     optarg.TextureThreshold, defaults.TextureThreshold, varargin{pvPairStartIdx:end})); UniquenessThreshold = (eml_get_parameter_value( ...     optarg.UniquenessThreshold, defaults.UniquenessThreshold, varargin{pvPairStartIdx:end})); DistanceThreshold = (eml_get_parameter_value( ...     optarg.DistanceThreshold, defaults.DistanceThreshold, varargin{pvPairStartIdx:end})); checkMethod(Method); isROIUsed = pvPairStartIdx == 3; if isROIUsed     errIf(strcmpi(Method,'SemiGlobal'),...     'vision:disparity:ROINotAvailableForSGBM');     checkROI('ROI1', firstArg, imageSize, 1);         secondArg = varargin{2};     checkROI('ROI1', secondArg, imageSize, 2);     ROI1 = firstArg;     ROI2 = secondArg; end checkContrastThreshold(ContrastThreshold); checkBlockSize(BlockSize, imageSize); checkDisparityRange(DisparityRange, imageSize); checkTextureThreshold(TextureThreshold); checkUniquenessThreshold(UniquenessThreshold); skipCheck = isscalar(DistanceThreshold) && ...     (DistanceThreshold == defaults.DistanceThreshold); if ~skipCheck     checkDistanceThreshold(DistanceThreshold, imageSize); end r.Method = Method; r.ContrastThreshold = ContrastThreshold; r.BlockSize = BlockSize; r.DisparityRange = DisparityRange; r.TextureThreshold = TextureThreshold; r.UniquenessThreshold = UniquenessThreshold; r.DistanceThreshold = DistanceThreshold; r.ROI1 = ROI1; r.ROI2 = ROI2; %========================================================================== function defaults = getDefaultParameters() defaults = struct(...     'Method', 'SemiGlobal',...     'ROI1', int32([1 1 0 0]), ...     'ROI2', int32([1 1 0 0]), ...     'ContrastThreshold', 0.5, ...     'BlockSize',   15, ...     'DisparityRange',   [0 64], ...     'TextureThreshold',   0.0002, ...     'UniquenessThreshold',   15, ...     'DistanceThreshold',  -107); % unusual value %========================================================================== function defaultsNoVal = getDefaultParametersNoVal() defaultsNoVal = struct(...     'Method',uint32(0),...     'ROI1', uint32(0), ...     'ROI2', uint32(0), ...     'ContrastThreshold', uint32(0), ...     'BlockSize',   uint32(0), ...     'DisparityRange',   uint32(0), ...     'TextureThreshold',   uint32(0), ...     'UniquenessThreshold',   uint32(0), ...     'DistanceThreshold',  uint32(0)); %========================================================================== function properties = getEmlParserProperties() properties = struct( ...     'CaseSensitivity', false, ...     'StructExpand',    true, ...     'PartialMatching', false); %========================================================================== function r = checkMethod(value) list = {'BlockMatching', 'SemiGlobal'}; validateattributes(value, {'char'}, {'nonempty'}, 'disparity', ...     'Method'); matchedValue = validatestring(value, list,  mfilename, 'Method'); coder.internal.errorIf(~strcmpi(value, matchedValue), ...     'vision:validateString:unrecognizedStringChoice', value); r = 1; %========================================================================== function r = checkROI(name, value, imageSize, position) validateattributes(value, {'numeric'}, ...     {'real', 'nonsparse', 'integer', 'positive', 'finite', 'size', [1, 4]},...     mfilename, name, position); errIf(value(1)+value(3) > imageSize(2)+1 || value(2)+value(4) > imageSize(1)+1, ...     'vision:disparity:invalidROIValue'); r = 1; %========================================================================== function r = checkContrastThreshold(value) validateattributes(value, {'numeric'}, ...     {'real', 'scalar', '>', 0, '<=', 1},...     mfilename, 'ContrastThreshold'); r = 1; %========================================================================== function r = checkBlockSize(value, imageSize) maxBlockSize = min([imageSize, 255]); validateattributes(value, {'numeric'}, ...     {'real', 'scalar', 'integer', 'odd', '>=', 5, '<=', maxBlockSize},...     mfilename, 'BlockSize'); r = 1; %========================================================================== function r = checkDisparityRange(value,imageSize) maxValue = min(imageSize); validateattributes(value, {'numeric'}, ...     {'real', 'nonsparse', 'integer', 'finite', 'size', [1,2], ...     '>', -maxValue, '<', maxValue},...     mfilename, 'DisparityRange'); errIf(value(2) <= value(1) || mod(value(2) - value(1), 16) ~= 0, ...     'vision:disparity:invalidDisparityRange'); r = 1; %========================================================================== function r = checkTextureThreshold(value) validateattributes(value, {'numeric'}, ...     {'real', 'scalar', 'finite', 'nonnegative', '<', 1},...     mfilename, 'TextureThreshold'); r = 1; %========================================================================== function r = checkUniquenessThreshold(value) validateattributes(value, {'numeric'}, ...     {'real', 'scalar', 'integer', 'finite', 'nonnegative'},...     mfilename, 'UniquenessThreshold'); r = 1; %========================================================================== function r = checkDistanceThreshold(value, imageSize) maxValue = min(imageSize); if ~isempty(value)     validateattributes(value, {'numeric'}, ...         {'real', 'scalar', 'integer', 'finite', 'nonnegative','<',maxValue},...         mfilename, 'DistanceThreshold'); end r = 1; %========================================================================== function flag = isSimMode() flag = isempty(coder.target); %========================================================================== function errIf(condition, msgID) coder.internal.errorIf(condition, msgID);
    转载请注明原文地址: https://ju.6miu.com/read-673389.html

    最新回复(0)