2017-01-02 95 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