obtainBnd

PURPOSE ^

create boundary data structure from raw data

SYNOPSIS ^

function bnd = obtainBnd(dataMatrix, dataType, image,sizeFraction, threshold, restoreFlag, resampleFlag)

DESCRIPTION ^

 create boundary data structure from raw data

 Syntax: bnd = obtainBnd(dataMatrix)

 A structure is created that contains the measurement data in dataMatrix
   (one data point each column) including some basic measures. The 
   structure contains the fields cartX, cartY, polarAngle (radian), 
   polarDistance that represent the input data. Additionally, the
   following fields are returned:
     polarBinSize: range of angle (radian) that is covered by each
       distance in polarDistance
     centerPointOriginal: coordinate origin as for the input points
     centerPointMean: coordinate origin as centered to the mean
     polarBoundaryArea: shape area estimated from circle sections
     convexHullArea: area of convex hull
     vrepHull: convex hull in V-rep
     hrepHull: convex hull in H-rep
     meanWidthHull: mean width of the convex hull
     convexity: convexity ratio as [shape area]/[hull area]
     largestAngleGap: largest gap in polarAngle vector
     sphericity1: 1 - (maxPolar - minPolar)/meanPolar
     sphericity2: 1 - stdPolar / meanPolar
     sphericity3: pi*[diameter area eq. circle] / [circumfence of hull]
     brightFraction: fraction of bright pixels (only with provided image)

 obtainBnd(.., type) sets the input data type. For type='cart', cartesian
   coordinates are exprected. For type='polar', the input data is 
   interpreted as polar coordinates with the distance in the first row and
   the angle (radian) in the second row.

 obtainBnd(.., type, image, sizeFraction, threshold) Allows to provide the
   corresponding image data to evaluate a brightness fraction of some 
   area. The area is a circle with a radius of 0.5*sizeFraction*[minimum 
   polar distance] that is centered in the bounding box. Bright pixels are
   any pixels above the threshold. This measure is used to filter for air 
   bubbles.

 See also: fitShapeBnd, viewBoundary

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function bnd = obtainBnd(dataMatrix, dataType, image, ...
0002     sizeFraction, threshold, restoreFlag, resampleFlag)
0003 % create boundary data structure from raw data
0004 %
0005 % Syntax: bnd = obtainBnd(dataMatrix)
0006 %
0007 % A structure is created that contains the measurement data in dataMatrix
0008 %   (one data point each column) including some basic measures. The
0009 %   structure contains the fields cartX, cartY, polarAngle (radian),
0010 %   polarDistance that represent the input data. Additionally, the
0011 %   following fields are returned:
0012 %     polarBinSize: range of angle (radian) that is covered by each
0013 %       distance in polarDistance
0014 %     centerPointOriginal: coordinate origin as for the input points
0015 %     centerPointMean: coordinate origin as centered to the mean
0016 %     polarBoundaryArea: shape area estimated from circle sections
0017 %     convexHullArea: area of convex hull
0018 %     vrepHull: convex hull in V-rep
0019 %     hrepHull: convex hull in H-rep
0020 %     meanWidthHull: mean width of the convex hull
0021 %     convexity: convexity ratio as [shape area]/[hull area]
0022 %     largestAngleGap: largest gap in polarAngle vector
0023 %     sphericity1: 1 - (maxPolar - minPolar)/meanPolar
0024 %     sphericity2: 1 - stdPolar / meanPolar
0025 %     sphericity3: pi*[diameter area eq. circle] / [circumfence of hull]
0026 %     brightFraction: fraction of bright pixels (only with provided image)
0027 %
0028 % obtainBnd(.., type) sets the input data type. For type='cart', cartesian
0029 %   coordinates are exprected. For type='polar', the input data is
0030 %   interpreted as polar coordinates with the distance in the first row and
0031 %   the angle (radian) in the second row.
0032 %
0033 % obtainBnd(.., type, image, sizeFraction, threshold) Allows to provide the
0034 %   corresponding image data to evaluate a brightness fraction of some
0035 %   area. The area is a circle with a radius of 0.5*sizeFraction*[minimum
0036 %   polar distance] that is centered in the bounding box. Bright pixels are
0037 %   any pixels above the threshold. This measure is used to filter for air
0038 %   bubbles.
0039 %
0040 % See also: fitShapeBnd, viewBoundary
0041 
0042 % The elk-library: convex geometry applied to crystallization modeling.
0043 %   Copyright (C) 2014 Alexander Reinhold
0044 %
0045 % This program is free software: you can redistribute it and/or modify it
0046 %   under the terms of the GNU General Public License as published by the
0047 %   Free Software Foundation, either version 3 of the License, or (at your
0048 %   option) any later version.
0049 %
0050 % This program is distributed in the hope that it will be useful, but
0051 %   WITHOUT ANY WARRANTY; without even the implied warranty of
0052 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0053 %   General Public License for more details.
0054 %
0055 % You should have received a copy of the GNU General Public License along
0056 %   with this program.  If not, see <http://www.gnu.org/licenses/>
0057 
0058 if ~exist('dataType', 'var')
0059     dataType = 'cart';
0060 end
0061 
0062 %% input matrix check
0063 % dimensions of data matrix
0064 if size(dataMatrix, 1) == 2
0065     % everything OK
0066 elseif size(dataMatrix, 2) == 2
0067     dataMatrix = dataMatrix';
0068 else
0069     error('elk:boundaryCurve:wrongInput', ...
0070           'input data matrix must contains two rows, one data point in each column');
0071 end
0072 
0073 %% restore points
0074 if exist('restoreFlag', 'var') && ~isempty(restoreFlag) && ...
0075         restoreFlag == 1 && strcmpi(dataType, 'cart')
0076     dataMatrix = restoreBoundary(dataMatrix);
0077 end
0078 
0079 %% evaluate brightness
0080 if ~exist('sizeFraction', 'var'),sizeFraction = 0.5;end
0081 if ~exist('threshold', 'var'),threshold=90;end
0082 % if image is provided
0083 if exist('image', 'var') && ~isempty(image) && strcmpi(dataType, 'cart')
0084     brightFraction = computeBrightFraction(image, ...
0085         dataMatrix(1,:), dataMatrix(2,:), ...
0086         sizeFraction, threshold);
0087 end
0088 
0089 %% build struct
0090 % extract cartesian and polar data
0091 if strcmpi(dataType, 'cart')
0092     % get data
0093     bnd.cartX = dataMatrix(1,:);
0094     bnd.cartY = dataMatrix(2,:);
0095     % center data
0096     [bnd.cartX, bnd.cartY bnd.centerPointOriginal] = ...
0097         centerCart(bnd.cartX, bnd.cartY);
0098     % create polar data
0099     [bnd.polarAngle bnd.polarDistance] = ...
0100         convertCartToPolar(bnd.cartX, bnd.cartY);
0101     % sort data
0102     [bnd.polarAngle bnd.polarDistance, permutationVector] = ...
0103         standardizePolar(bnd.polarAngle, bnd.polarDistance);
0104     bnd.cartX = bnd.cartX(permutationVector);
0105     bnd.cartY = bnd.cartY(permutationVector);
0106     
0107 elseif strcmpi(dataType, 'polar')
0108     % get data
0109     bnd.polarAngle = dataMatrix(1,:);
0110     bnd.polarDistance = dataMatrix(2,:);
0111     % check origin in interior
0112     if min(bnd.polarDistance) < 0
0113         error('elk:boundary:wrongInput', ['The polar input data must have ' ...
0114             'positive distances only']);
0115     end
0116     % sort data
0117     [bnd.polarAngle bnd.polarDistance, ~] = ...
0118         standardizePolar(bnd.polarAngle, bnd.polarDistance);
0119     % create cart data
0120     [bnd.cartX bnd.cartY] = convertPolarToCart(bnd.polarAngle, ...
0121         bnd.polarDistance);
0122     bnd.centerPointOriginal = [0; 0];
0123 else
0124     error('elk:boundaryCurve:wrongInput', ...
0125           'the specified data type must be ''cart'' or ''polar''');
0126 end
0127 
0128 if exist('resampleFlag', 'var') && resampleFlag > 0
0129     % resample data to an accuracy of resampleFlag
0130     angleVector = 0:resampleFlag:2*pi;
0131     distanceVector = 0*angleVector;
0132     for iAngle = 1:length(angleVector)
0133         thisFilter = (bnd.polarAngle >= (angleVector(iAngle) - resampleFlag/2)) | ...
0134                      (bnd.polarAngle >= (angleVector(iAngle) - resampleFlag/2 + 2*pi));
0135         thisFilter = thisFilter & ...
0136                      (bnd.polarAngle <= (angleVector(iAngle) + resampleFlag/2)) | ...
0137                      (bnd.polarAngle <= (angleVector(iAngle) + resampleFlag/2 - 2*pi));
0138         distanceVector(iAngle) = mean(bnd.polarDistance(thisFilter));
0139     end
0140     angleVector(isnan(distanceVector)) = [];
0141     distanceVector(isnan(distanceVector)) = [];
0142     bnd.polarAngle = angleVector;
0143     bnd.polarDistance = distanceVector;
0144     [bnd.cartX bnd.cartY] = convertPolarToCart(bnd.polarAngle, ...
0145         bnd.polarDistance);
0146 end
0147 
0148 
0149 %% add angle bin sizes
0150 leftPolarAngle = 0.5*[bnd.polarAngle(end)-2*pi bnd.polarAngle(1:(end-1))] + ...
0151     0.5*bnd.polarAngle;
0152 rightPolarAngle = 0.5*[bnd.polarAngle(2:end) bnd.polarAngle(1)+2*pi] + ...
0153     0.5*bnd.polarAngle;
0154 bnd.polarBinSize = rightPolarAngle - leftPolarAngle;
0155 
0156 %% correct bnd
0157 bnd = moveBndToCenterOfMass(bnd);
0158 
0159 %% add convexity information
0160 bnd.polarBoundaryArea = sum(bnd.polarDistance.^2.*bnd.polarBinSize)/2;
0161 [K bnd.convexHullArea] = convhull(bnd.cartX, bnd.cartY);
0162 bnd.vrepHull.V = [bnd.cartX(K)' bnd.cartY(K)'];
0163 bnd.hrepHull = convertVrepToHrep(bnd.vrepHull);
0164 bnd.meanWidthHull = sum(computeEdgeLengthHrep(bnd.hrepHull, ...
0165     bnd.hrepHull.A))/pi;
0166 bnd.convexity = bnd.polarBoundaryArea/bnd.convexHullArea;
0167 bnd.largestAngleGap = max(diff([bnd.polarAngle bnd.polarAngle(1)+2*pi]));
0168 bnd.sphericity = 1 - (max(bnd.polarDistance) - min(bnd.polarDistance)) ...
0169             / mean(bnd.polarDistance);
0170 bnd.sphericity2 = 1 - std(bnd.polarDistance) ...
0171             / mean(bnd.polarDistance);
0172 bnd.sphericity3 = 2*sqrt(bnd.convexHullArea/pi)/bnd.meanWidthHull;
0173 if exist('brightFraction', 'var')
0174     bnd.brightFraction = brightFraction;
0175 end
0176 
0177 %% add circle fit
0178 bnd.lambda = 0.5*max(bnd.polarDistance) + 0.5*min(bnd.polarDistance);
0179 
0180 end

Generated on Sat 18-Jul-2015 16:45:31 by m2html © 2005