2016-11-22 7 views
1

私は画像マスクの2つの領域のインデックス/位置を抽出しようとしており、python、opencv2、numpyおよびscipyの組み合わせを使用しています。画像マスクの特徴位置のインデックスを、python、opencv2、numpyで取得します。

私は画像と同じサイズのバイナリmaskを持っています。 この情報を使用して

label_im, nb_labels = ndimage.label(mask) 
sizes = ndimage.sum(mask, label_im, range(nb_labels + 1)) 

とラベルとそれの大きさを生成した後、私は最大の領域を抽出することができています。

のは、我々は10×10の行列があるとしましょう:

1  1  1  0  0  0  0  0  0  0 
1  1  1  0  0  0  0  0  0  0 
1  1  1  0  0  0  0  2  2  0 
0  0  0  0  0  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  0  0  0 
0  0  0  0  0  0  0  0  0  0 

たものがあるので、私はさらにエリア2と3を(分析する必要があることを、私は3つの異なる領域(1,2,3)を持っていると私はすでに知っています2つの最大)。

今は領域の

  1. 一番上の一番左にあるピクセルのインデックス検索する - (N)として以下マーク
  2. 領域の最右端 - [N]と下マーク
  3. を上記のように

同じマトリックス:

1  1  1  0  0  0  0  0  0  0 
1  1  1  0  0  0  0  0  0  0 
1  1  1  0  0  0  0 (2) 2  0 
0  0  0  0  0  0  0  2  2  0 
0 (3) 3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2  2  0 
0  3  3  3  3  0  0  2 [2] 0 
0  3  3  3 [3] 0  0  0  0  0 
0  0  0  0  0  0  0  0  0  0 

はどのようにトンを行うための最速の方法です帽子?

問題1: 私はこれらの行列条件の構文に苦しんでいます。 例えば、私が試してみてください。それが再びバイナリマスクを取得する必要があります

mask2 = mask[label_im == 2] 

が、元のマスクが2 を持っているに設定された細胞だけで私が何を上記の結果を正確にわからないんだけど生成する。私はそれをさらに処理することができません。

問題2: その後、最左端のピクセルが設定されている行/列のインデックスを見つけるようなことをしなければなりません。 最下点と同じです。

例えば領域2のために、結果は次のようになります(上記の行列のような)

Xが列を表し、及び行のY(インデックス0から始まる)

するか、である

point1-X = 7 
point1-Y = 2 
point2-X = 8 
point2-Y = 7 

python/opencv2/numpy/scipyの組み合わせで問題を解決する良い方法がありますか? lowermost rightmostが最後のものであろう一方

答えて

1

numpyの入力画像アレイの平坦化バージョンに基づく溶液

は、topmost leftmost場所は、最初のものであろう。だから、1つのトリックは、np.nonzeroでこれらの2つの領域の平坦化されたインデックスを取得し、それぞれ期待される出力を得るために単にminmaxのインデックスを探します。最後にnp.unravel_indexを使用して元の2D形式に対応する行、列インデックスを取得します。

したがって、1つのアプローチは次のようになり -

# Flattend indices for those two regions using the given labels 
idx0 = np.nonzero(a.ravel()==2)[0] 
idx1 = np.nonzero(a.ravel()==3)[0] 

# Get the min, max indices for them. Use np.unravel_index to retrieve 
# back row, col indices corresponding to original format of 2D input. 
idxs = [idx0.min(), idx0.max(), idx1.min(), idx1.max()] 
out = np.column_stack(np.unravel_index(idxs,a.shape)) 

サンプル実行 -

In [137]: a 
Out[137]: 
array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 
     [1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 
     [1, 1, 1, 0, 0, 0, 0, 2, 2, 0], 
     [0, 0, 0, 0, 0, 0, 0, 2, 2, 0], 
     [0, 3, 3, 3, 3, 0, 0, 2, 2, 0], 
     [0, 3, 3, 3, 3, 0, 0, 2, 2, 0], 
     [0, 3, 3, 3, 3, 0, 0, 2, 2, 0], 
     [0, 3, 3, 3, 3, 0, 0, 2, 2, 0], 
     [0, 3, 3, 3, 3, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

In [138]: idx0 = np.nonzero(a.ravel()==2)[0] 
    ...: idx1 = np.nonzero(a.ravel()==3)[0] 
    ...: idxs = [idx0.min(), idx0.max(), idx1.min(), idx1.max()] 
    ...: out = np.column_stack(np.unravel_index(idxs,a.shape)) 
    ...: 

In [139]: out 
Out[139]: 
array([[2, 7], # topmost leftmost of region -1 
     [7, 8], # lowermost rightmost of region -1 
     [4, 1], # topmost leftmost of region -2 
     [8, 4]]) # lowermost rightmost of region -2 

OpenCVのベースのソリューション

のOpenCVのcv2.findContours輪郭を見つけるために使用することができ、それ自体はかなりのエフェイです簡単な実装。したがって、パフォーマンス指向のソリューションの場合にのみ、インデックスの発見を輪郭に限定することになります。 topmost leftmostlowermost rightmost行、各地域の列のインデックスを取得するための関数は以下であることが示さ -

def TL_LR(a, label): 
    _,contours,hierarchy = cv2.findContours((a==label).astype('uint8'),\ 
              cv2.RETR_TREE,cv2.RETR_LIST) 
    idx = contours[0].reshape(-1,2) 
    lidx = idx[:,0] + a.shape[1]*idx[:,1] 
    return np.unravel_index([lidx.min(), lidx.max()],a.shape) 

OpenCVのバージョンの前3.0に、我々は唯一のcv2.findContoursから2つの出力を取得されることに注意してください。したがって、これらのバージョンの場合は、そのステップで_をスキップしてください。

のは、与えられたサンプル上でそれを使用してみましょう -

In [188]: TL_LR(a,2) 
Out[188]: (array([2, 7]), array([7, 8])) 

In [189]: TL_LR(a,3) 
Out[189]: (array([4, 8]), array([1, 4])) 

In [190]: out # Output from previous approach 
Out[190]: 
array([[2, 7], 
     [7, 8], 
     [4, 1], 
     [8, 4]]) 
+0

すごいです!助けてくれてありがとう!それは完璧に動作します! –

+0

私は最初にnumpyベースのソリューションを試した後、サンプルイメージ1920x1080でopencv-solutionを試しました。 S1:0.0529999732971sの時間、S2:0.0599999427795sの時間、これらの実装の違いは本当に目立っていません。とにかくopencvベースのソリューションもありがとう! –

関連する問題