我有一个带有曲线的3D阵列(骨架化数据),需要找到这些线上两点之间的最短连接路径。
如何在Matlab中找到沿3D骨架阵列的两点之间的最短路径?
There are several people asking a similar question both {{数学工作论坛上的3}} here。但大多数答案指向and寻找最短路径,而不是沿着骨架搜索。如果我试图沿着骨架强行它,它也会返回不在两点之间但远离两点的路径。此外,人们建议的一些matlab函数只能处理2D数据(如bwdistgeodesic
,可用于规避非骨架体素)。
我this blog post来自文件交换的两个use。这是我的所作所为:
%get data
load mri
D = double(squeeze(D)); D = D./max(D(:)); D = real(ifft(ifft(ifft(ifftshift(ifftshift(ifftshift( padarray( fftshift(fftshift(fftshift(fft(fft(fft(D,[],1),[],2),[],3),1),2),3), size(D),0,'both' ) ,1),2),3),[],1),[],2),[],3));
figure; ax(1) = subplot(1,3,1); imshow(mean(D,3),[]); title('mean image')
%find vasculature
spacing = [1 1 1];sigmas = [0.5:0.5:2];tau = 1;whiteondark = false;Dvess = vesselness3D(D, sigmas, spacing, tau, whiteondark);
ax(2) = subplot(1,3,2); imshow(imfuse(squeeze(max(Dvess,[],3)), squeeze(max(Dvess>0.5,[],3))),[]); title('masked "vessels"')
%skeletonize
Dskel = Skeleton3D(Dvess>0.5);
ax(3) = subplot(1,3,3); imshow(imfuse(squeeze(max(Dskel,[],3)), squeeze(max(Dvess>0.5,[],3))),[]); title('skeletonized mask'); linkaxes(ax); zoom(2);
%select seeds
corline1 = imline(); idx1 = find(repmat(corline1.createMask, [1 1 size(Dskel,3)]).*Dskel); [sub11, sub21, sub31] = ind2sub(size(Dskel), idx1);
corline2 = imline(); idx2 = find(repmat(corline2.createMask, [1 1 size(Dskel,3)]).*Dskel); [sub12, sub22, sub32] = ind2sub(size(Dskel), idx2);
到目前为止,这些结果非常好:
右图中的白线表示骨架,蓝线表示种子。但是如果我尝试应用距离变换,我找不到最短的路径:
%distance map
dist1 = zeros(size(Dskel)); dist1(sub11, sub21, sub31) = 1; dist1 = bwdist(dist1);
dist2 = zeros(size(Dskel)); dist2(sub12, sub22, sub32) = 1; dist2 = bwdist(dist2);
dist12 = dist1+dist2;
%path
path1 = imregionalmin(Dskel.*dist12);
path2 = imregionalmin(Dskel.*dist12+10000.*(~Dskel));
%path3 = imregionalmin(Dskel.*dist12+Inf.*Dskel); %function cant handle inf
figure; ax(1) = subplot(1,3,1); imshow(squeeze(sum(double(path1),3)),[]); title('')
ax(2) = subplot(1,3,2); imshow(squeeze(sum(double(path2),3)),[]); title('')
%ax(2) = subplot(1,3,2); imshow(squeeze(sum(double(path3),3)),[]); title('')
linkaxes(ax); zoom(3);
第一个发现了几乎整个骨架,第二个看起来像假。区域最小值肯定不适合找到路径,但不确定还有什么。此外,我的距离计算没有考虑骨架,我试图绕过第二条路径,但也没有很好地工作。
我应该做些什么不同?