如何检测3D域中某些序列的结束位置(x,y,z)

时间:2016-08-17 03:05:30

标签: python algorithm graph analytics d3dimage

我有蛋白质3D creo-EM扫描,它包含一个自身弯曲和扭曲的链条 - 并且在三维空间中有2个链端(如连续绳索)。我需要在两个给定的立方体空间内检测(x,y,z)位置,或者可能在2个结尾的乘数中检测。通过扫描EM显微镜提供的每个体素(在0到1的范围内)中的密度呈现扫描的立方体空间,使得"现有物质"给出接近1的值,"无论"密度值接近0.我需要一种检测蛋白质的方法" rope"边缘(可能"绳索结束"定义在某些纠结的方向上缺乏延续。直观地,我认为至少有两种方法:1)图论中的某种方法(我无法精确指定) - 如果你知道一个 - 请说出或描述它.2)来自分析代数的衍生物 - 但我再也不能指明具体的态度 - 所以请说出或解释一个。请指定建议方法的计算复杂度。我的项目是用Python实现的。请帮忙。提前谢谢。

2 个答案:

答案 0 :(得分:1)

一种方法是选择阈值密度,将低于此阈值的所有体素转换为0并将其全部转换为1,然后查找最短路径最长的一对体素在所有1对体素中。无论绳索的确切形状如何,这两个体素都应该靠近最长绳索的末端。

您可以定义一个图形,其中每个1体素都有一个顶点,每个1体素与其6个(或可能是14个)邻居之间存在边缘。然后,您可以使用广度优先搜索计算O(| V |)时间和空间中某个给定顶点u和每个其他顶点之间的最短路径的长度(因为每个边缘都不需要Dijkstra或Floyd-Warshall有重量1)。对每个可能的起始顶点重复此操作u给出O(| V | ^ 2) - 时间算法。当你这样做时,记录到目前为止最远的一对。

如果您的体素空间有w * h * d个单元格,图表中可能有w * h * d个顶点(如果每个体素都是1个体素),那么这可能需要O(w ^ 2 * h) ^ 2 * d ^ 2)在最坏的情况下,这可能是相当多的时间。幸运的是,如果你能负担得起一个稍微不精确的答案,有很多方法可以加快速度:

  • 仅计算来自边界处的起始顶点的最短路径 - 即具有少于6(或14)个邻居的那些顶点。 (我相信这不会牺牲最佳解决方案。)
  • 或者,首先"镂空"通过反复去除所有这样的边界顶点来删除图形的图形。
  • 选择起始顶点的一个好的顺序是首先选择任何顶点,然后总是选择一个顶点,该顶点与最后一个顶点相距最大可能的距离(当然还没有尝试过)。这将使您在仅仅3次迭代后获得对最长最短路径的非常好的近似:从起始顶点开始的最远顶点将接近两个绳索末端中的一个,并且距离 顶点的最远顶点将是靠近另一端!

注意:如果绳索上由于弯曲而彼此靠近的远点之间没有全体素间隙,那么最短的路径将会短路"通过这些错误的连接,可能会降低准确性。您可以通过提高阈值来改善这种情况。 OTOH,如果阈值太高,那么绳索就会断开。我希望您能够选择仅产生1个连接组件的最高阈值。

答案 1 :(得分:0)

如果要在3D扫描中枚举每个连续路径(从而获得每个路径的末端),您可以为每个位置应用基本的深度优先搜索,例如:

//applied at some voxel
dfs(...)
    for each surrounding voxel 
        dfs(...)

或详细说明:

class coordinate{
    x
    y
    z
    visited
}

initialize pathList
initialize coords

add all coordinates which contain "matter" to coords

dfs(coordinate,path)
    coordinate.visited = TRUE
    isEnd = TRUE
    FOR each coordinate
        //check each of the 26 possible locations (total 26 conditionals)
        IF coordinate.get(x-1,y-1,z+1) IN coords AND 
           NOT coordinate.get(x-1,y-1,z+1).visited THEN
            isEnd = FALSE
            path += coordinate.get(x-1,y-1,z+1)
            dfs(coordinate.get(x-1,y-1,z+1),path)
        ...
        IF coordinate.get(x+1,y+1,z-1) IN coords AND 
           NOT coordinate.get(x+1,y+1,z-1).visited THEN 
            isEnd = FALSE
            path += coordinate.get(x+1,y+1,z-1) 
            dfs(coordinate.get(x+1,y+1,z-1),path)
    IF isEnd THEN
        add path to pathList
    remove coordinate from coords

WHILE coords isn't empty
    dfs(coords.get(0),"")

一般程序(dfs)在许多其他网站上有详细记录,但是如果你想在这里测试一些粗糙的java(我对python不太熟悉)反映了什么&#39在上面:

public class C {

    ArrayList<Coordinate> coords = new ArrayList<>();
    ArrayList<String> paths = new ArrayList<>();



    static class Coordinate {
        int x, y, z;
        boolean visited;
        Coordinate(int x,int y,int z){
            this.x = x;
            this.y = y;
            this.z = z;
            visited = false;
        }

        public String toString() {
            return "("+x+","+y+","+z+")";
        }
    }



    void dfs(Coordinate c,String path) {
        c.visited=true;
        path+=c.toString();
        boolean isEnd = true;
        //apply dfs to 26 possible neighbors
        for(int x = c.x-1; x <= c.x+1; x++) {
            for (int y = c.y-1; y <= c.y+1; y++) {
                for (int z = c.z+1; z >= c.z-1; z--) {
                    Coordinate coord = getCoordinate(x,y,z);
                    //if coord exists and it's not been visited
                    if(coord!=null && !coord.visited && !coord.equals(c)) {
                        isEnd = false;
                        dfs(coord, path);
                    }
                }
            }
        }
        if(isEnd) paths.add(path);

        coords.remove(c);
    }

    Coordinate getCoordinate(int x,int y,int z){
        for(Coordinate b: coords){
            if(x==b.x && y==b.y && z==b.z) return b;
        }
        return null;
    }


    void search(){
        //while there are points in 3d space extend a path from one
        while(!coords.isEmpty()){
            dfs(coords.get(0),"");
        }
    }




    public static void main(String[] args) {

        C coord = new C();

        //for each place where there exists matter
        //create a coordinate object and add to coords
        // for example:
        coord.coords.add(new Coordinate(0,0,0));
        coord.coords.add(new Coordinate(-1,1,1));
        coord.coords.add(new Coordinate(1,1,1));
        coord.coords.add(new Coordinate(-1,2,2));
        coord.coords.add(new Coordinate(-1,0,2));
        coord.coords.add(new Coordinate(1,2,2));
        coord.coords.add(new Coordinate(1,0,2));

        coord.search();
        //print out each path on separate line, 
        //the path endings can easily be obtained from this 
        for(String s:coord.paths) System.out.println(s);

    }
}