2

ランダムな形状の 3D オブジェクトの体積を計算するスクリプトを作成しています。オブジェクトが中空であるかどうかは気にしません。その総体積を計算する必要があります。私が持っているデータ モデルは、1 と 0 の 3D テーブル (ピクセルのヒストグラム) です。1 は明らかにオブジェクトがある場所であり、何もない場所では 0 です。十分に塗りつぶされたオブジェクトのボリュームを計算するには、1 を含むすべてのピクセルを合計し、ピクセル ボリュームを掛けるだけです。一方、主な問題は、中空のオブジェクトがある場合に残っているため、0 が 1 で囲まれています。したがって、ここで説明した簡単な方法を適用することは、もはや有効ではありません。私たちがする必要があるのは、すべてのオブジェクト領域を 1 で埋めることです。ここに2Dの例があるので、理解できます

2D テーブル:

0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 1 1 1 1 1 1 0 0 0 
0 0 1 1 0 0 0 1 1 1 0 0 
0 0 0 1 0 0 1 0 0 0 0 0 
0 0 1 0 0 0 0 1 0 0 0 0 
0 0 1 0 0 0 0 1 0 0 0 0 
0 0 1 1 1 1 1 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 

これに変換する必要があります

0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 1 1 1 1 1 1 0 0 0 
0 0 1 1 1 1 1 1 1 1 0 0
0 0 0 1 1 1 1 0 0 0 0 0 
0 0 1 1 1 1 1 1 0 0 0 0 
0 0 1 1 1 1 1 1 0 0 0 0 
0 0 1 1 1 1 1 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 
4

5 に答える 5

4

を使用scipyすると、これを 1 行で実行できますbinary_fill_holesそして、これはn次元で機能します。あなたの例では:

import numpy as np
from scipy import ndimage
shape=np.array([
    [0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,1,1,1,1,1,1,0,0,0],
    [0,0,1,1,0,0,0,1,1,1,0,0],
    [0,0,0,1,0,0,1,0,0,0,0,0],
    [0,0,1,0,0,0,0,1,0,0,0,0],
    [0,0,1,0,0,0,0,1,0,0,0,0],
    [0,0,1,1,1,1,1,1,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0]
    ])
shape[ndimage.binary_fill_holes(shape)] = 1
#Output:
[[0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 1 1 1 1 1 0 0 0]
 [0 0 1 1 1 1 1 1 1 1 0 0]
 [0 0 0 1 1 1 1 0 0 0 0 0]
 [0 0 1 1 1 1 1 1 0 0 0 0]
 [0 0 1 1 1 1 1 1 0 0 0 0]
 [0 0 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]]
于 2012-07-07T19:38:41.583 に答える
2

標準のフラッド フィルは、3 次元に拡張できる必要があります。ウィキペディアから、概要の 2-d バージョン:

1. If the color of node is not equal to target-color, return.
 2. Set the color of node to replacement-color.
 3. Perform Flood-fill (one step to the west of node, target-color, replacement-color).
    Perform Flood-fill (one step to the east of node, target-color, replacement-color).
    Perform Flood-fill (one step to the north of node, target-color, replacement-color).
    Perform Flood-fill (one step to the south of node, target-color, replacement-color).
 4. Return.

ステップ 3. では、すべての隣接セルを追跡していることに注意してください。これを変更して 3 次元で隣接するすべてのセルを検索し、以前と同じように実行すると、うまく機能するはずです。

于 2012-07-07T16:00:44.630 に答える
1
matrix=[
    [0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,1,1,1,1,1,1,0,0,0],
    [0,0,1,1,0,0,0,1,1,1,0,0],
    [0,0,0,1,0,0,1,0,0,0,0,0],
    [0,0,1,0,0,0,0,1,0,0,0,0],
    [0,0,1,0,0,0,0,1,0,0,0,0],
    [0,0,1,1,1,1,1,1,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0]
    ]

def fill (x,y):
    global matrix
    if ( x==len (matrix)
             or y==len (matrix[0])
             or x==-1
             or y==-1
             or matrix[x][y]==1 ):
            return
    else:
        matrix[x][y]=1
        fill (x+1,y)
        fill (x-1,y)
        fill (x,y+1)
        fill (x,y-1)

fill (4,4)

for i in matrix:
    print i
于 2012-07-07T16:15:03.100 に答える
1

直感的で読みにくいですが、コンパクトです。

matrix = [[0, 0, 0, 0, 0, 0],
          [0, 0, 1, 0, 1, 0],
          [0, 1, 0, 0, 0, 1],
          [0, 0, 0, 0, 0, 0]]

ranges = [1 in m and range(m.index(1), len(m)-list(reversed(m)).index(1)) or None for m in matrix]
result = [[ranges[j] is not None and i in ranges[j] and 1 or 0 for i,a in enumerate(m)] for j,m in enumerate(matrix)]

result
[[0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0],
 [0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0]]
于 2012-07-07T16:25:22.143 に答える
0

ボクセル形状を塗りつぶすようなことについて話していると仮定すると、なぜこのようなことができないのでしょうか (単純化された 2D ケースの疑似コードの例として取り上げてください。使用しているデータ構造がわかりません-多分numpy.array ? - 私は仮想の「リストのリストをマトリックスとして」取っているだけで、トラバース中に iterable を変更する問題などは考慮していません):

for i, row in enumerate(matrix):
    last_filled_voxel_j = false
    for j, voxel in enumerate(row):
        if voxel:
            if last_filled_voxel != false:
                fill_matrix(matrix, i, last_filled_voxel_j, j)
            last_filled_voxel_j = j

... と と を含まないとfill_matrix(matrix, row, column_start, column_end)の間のボクセルの行をちょうど埋めると仮定します。column_startcolumn_end

これはおそらくあなたが探している答えではないと思いますが、実際に必要になる前に、私が疑似コード化したものとは異なるものを拡張して、より多くの助けを得ることができますか?

于 2012-07-07T16:09:30.653 に答える