我有一個圖像,存儲在uint8
的一個numpy數組中,形狀爲(planes, rows, cols)
。我需要將其與存儲在形狀爲(mask_rows, mask_cols)
的掩碼(也是uint8
s)中的值進行比較。雖然圖像可能非常大,但面具通常較小,通常爲(256, 256)
,並且將平鋪在image
之上。爲了簡化代碼,我們假設rows = 100 * mask_rows
和cols = 100 * mask_cols
。用於定期屏蔽的`numpy.tile`的替代
我目前正在處理這個閾值的方法是這樣的:
out = image >= np.tile(mask, (image.shape[0], 100, 100))
我可以處理在臉上摑越來越具有MemoryError
之前,這種方式最大的數組比(3, 11100, 11100)
稍大。我認爲這樣做,這樣做我有三個ginormous陣列共存在內存中:image
,瓷磚mask
,和我的回報out
。但平鋪蒙版是同一個小數組複製超過10,000次。因此,如果我能夠節省內存,我只能使用2/3的內存,並且應該能夠處理大3/2的圖像,因此大小約爲(3, 13600, 13600)
。這是,順便說一下,與我獲得一致的,如果我有
np.greater_equal(image, (image.shape[0], 100, 100), out=image)
做閾值來代替我的(失敗)的嘗試在開發的mask
週期性質來處理更大的陣列已經索引mask
定期線性陣列:
mask = mask[None, ...]
rows = np.tile(np.arange(mask.shape[1], (100,))).reshape(1, -1, 1)
cols = np.tile(np.arange(mask.shape[2], (100,))).reshape(1, 1, -1)
out = image >= mask[:, rows, cols]
對於小陣列它確實產生相同的結果的另一個,儘管具有20×減速(!!!)的東西,但它非常不爲更大的尺寸進行。而不是MemoryError
它最終會崩潰python,即使對於其他方法處理沒有問題的值。
我認爲正在發生的是numpy的實際建設(planes, rows, cols)
數組索引mask
,這樣不僅是有沒有記憶保存,但由於它是int32
秒的陣列,它實際上正在四倍空間商店...
任何想法如何去做到這一點?要饒你麻煩,下面的一些沙箱代碼玩弄:
import numpy as np
def halftone_1(image, mask) :
return np.greater_equal(image, np.tile(mask, (image.shape[0], 100, 100)))
def halftone_2(image, mask) :
mask = mask[None, ...]
rows = np.tile(np.arange(mask.shape[1]),
(100,)).reshape(1, -1, 1)
cols = np.tile(np.arange(mask.shape[2]),
(100,)).reshape(1, 1, -1)
return np.greater_equal(image, mask[:, rows, cols])
rows, cols, planes = 6000, 6000, 3
image = np.random.randint(-2**31, 2**31 - 1, size=(planes * rows * cols // 4))
image = image.view(dtype='uint8').reshape(planes, rows, cols)
mask = np.random.randint(256,
size=(1, rows // 100, cols // 100)).astype('uint8')
#np.all(halftone_1(image, mask) == halftone_2(image, mask))
#halftone_1(image, mask)
#halftone_2(image, mask)
import timeit
print timeit.timeit('halftone_1(image, mask)',
'from __main__ import halftone_1, image, mask',
number=1)
print timeit.timeit('halftone_2(image, mask)',
'from __main__ import halftone_2, image, mask',
number=1)
美麗!我在類似這個解決方案上敲了敲頭,但無法正確地獲得額外維度的順序。如果可以的話,我會給你一個額外的+1鏈接到滾動窗口的技巧。並且只是爲了確認:這確實需要遮罩精確地分割圖像,如果沒有,我猜測填充圖像直到它完成,以及可以用圖像完成。調整大小「,對吧? – Jaime
@Jaime,真的,但如果你需要填充,你需要複製(它*可能*可能複製到同一個數據段中,但真的讓我們保持現實...)。唯一可以避免的就是使用一些「scipy」。ndimage'工具,或者明確地處理邊界。 ndimage的東西可能都會覆蓋面具。 – seberg
@Jaime OK,nvm ...它似乎調整大小實際上設法做那記憶移動(如果您是幸運的) – seberg