2016-08-12 33 views
1

假設我有一個場景解析映射的圖像,這個場景解析映射中的每個像素指示這個像素屬於哪個對象。現在我想要獲得每個對象的邊界框,我該如何在python中實現它? 對於一個具體例子,說我有一個場景分析圖是這樣的:如何獲得在python中給定像素標籤的對象邊界框?

0 0 0 0 0 0 0 
0 1 1 0 0 0 0 
1 1 1 1 0 0 0 
0 0 1 1 1 0 0 
0 0 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 
1 1 1 1 1 0 0 
1 0 0 0 1 0 0 
1 0 0 0 1 0 0 
1 1 1 1 1 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 

其實,在我的任務,只知道這個寬度和高度對象就夠了。

一個基本的想法是在場景解析圖中從上,下,左,右方向搜索四條邊。但是圖像中可能存在很多小物體,這種方式並不具有時間效率。

第二種方法是計算所有非零元素的座標並找出最大/最小x/y。然後使用這些x和y來計算重量和高度。

有沒有其他更有效的方法來做到這一點?謝謝。

+0

請SH把你的嘗試交給我們。 – Julien

+0

加入@ @ JulienBernu – Demonedge

+0

你需要做的事聽起來非常類似於圖形[洪水填充](https://en.wikipedia.org/wiki/Flood_fill),所以你可以使用算法來做它的起點點(雙關語意)。 – martineau

回答

3

如果你正在處理圖像,你可以使用scipy的ndimage庫。

如果只有一個對象的圖像中,你可以得到scipy.ndimage.measurements.find_objects測量(http://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.ndimage.measurements.find_objects.html):

import numpy as np 
from scipy import ndimage 
a = np.array([[0, 0, 0, 0, 0, 0, 0], 
       [0, 1, 1, 0, 0, 0, 0], 
       [1, 1, 1, 1, 0, 0, 0], 
       [0, 0, 1, 1, 1, 0, 0], 
       [0, 0, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0]]) 

# Find the location of all objects 
objs = ndimage.find_objects(a) 

# Get the height and width 
height = int(objs[0][0].stop - objs[0][0].start) 
width = int(objs[0][1].stop - objs[0][1].start) 

如果在圖像中許多對象,你首先必須標記每個對象,然後得到的測量:

import numpy as np 
from scipy import ndimage 
a = np.array([[0, 0, 0, 0, 0, 0, 0], 
       [0, 1, 1, 0, 0, 0, 0], 
       [1, 1, 1, 1, 0, 0, 0], 
       [0, 0, 1, 1, 1, 0, 0], 
       [0, 0, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 1, 1, 1, 0, 0]]) # Second object here 
# Label objects 
labeled_image, num_features = ndimage.label(a) 
# Find the location of all objects 
objs = ndimage.find_objects(labeled_image) 
# Get the height and width 
measurements = [] 
for ob in objs: 
    measurements.append((int(ob[0].stop - ob[0].start), int(ob[1].stop - ob[1].start))) 

如果檢查ndimage.measurements,你可以得到更多的測量:質量,區域的中心......

+0

這真的很酷!謝謝! – Demonedge

2

使用numpy的:更

import numpy as np 

ind = np.nonzero(arr.any(axis=0))[0] # indices of non empty columns 
width = ind[-1] - ind[0] + 1 
ind = np.nonzero(arr.any(axis=1))[0] # indices of non empty rows 
height = ind[-1] - ind[0] + 1 

說明一下:

arr.any(axis=0)給出了一個布爾數組,告訴您如果列是空的(False)否(True)。 np.nonzero(arr.any(axis=0))[0]然後從該數組中提取非零(即True)索引。 ind[0]是該數組的第一個元素,因此最左列非空列和ind[-1]是最後一個元素,因此是最右側非空列。然後差異給出寬度,取決於是否包含邊框。 高度相似的東西,但在另一個軸上。

+0

爲什麼downvote? – Julien

+0

我不知道,也許強制使用'numpy',因爲它完全可以用python來實現。但OP沒有向我們顯示任何代碼,所以我懷疑他沒有編寫任何代碼。一些高級代表人員在編寫代碼時沒有先寫代碼就皺眉頭。 –

+0

OP要求效率,所以禁止使用numpy先驗和downvoting出於這個原因似乎對我來說是愚蠢的。如果這是我不是一個精神病患者的第二個原因,所以我希望被告知而不是被期望讀懂他們的想法......+我已經看到很多類似的問題由hi-rep人自己回答... – Julien

相關問題