簡體   English   中英

如何在Python 2.7中使用NumPy數組加快操作速度

[英]How can i speed up operations with NumPy array in Python 2.7

我嘗試處理許多表示為NumPy數組的圖像,但是花費的時間太長。 那就是我想做的

# image is a list with images
max = np.amax(image[k])# k is current image index in loop
# here i try to normalize SHORT color to BYTE color and make it fill all range from 0 to 255
# in images max color value is like 30000 min is usually 0
i = 0
while i < len(image[k]):
    j = 0
    while j < len(image[k][i]):
        image[k][i][j] = float(image[k][i][j]) / (max) * 255
        j += 1
    i += 1

如果我只讀取圖像(總共170張(圖像為512x512),而不花費大約7秒的時間,如果我執行此標准化操作則需要20分鍾。 代碼到此結束。 在這里我嘗試使我的圖像彩色

maskLoot1=np.zeros([len(mask1), 3*len(mask1[0])])
for i in range(len(mask1)):
    for j in range(len(mask1[0])):
        maskLoot1[i][j*3]=mask1[i][j]
        maskLoot1[i][j*3+1]=mask1[i][j]
        maskLoot1[i][j*3+2]=mask1[i][j]

接下來,我嘗試用彩色像素替換選定的區域像素,例如rgb模型中的120(灰色)->(255 40 0)。

            for i in range(len(mask1)):
                for j in range(len(mask1[0])):
                #mask is NumPy array with selected pixel painted in white (255)
                    if (mask[i][j] > 250):
                        maskLoot1[i][j * 3] = lootScheme[mask1[i][j]][1] #red chanel
                        maskLoot1[i][j * 3+1] = lootScheme[mask1[i][j]][2] #green chanel
                        maskLoot1[i][j * 3+2] = lootScheme[mask1[i][j]][3] #bluechanel

而且還需要很多時間,而不是20分鍾,而是需要很長時間才能使我的腳本滯后。 認為這只是我對數組進行的許多操作中的2個,如果在第二種情況下,我們可以對某些對象使用bultin函數的可能性很小。 那么有沒有辦法加快我的腳步?

對於您的蒙版制作代碼,請嘗試以下替換方法進行循環:

maskLoot1 = np.dstack(3*[mask1]).reshape((mask1.shape[0],3*mask1.shape[1]))

還有許多其他方法/變體可以實現上述目標,例如,

maskLoot1 = np.tile(mask1[:,:,None], 3).reshape((mask1.shape[0],3*mask1.shape[1]))

至於問題的第一部分,最好的答案是@furas對您的問題的第一條評論

首先,考慮遷移到Python 3. *。 Numpy放棄對Python的支持Numpy從2020年開始放棄對Python 2.7的支持

對於您的代碼問題。 您沒有在下面使用Numpy的意思。 Numpy是從較低級的庫編譯而來的,它運行速度非常快,不應在Python中循環索引,而應將矩陣扔給Numpy。

問題1使用listcomp和np.array的標准化非常快

import numpy as np
import time

# create dummy image structure (k, i, j, c) or (k, i, j)
# k is image index, i is row, j is columns, c is channel RGB
images = np.random.uniform(0, 30000, size=(170, 512, 512))

t_start = time.time()
norm_images = np.array([(255*images[k, :, :]/images[k, :, :].max()).astype(int) for k in range(170)])
t_end = time.time()

print("Processing time = {} seconds".format(t_end-t_start))
print("Input shape = {}".format(images.shape))
print("Output shape = {}".format(norm_images.shape))
print("Maximum input value = {}".format(images.max()))
print("Maximum output value = {}".format(norm_images.max()))

創建以下輸出

Processing time = 0.2568979263305664 seconds
Input shape = (170, 512, 512)
Output shape = (170, 512, 512)
Maximum input value = 29999.999956185838
Maximum output value = 255

需要0.25秒!

問題2不確定此處的含義,但是如果要將單色圖像的值克隆為RGB值,可以這樣做

# coloring (by copying value and keeping your structure)
color_img = np.array([np.tile(images[k], 3) for k in range(170)])
print("Output shape = {}".format(color_img.shape))

哪個產生

Output shape = (170, 512, 1536)

如果您想保留(c,i,j,k)結構

color_img = np.array([[images[k]]*3 for k in range(170)])  # that creates (170, 3, 512, 512)
color_img = np.swapaxes(np.swapaxes(color_img, 1,2), 2, 3) # that creates (170, 512, 512, 3)

所有這一切需要0.26秒!

問題3為某些區域着色,我將再次使用一個函數和一個listcomp。 由於這是一個示例,因此我使用了默認的顏色(255,40,0),但是您可以使用任何顏色,包括LUT。

# create mask of zeros and ones
mask = np.floor(np.random.uniform(0,256, size=(512,512)))
default_scheme = (255, 40, 0)

def substitute(cimg, mask, scheme):
  ind = mask > 250
  cimg[ind, :] = scheme
  return cimg

new_cimg = np.array([substitute(color_img[k], mask, default_scheme) for k in range(170)])

通常,for循環比while循環快得多。 也使用一個功能

maskLoot1[i][j*3]=mask1[i][j]
maskLoot1[i][j*3+1]=mask1[i][j]
maskLoot1[i][j*3+2]=mask1[i][j]

並在循環中調用該函數將大大加快該過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM