MATLAB:在3d骨架线中排序像素位置或路径

时间:2018-04-10 16:21:23

标签: matlab 3d line

我在3d矩阵中有一系列血管对象。我已经分离了每个并使用Skeleton3D对它们进行骨架化(所以现在我有一堆带有扭曲线段的矩阵(没有分支))。我想现在沿着每个骨架的长度从尖端移动到尖端并在每个点执行操作......只是不知道如何找到线的末端或路径。

所以在下面的代码中,我需要像素序列向量,其中包含从扭曲的3d线的一端开始并向另一端运行的3d像素位置。

    for i=1:length(pixelorder)
        someoperation(pixelorder(i));
    end

我开始使用一些中间方法的代码。它穿过z轴并寻找一个切片,其中只有一个像素值等于一(我知道这是一厢情愿的想法..但如果它在那里它应该是该线的横截面)。从那里我在像素周围采用3x3x3邻域(2,2,2处的像素),并寻找等于1的其他值。然后,我检查从中心像素到该邻域中任何等于1的距离。我把距离中心像素最小距离的两个最小距离像素称为该线的任一方向。如果转弯(即在2,2,2中心处有1个像素值,2,2,1..2,2,3然后在1,2,3处转弯)我会移除相邻像素(距离== 1)距离中心最近的像素。

然后计划在两个方向上移动,使用类似的策略在任一方向构建向量,最后我将这些向量组合在一起。

当我处理它时,我将每个邻域的中心值设置为零...当我用完像素== 1的值时应该到达行的末尾?

希望这是有道理的..

无论轴和扭曲如何,段都以随机位置开始和结束,所以我不能只迭代一个轴。

 skel=skel2;%padarray(skel2,[1,1,1],0,'both');
skelcopy=skel;
vectorforward=[];
vectorbackward=[];
for i=1:z
    if sum(sum(skel(:,:,i)))==0
        continue
    elseif sum(sum(skel(:,:,i)))==1 %doesnt really work if there's no single point in this/any dimension
        [startrow,startcol]=find(skel(:,:,i)==1);
        startind=sub2ind(size(skel),startrow,startcol,i);
        vectorforward(end+1)=startind;
        skelcopy(startrow,startcol,i)=0;
        checksize=1;
        truelocind=find(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,i-checksize:i+checksize)==1);
        xrow=startrow-checksize:startrow+checksize;
        ycol=startcol-checksize:startcol+checksize;
        islice=i-checksize:i+checksize;
        truelocsubs=[];
        dists=[];
        matsize=size(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,i-checksize:i+checksize));

        indmat=zeros(matsize);
        for im=1:matsize(1)
            for jm=1:matsize(2)
                for km=1:matsize(3)
                    indmat(im,jm,km)=sub2ind(size(skel),xrow(im),ycol(jm),islice(km));%sub2ind(size(skel),j,i,k);
                end
            end
        end      
        for j=1:length(truelocind)
            [truelocsubs(j,1),truelocsubs(j,2),truelocsubs(j,3)]=ind2sub(matsize,truelocind(j));
            dists(j)=norm((matsize/2+0.5)-truelocsubs(j,:));
        end
        [sortlist,sortorder]=sort(dists);
        if length(sortlist)>2
            if sortlist(3)>sortlist(2)
                closeinds=indmat(truelocind(sortorder(1:2)));
            else %in case of turn: 3x3x3 neighborhood has values at 2,2,1..2,2,2..2,2,3..1,2,3
                closeinds=indmat(truelocind(sortorder(1))); %selects closest pixel
                dists2=[];
                for j=1:length(truelocind)
                    dists2(j)=norm(truelocsubs(sortorder(1),:)-truelocsubs(j,:)); %distances of other connected pixels from closest
                end
                adjacents=find(dists2==1);
                adjacents(end+1)=find(dists2==0);
                truelocind(adjacents)=[]; %removes pixels that are part of turn from selection
                sortorder(adjacents)=[];
                closeinds(end+1)=indmat(truelocind(sortorder(1)));
            end
        elseif length(sortlist)==2
            closeinds=indmat(truelocind(sortorder(1:2)));
        else
            disp('line end')
        end
            vectorforward(end+1)=closeinds(1);
            vectorbackward(end+1)=closeinds(2);
        % forwards
        while length(truelocind)>0
            center=vectorforward(end);%closeinds(1);%...do the stuff with that...find new closeind(1      
            [startrow,startcol,zloc]=ind2sub(size(skel),center);         
            startind=center;%sub2ind(size(skel),startrow,startcol,zloc);
            skelcopy(startrow,startcol,zloc)=0;
            checksize=1;
            truelocind=find(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,zloc-checksize:zloc+checksize)==1);
            xrow=startrow-checksize:startrow+checksize;
            ycol=startcol-checksize:startcol+checksize;
            islice=zloc-checksize:zloc+checksize;
            truelocsubs=[];
            dists=[];
            matsize=size(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,zloc-checksize:zloc+checksize));

            indmat=zeros(matsize);
            for im=1:matsize(1)
                for jm=1:matsize(2)
                    for km=1:matsize(3)
                        indmat(im,jm,km)=sub2ind(size(skel),xrow(im),ycol(jm),islice(km));%sub2ind(size(skel),j,zloc,k);
                    end
                end
            end      
            for j=1:length(truelocind)
                [truelocsubs(j,1),truelocsubs(j,2),truelocsubs(j,3)]=ind2sub(matsize,truelocind(j));
                dists(j)=norm((matsize/2+0.5)-truelocsubs(j,:));
            end
            [sortlist,sortorder]=sort(dists);
            if length(sortlist)>1
                disp('check')
                if sortlist(2)>sortlist(1)
                    closeinds=indmat(truelocind(sortorder(1)));
                else %in case of turn: 3x3x3 neighborhood has values at 2,2,1..2,2,2..2,2,3..1,2,3
                    disp('sup?')
                    closeinds=indmat(truelocind(sortorder(1))); %selects closest pixel
                    dists2=[];
                    for j=1:length(truelocind)
                        dists2(j)=norm(truelocsubs(sortorder(1),:)-truelocsubs(j,:)); %distances of other connected pixels from closest
                    end
                    adjacents=find(dists2==1);
                    adjacents(end+1)=find(dists2==0);
                    truelocind(adjacents)=[]; %removes pixels that are part of turn from selection
                    sortorder(adjacents)=[];
                    closeinds(end+1)=indmat(truelocind(sortorder(1)));
                end
            elseif length(sortlist)==1
                closeinds=indmat(truelocind(sortorder(1)));
            else
                disp('end line')
            end
                vectorforward(end+1)=closeinds(1);
            end
        % backwards
  truelocind='startbackwards';      
        while length(truelocind)>0
            center=vectorbackward(end);%closeinds(1);%...do the stuff with that...find new closeind(1      
            [startrow,startcol,zloc]=ind2sub(size(skel),center);         
            startind=center;%sub2ind(size(skel),startrow,startcol,zloc);
            skelcopy(startrow,startcol,zloc)=0;
            checksize=1;
            truelocind=find(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,zloc-checksize:zloc+checksize)==1);
            xrow=startrow-checksize:startrow+checksize;
            ycol=startcol-checksize:startcol+checksize;
            islice=zloc-checksize:zloc+checksize;
            truelocsubs=[];
            dists=[];
            matsize=size(skelcopy(startrow-checksize:startrow+checksize,startcol-checksize:startcol+checksize,zloc-checksize:zloc+checksize));

            indmat=zeros(matsize);
            for im=1:matsize(1)
                for jm=1:matsize(2)
                    for km=1:matsize(3)
                        indmat(im,jm,km)=sub2ind(size(skel),xrow(im),ycol(jm),islice(km));%sub2ind(size(skel),j,zloc,k);
                    end
                end
            end      
            for j=1:length(truelocind)
                [truelocsubs(j,1),truelocsubs(j,2),truelocsubs(j,3)]=ind2sub(matsize,truelocind(j));
                dists(j)=norm((matsize/2+0.5)-truelocsubs(j,:));
            end
            [sortlist,sortorder]=sort(dists);
            if length(sortlist)>1
                if sortlist(2)>sortlist(1)
                    closeinds=indmat(truelocind(sortorder(1)));
                else %in case of turn: 3x3x3 neighborhood has values at 2,2,1..2,2,2..2,2,3..1,2,3
                    disp('sup?')
                    closeinds=indmat(truelocind(sortorder(1))); %selects closest pixel
                    dists2=[];
                    for j=1:length(truelocind)
                        dists2(j)=norm(truelocsubs(sortorder(1),:)-truelocsubs(j,:)); %distances of other connected pixels from closest
                    end
                    adjacents=find(dists2==1);
                    adjacents(end+1)=find(dists2==0);
                    truelocind(adjacents)=[]; %removes pixels that are part of turn from selection
                    sortorder(adjacents)=[];
                    closeinds(end+1)=indmat(truelocind(sortorder(1)));
                end
            elseif length(sortlist)==1
                closeinds=indmat(truelocind(sortorder(1)));
            else
                disp('end line')
            end
                vectorbackward(end+1)=closeinds(1);

 end

        break
    end 
end
vectorbackward(end)=[];
vectorforward(end)=[];
pixelorder=[vectorbackward,vectorforward];

0 个答案:

没有答案