2015-04-27 31 views
2

有點隨機創建3D圖像給定2個圖像有點隨機創建2個圖像的3D點

目標是從2個圖像中創建一組n個3D座標(種子)。 n可以是100-1000點的任何地方。

我有2個純黑白圖像,它們的高度相同,寬度可變。圖像的大小可以高達1000x1000像素。我將它們讀入numpy數組中,並將rgb代碼壓扁成1(黑色)和零(白色)。

這裏是例如從處理2非常小的圖像:

In [6]: img1 
Out[6]: 
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8) 

In [8]: img2 
Out[8]: 
array([[0, 0, 0, 0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 1, 1, 0, 0, 0], 
     [0, 0, 0, 1, 1, 0, 0, 1, 0, 0], 
     [0, 0, 1, 1, 0, 0, 0, 1, 0, 0], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [1, 1, 0, 0, 0, 0, 0, 0, 1, 1], 
     [0, 0, 1, 0, 0, 0, 1, 1, 0, 0], 
     [0, 0, 1, 0, 0, 1, 1, 0, 0, 0], 
     [0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
     [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]], dtype=uint8) 

接下來,創建索引陣列黑色像素的所有位置映射爲每個圖像像這樣:

In [10]: np.transpose(np.nonzero(img1)) 
Out[10]: 
array([[0, 0], 
     [0, 1], 
     [0, 2], 
     [0, 3], 
     [0, 4], 
     [0, 5], 
     [0, 6], 
     ... 

我然後想要將每個圖像的每個2D黑色像素擴展到3D空間。如果這些3D點相交,我想隨機抓取n個3D字體(種子)。此外,作爲一個增強,如果我可以將這些3d點稍微均勻地分散到三維空間中以避免具有較大黑色像素密度的區域的「聚類」,則會更好。但是我還沒有能夠圍繞這個過程進行考慮。

這裏的設置了一個可視化:

line up images extrude image intersecting images

我已經試過以下似乎工作在非常小的圖像,但減速停下的圖像變得更大。瓶頸似乎發生在我分配common_points的地方。

img1_array = process_image("Images/nhx.jpg", nheight) 
img2_array = process_image("Images/ku.jpg", nheight) 

img1_black = get_black_pixels(img1_array) 
img2_black = get_black_pixels(img2_array) 

# create all img1 3D points: 
img1_3d = [] 
z1 = len(img2_array[1]) # number of img2 columns 

for pixel in img1_black: 
    for i in range(z1): 
     img1_3d.append((pixel[0], pixel[1], i)) # (img1_row, img1_col, img2_col) 

# create all img2 3D points: 
img2_3d = [] 
z2 = len(img1_array[1]) # number of img1 columns 

for pixel in img2_black: 
    for i in range(z2): 
     img2_3d.append((pixel[0], pixel[1], i)) # (img2_row, img2_col, img1_col) 

# get all common 3D points 
common_points = [x for x in img1_3d if x in img2_3d] 

# get num_seeds number of random common_points 
seed_indices = np.random.choice(len(common_points), num_seeds, replace=False) 

seeds = [] 
for index_num in seed_indices: 
    seeds.append(common_points[index_num]) 

問題:

  • 我怎樣才能避免瓶頸?我一直未能想出一個numpy解決方案。
  • 有沒有更好的解決方案,一般來說,我是如何編碼的?
  • 有關我如何能夠在某種程度上均勻分散種子的想法?

更新編輯:

基於盧克的算法,我想出了下面的工作代碼。這是正確的實施?這可以改進嗎?

img1_array = process_image("Images/John.JPG", 500) 
img2_array = process_image("Images/Ryan.jpg", 500) 

img1_black = get_black_pixels(img1_array) 
# img2_black = get_black_pixels(img2_array) 

density = 0.00001 
seeds = [] 

for img1_pixel in img1_black: 
    row = img1_pixel[0] 

    img2_row = np.array(np.nonzero(img2_array[row])) # array of column numbers where there is a black pixel 

    if np.any(img2_row): 
     for img2_col in img2_row[0]: 
      if np.random.uniform(0, 1) < density: 
       seeds.append([row, img1_pixel[1], img2_col]) 

回答

0

的瓶頸是因爲你比較在「蘋果」每一個3D點在「橙色」陰影區,這是一個巨大的比較的數量陰影區,每一個三維點。只需查看同一行中的點,就可以加快imgHeight的速度。你也可以通過將img2_3d存儲爲一個集合而不是一個列表來加速它,因爲調用集合中的「in」要快得多(這是O(1)操作而不是O(n)操作)。

但是,最好完全避免列出所有3D點。這裏有一個解決方案:

  1. 選擇一個任意密度參數,稱之爲密度。嘗試密度= 0.10填充10%的交點。
  2. 對於Apple中的每個黑色像素,循環遍歷橙色的同一行中的黑色像素。如果(random.uniform(0,1)<密度),請在(applex,orangex,row)或任何適合您的座標系的佈置上創建3D點。

該算法將均勻採樣,因此具有更多黑色的3D區域將具有更多樣本。如果我理解你的最後一個問題,你想在黑色較少的區域採樣更密集(儘管我不知道爲什麼)。要做到這一點,你可以:

  1. 做你的兩個圖像(OpenCV有這個功能)的反相的高斯模糊,並乘以每個0.9和0.1。現在您的圖像具有較高的值,圖像更白。
  2. 做上面的算法,但對於步驟2中的每個像素對,設置Density = blurredOrangePixel * blurredApplePixel。因此,您的選擇密度將在白色區域更高。

雖然我會嘗試基本的算法;我認爲它會更好看。

+0

盧克,感謝您的幫助!我沒有做好解釋如何以及爲什麼我想要特定類型的「種子」分佈,但您的算法似乎很好地分配像素。如果它成爲問題,我會在那個時候穿過那座橋。在我接受你的答案之前最後一個問題,我的實現看起來是否正確? – Mox

+0

基本邏輯對我來說很合適。我的猜測是它可以用於小圖像。你可以用一些非常小的東西來測試它,比如一對3x2像素的圖像。 – Luke