簡體   English   中英

Python if-elif-else運行時優化

[英]Python if-elif-else runtime optimization

我對上一個問題進行了搜索,但是沒有找到優化代碼的條件。

有關信息,我在Python 2.7上運行,但如果需要可以更改為3

我正在轉換圖像的每個像素,由於某些條件,我必須逐像素進行轉換。 因此,我在其中嵌套了if-elif-else語句的for循環,這需要很長時間才能運行。 對於1536 x 2640的圖像,整個代碼需要約20秒的時間,而90%的時間在這個double for循環內

我相信應該有更好的方法來編寫以下代碼

  for pixel in range(width):
    for row in range(height):
      ADC = img_original[row, pixel]
      if ADC < 84:
        gain   = gain1
        offset = offset1
      elif ADC > 153: 
        gain   = gain3
        offset = offset3
      else:
        gain   = gain2
        offset = offset2

      Conv_ADC  = int(min(max(ADC * gain + offset, 0),255))
      img_conv[row, pixel] = Conv_ADC

謝謝您的幫助


編輯其他詳細信息:

@Jean-FrançoisFabre是正確的,我將根據在0到255之間的哪個部分來應用三個不同的增益/偏移。但是該部分並不總是均勻分布的,可以修改。 也許要提供一些附加的上下文,我只是在圖像上應用自定義S曲線以向上/向下移動像素值。 圖像中的每一列都有自己的S曲線

我的gain1,2,3 / offset1,2,3的值是浮點數。 增益將始終為正,偏移量可以為負或正。我在寬度方向上每個像素都有一個單獨的值,但在行方向上是相同的。

例如,第1列的所有像素都可以使用下表第一行的增益/偏移1,2,3。 圖像中第2列的所有像素將使用下表中第2行的增益/偏移

Pixel   Gain1     Offset1    Gain2     Offset2   Gain3     Offset3
1       0.417722  24.911392  0.623188  7.652176  1.175676  -76.878357
2       0.43038   25.848103  0.623188  9.652176  1.148649  -70.743225
3       0.443038  23.784809  0.637681  7.434776  1.175676  -74.878357
4       0.443038  22.784809  0.652174  5.217384  1.175676  -74.878357
5       0.455696  23.721519  0.637681  8.434776  1.202703  -78.013519
6       0.455696  21.721519  0.637681  6.434776  1.243243  -86.216217
7       0.455696  22.721519  0.623188  8.652176  1.216216  -82.081085
8       0.443038  22.784809  0.623188  7.652176  1.22973   -85.148651
... until pixel 2640 in width direction

我將研究@Jean-FrançoisFabre解決方案,但與此同時,我也正在研究使用一些麻木的方法。

一旦獲得計算速度更快的內容,我將在這里發布我的發現

由於您的值介於0到255之間,並且邊界是均勻分布的,因此可以使用以下技巧:

您似乎要應用3種不同的增益,具體取決於您位於0-255范圍的前三分之一,后三分之一還是后三分之一。

為什么不通過除以85(255/3)來計算索引?

簡單的概念證明:

gainsoffsets = [(10,1),(20,2),(30,3),(30,3)] # [(gain1,offset1),(gain2,offset2),(gain3,offset3)] + extra corner case for value 255

for value in 84,140,250:
    index = value // 85
    gain,offset = gainsoffsets[index]
    print(gain,offset)

結果:

10 1
20 2
30 3

在此循環中,只有一個除法,而沒有if 應該更快(除了numpy方法)

您可以使用更精確的查詢表(也可以通過生成256個元組來避免除法):

gainsoffsets = [(10,1)]*85+[(20,2)]*85+[(30,3)*86]  # add more intervals for more thresholds

嘗試使用查找表:您預先計算了[0,255]范圍內的所有轉換ADC值,並且循環體將簡化

  for pixel in range(width):
    for row in range(height):
      img_conv[row, pixel]= LUT[img_original[row, pixel]]

這是我用來刪除2 for循環的最終實現。 每張圖像下降到約1〜2秒

我正在創建3數組,當它不在我想要的范圍內時,我將內容替換為0。 然后在每個相加之前進行增益乘法和偏移

  height = img_original.shape[0]
  width  = img_original.shape[1]
  print 'height = ', height, 'width = ', width

  # create temp 3 2D-arrays
  img1 = np.array(img_original,dtype=np.int)
  img2 = np.array(img_original,dtype=np.int)
  img3 = np.array(img_original,dtype=np.int)

  #create the 2D array for gain/offset based on 1D array
  # csv array acquire from .csv file, INDEX_xx for column to read
  array_gain1    = np.tile(csv[1:, INDEX_G1],(height,1))
  array_offset1  = np.tile(csv[1:, INDEX_O1],(height,1))

  array_gain2   = np.tile(csv[1:, INDEX_G2],(height,1))
  array_offset2 = np.tile(csv[1:, INDEX_O2],(height,1))

  array_gain3    = np.tile(csv[1:, INDEX_G3],(height,1))
  array_offset3  = np.tile(csv[1:, INDEX_O3],(height,1))

  # replace the content by 0 when not in the desired zone
  np.place(img1,img_original >= G2_TARGET, 0) 
  np.place(img2,img_original < G2_TARGET,0)   
  np.place(img2,img_original > G1_TARGET,0)   
  np.place(img3,img_original <= G1_TARGET, 0) 

  np.place(array_offset1,img_original >= G2_TARGET, 0)
  np.place(array_offset2,(img_original < G2_TARGET), 0)
  np.place(array_offset2,(img_original > G1_TARGET), 0)
  np.place(array_offset3,img_original <= G1_TARGET, 0)

  # apply the gain/offset for each zone
  img1 = np.array(img1 * array_gain1 + array_offset1, dtype=np.uint8)
  img2 = np.array(img2 * array_gain2 + array_offset2, dtype=np.uint8)
  img3 = np.array(img3 * array_gain3 + array_offset3, dtype=np.uint8)

  # recrete the whole image
  img_conv = np.clip(img1 + img2 + img3, 0, 255)

暫無
暫無

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

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