function patchData = canonicalizePatchData(patches)
    %also processes depth since we compute statistics over this

    canonicalSize = [80, 80];
    nPatches = numel(patches);
    %allocate
    patchData.patchValid = zeros([canonicalSize(1), canonicalSize(2), nPatches]);
    patchData.patchNx = zeros([canonicalSize(1), canonicalSize(2), nPatches]);
    patchData.patchNy = zeros([canonicalSize(1), canonicalSize(2), nPatches]);
    patchData.patchNz = zeros([canonicalSize(1), canonicalSize(2), nPatches]);
    %allocate nans in case depth isn't defined
    patchData.patchDepth = nan([canonicalSize(1), canonicalSize(2), nPatches]);
    patchData.patchDepthNorm = nan([canonicalSize(1), canonicalSize(2), nPatches]);

    %concatenate
    for i=1:numel(patches)
        p = patches{i};
        patchData.patchValid(:,:,i) = imresize(p.patchValid, canonicalSize) == 1;
        if isfield(p,'patchDepth')
            patchData.patchDepth(:,:,i) = imresize(p.patchDepth, canonicalSize);
            patchData.patchDepthNorm(:,:,i) = normalizeDepth(patchData.patchDepth(:,:,i));
        end
        patchData.patchNx(:,:,i) = imresize(p.patchNx, canonicalSize);
        patchData.patchNy(:,:,i)= imresize(p.patchNy, canonicalSize);
        patchData.patchNz(:,:,i)= imresize(p.patchNz, canonicalSize);
    end
end

function normDepth = normalizeDepth(depth)
    %compute the normalized depth
    depthMasked = depth;
    depthMasked(depth == 0) = NaN;
    normDepth = (depthMasked - nanmean(depthMasked(:))) ./ nanstd(depthMasked(:));
end

