2017-01-02 97 views
3

根據this SO question比較快的方式,有可能通過計算轉換的數範圍到另一個(線性變換):到多個從範圍轉換爲另範圍

NewValue = (((OldValue - OldMin) * NewRange)/OldRange) + NewMin

然而,我想知道如果有另外更快方式來做到這一點。

考慮一個沒有除法指令的微控制器需要一段時間才能將大量的範圍轉換成另一個範圍(即從圖像文件到18位彩色/像素的24位彩色/像素)。我在想有什麼方法可以優化這一點。

+3

這裏唯一的整數除法替代是浮點乘法。無論你轉向哪個方向,你都不能改變基礎數學的規則。 –

+0

我可以想象浮點操作在這些設備上會更慢。 –

+2

你給出的將範圍(0,2^24-1)轉換爲(0,2^18-1)的例子可以通過位移來完成(加上一個加,如果你想舍入到最近) –

回答

4

24位顏色通常是8 x 3(3個組件,每個8位)。

18位顏色是6×3

一個簡單的轉換>>2 8位值至6個的值的範圍,「下舍入」。在大多數硬件上移位操作都很快。

由於溢出,舍入到最近位置更加困難。 Starrt與此:

(x+2)>>2 

在一個16位值。結果是0到2^6的值,而不是0到2^6-1,就像你想要的那樣。你必須檢測最後一個案例。

如果你買得起ROM,可以使用查找表。 256項並不是那麼多。如果你想應用伽瑪或其他修正,這可能更值得考慮。

但是,真的,只是>>2和/或掩蓋每個組件,然後移動和掩碼到位。

int32 r = ((pix>>2)&(0x3F<<0))|((pix>>4)&(0x3F<<6))|((pix>>6)&(0x3F<<12)); 

其中pix是存儲24位像素的32位值,r存儲18位結果。

這種優化需要在儘可能接近真實環境的情況下進行分析。

+1

舍入到最近並不是一個好主意。簡單地捨棄低兩位就會產生一個統一的變換,其中恰好4個源值映射到1個目標值,貫穿整個範圍(包括末端)。 –

+0

爲什麼你只關閉每個2 MSB(即'&0x3F')?這不會使比例不同嗎? –

+0

@KongChunHo Oops每個字節佔用6個LSB,而不是6個MSB。定影。 – Yakk