如何快速在转换后的YUV格式33×33×33 LUT中查找8个顶点?
我之前刚好处理过类似的3D LUT在YUV图像流中的性能优化问题,给你两个方向的解决方案,看哪种更贴合你的需求:
方案一:保留原RGB空间插值逻辑,砍掉冗余转换
这种方案能完全和你原来的处理结果一致,核心是减少不必要的YUV↔RGB转换步骤:
- 只做一次YUV→RGB转换:你不需要把插值后的RGB再转回YUV了!既然你已经把所有33³个LUT顶点的输出RGB预转成了YUV,那流程可以改成:
- 把目标YUV像素转成RGB,计算它在RGB网格中的索引:
假设RGB通道范围是0-255,网格步长是step = 255 / 32 ≈ 7.96875,那么索引计算可以用整数运算加速:
这样比浮点除法快很多,而且不会有精度损失。i = (Rt * 32) >> 8 // Rt是转换后的红色通道值,0-255 j = (Gt * 32) >> 8 k = (Bt * 32) >> 8 - 取出这8个顶点对应的预转换好的输出YUV值(就是你之前转好的那些)
- 用原RGB空间的插值权重对这8个YUV值进行插值:
权重基于目标RGB在立方体中的相对位置计算:
然后8个顶点的权重分别是r_weight = (Rt - i * step) / step g_weight = (Gt - j * step) / step b_weight = (Bt - k * step) / step(1-r_weight)*(1-g_weight)*(1-b_weight)、r_weight*(1-g_weight)*(1-b_weight)等,用这些权重对Y、U、V三个分量分别插值,直接得到最终的YUV结果。
- 把目标YUV像素转成RGB,计算它在RGB网格中的索引:
- 边界处理:当目标RGB值刚好是255时,索引会是32,此时i+1=33超出范围,这种情况直接让i+1=i即可,也就是用同一个顶点。
方案二:直接在YUV空间构建3D LUT(性能拉满,结果略有差异)
如果可以接受和原RGB插值结果的细微差异,完全可以绕开所有RGB转换,直接在YUV空间操作:
- 划分YUV网格:和RGB网格逻辑一致,把Y、U、V三个通道分别分成33个采样点:
- Y通道范围如果是0-255,步长同样是
255/32 - U/V通道如果是-128到127,先把值偏移到0-255范围,再用同样步长划分
- Y通道范围如果是0-255,步长同样是
- 预填充YUV LUT:对每个YUV网格点,转成RGB后查原RGB LUT得到输出RGB,再转成YUV存入新的LUT
- 快速查找插值:对目标YUV像素,直接计算每个通道的索引,取出8个顶点的输出YUV值插值即可,全程不需要任何RGB转换,速度是最快的。
注意:这种方案的插值是在YUV空间进行的,和原RGB空间的立方体插值结果会有细微差异(因为YUV和RGB的转换是线性矩阵变换,但网格划分的空间不同),需要测试是否符合你的画质要求。
内容的提问来源于stack exchange,提问作者Natalia Slepkova
相关产品推荐
相关产品推荐

