What's the fastest way to find deepest path in a 3D array?

后端 未结 4 2274
遇见更好的自我
遇见更好的自我 2021-02-14 15:34

I\'ve been trying to find solution to my problem for more than a week and I couldn\'t find out anything better than a milion iterations prog, so I think it\'s time to ask someon

4条回答
  •  借酒劲吻你
    2021-02-14 16:08

    It sounds like you're solving a "connected components" problem. If your 3D array can be converted to a bit array (e.g. 0 = bedrock, 1 = cave, or vice versa) then you can apply a technique used in image processing to find the number and dimensions of either the foreground or background.

    Typically this algorithm is applied in 2D images to find "connected components" or "blobs" of the same color. If possible, find a "single pass" algorithm:

    http://en.wikipedia.org/wiki/Connected-component_labeling

    The same technique can be applied to 3D data. Googling "connected components 3D" will yield links like this one:

    http://www.ecse.rpi.edu/Homepages/wrf/pmwiki/pmwiki.php/Research/ConnectedComponents

    Once the algorithm has finished processing your 3D array, you'll have a list of labeled, connected regions, and each region will be a list of voxels (volume elements analogous to image pixels). You can then analyze each labeled region to determine volume, closeness to the surface, height, etc.

    Implementing these algorithms can be a little tricky, and you might want to try a 2D implementation first. Thought it might not be as efficient as you like, you could create a 3D connected component labeling algorithm by applying a 2D algorithm iteratively to each layer and then relabeling the connected regions from the top layer to the bottom layer:

    1. For layer 0, find all connected regions using the 2D connected component algorithm
    2. For layer 1, find all connected regions.
    3. If any labeled pixel in layer 0 sits directly over a labeled pixel in layer 1, change all the labels in layer 1 to the label in layer 0.
    4. Apply this labeling technique iteratively through the stack until you reach layer N.

    One important considering in connected component labeling is how one considers regions to be connected. In a 2D image (or 2D array) of bits, we can consider either the "4-connected" region of neighbor elements

    X 1 X
    1 C 1
    X 1 X
    

    where "C" is the center element, "1" indicates neighbors that would be considered connected, and "X" are adjacent neighbors that we do not consider connected. Another option is to consider "8-connected neighbors":

    1 1 1
    1 C 1
    1 1 1
    

    That is, every element adjacent to a central pixel is considered connected. At first this may sound like the better option. In real-world 2D image data a chessboard pattern of noise or diagonal string of single noise pixels will be detected as a connected region, so we typically test for 4-connectivity.

    For 3D data you can consider either 6-connectivity or 26-connectivity: 6-connectivity considers only the neighbor pixels that share a full cube face with the center voxel, and 26-connectivity considers every adjacent pixel around the center voxel. You mention that "diagonally placed" doesn't count, so 6-connectivity should suffice.

提交回复
热议问题