我有一个3D图像,分为连续区域,每个体素具有相同的值.分配给该区域的值对于该区域是唯一的,并用作标签.下面的示例图片描述了2D案例: 1 1 1 1 2 2 2 1 1 1 2 2 2 3Im = 1 4 1 2 2 3 3 4 4 4 4 3 3 3
1 1 1 1 2 2 2 1 1 1 2 2 2 3 Im = 1 4 1 2 2 3 3 4 4 4 4 3 3 3 4 4 4 4 3 3 3
我想创建一个描述这些区域之间的相互关系的图表.在上面的例子中,这将是:
0 1 0 1 A = 1 0 1 1 0 1 0 1 1 1 1 0
我正在寻找一个快速的解决方案来在MATLAB中为大型3D图像执行此操作.我提出了一个迭代所有区域的解决方案,每次迭代需要0.05秒 – 不幸的是,对于具有32’000个区域的图像,这将花费半个多小时.现在有人有更优雅的方式吗?我发布了下面的当前算法:
labels = unique(Im); % assuming labels go continuously from 1 to N A = zeros(labels); for ii=labels % border mask to find neighbourhood dil = imdilate( Im==ii, ones(3,3,3) ); border = dil - (Im==ii); neighLabels = unique( Im(border>0) ); A(ii,neighLabels) = 1; end
imdilate是我想避免的瓶颈.
谢谢您的帮助!
我提出了一个解决方案,它结合了 Divakar和 teng的答案,以及我自己的修改,并将其推广到2D或3D案例.为了提高效率,我应该预先分配r和c,但在此期间,这是运行时:
>对于尺寸为117x159x126和32000个独立区域的3D图像:0.79秒
>对于上面的2D示例:使用此解决方案为0.004671s,使用Divakar解决方案为0.002136s,使用teng解决方案为0.03995s.
不过,我没有尝试将获胜者(Divakar)扩展到3D案例!
noDims = length(size(Im)); validim = ones(size(Im))>0; labels = unique(Im); if noDims == 3 Im = padarray(Im,[1 1 1],'replicate', 'post'); shifts = {[-1 0 0] [0 -1 0] [0 0 -1]}; elseif noDims == 2 Im = padarray(Im,[1 1],'replicate', 'post'); shifts = {[-1 0] [0 -1]}; end % get value of the neighbors for each pixel % by shifting the image in each direction r=[]; c=[]; for i = 1:numel(shifts) tmp = circshift(Im,shifts{i}); r = [r ; Im(validim)]; c = [c ; tmp(validim)]; end A = sparse(r,c,ones(size(r)), numel(labels), numel(labels) ); % make symmetric, delete diagonal A = (A+A')>0; A(1:size(A,1)+1:end)=0;
谢谢您的帮助!