如何使用Python将3D Luts .cube文件应用到图像中?
在Python中应用64×64×64规格3D LUT的方法
OpenCV本身没有直接支持3D LUT的API,但可以通过手动实现插值或者借助专业颜色处理库来完成。以下是两种可行方案:
方法一:基于OpenCV+Numpy手动实现三线性插值
这种方式不需要额外依赖,完全用基础库实现核心逻辑:
import cv2 import numpy as np def apply_3d_lut(image, lut): # 转换图像到RGB格式(OpenCV默认读入BGR) if image.shape[-1] == 3: image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 将像素值从0-255映射到LUT的0-63范围 normalized = image.astype(np.float32) / 255.0 * 63.0 r, g, b = np.split(normalized, 3, axis=-1) r, g, b = r[..., 0], g[..., 0], b[..., 0] # 计算插值所需的整数坐标(确保不超出LUT边界) r0 = np.floor(r).astype(np.int32) r1 = np.minimum(r0 + 1, 63) g0 = np.floor(g).astype(np.int32) g1 = np.minimum(g0 + 1, 63) b0 = np.floor(b).astype(np.int32) b1 = np.minimum(b0 + 1, 63) # 计算插值权重 dr = r - r0 dg = g - g0 db = b - b0 # 提取8个相邻的LUT颜色值 c000 = lut[r0, g0, b0] c001 = lut[r0, g0, b1] c010 = lut[r0, g1, b0] c011 = lut[r0, g1, b1] c100 = lut[r1, g0, b0] c101 = lut[r1, g0, b1] c110 = lut[r1, g1, b0] c111 = lut[r1, g1, b1] # 执行三线性插值 c00 = c000 * (1 - db) + c001 * db c01 = c010 * (1 - db) + c011 * db c10 = c100 * (1 - db) + c101 * db c11 = c110 * (1 - db) + c111 * db c0 = c00 * (1 - dg) + c01 * dg c1 = c10 * (1 - dg) + c11 * dg final_color = c0 * (1 - dr) + c1 * dr # 转换回BGR格式并保存 final_image = final_color.astype(np.uint8) final_image = cv2.cvtColor(final_image, cv2.COLOR_RGB2BGR) return final_image # 示例用法 # lut = np.load('64x64x64_lut.npy') # 加载已解析的LUT数组,形状为(64,64,64,3) # input_img = cv2.imread('input.jpg') # output_img = apply_3d_lut(input_img, lut) # cv2.imwrite('output.jpg', output_img)
方法二:使用colour-science库快速实现
colour是专门的颜色处理库,支持直接加载.cube等常见3D LUT格式,无需手动处理插值:
- 先安装库:
pip install colour-science
- 代码实现:
import cv2 import numpy as np from colour.io import read_LUT, apply_LUT # 加载64x64x64的3D LUT(支持.cube格式) lut = read_LUT('your_lut.cube') # 读取并预处理图像 input_img = cv2.imread('input.jpg') img_rgb = cv2.cvtColor(input_img, cv2.COLOR_BGR2RGB) img_float = img_rgb.astype(np.float32) / 255.0 # 应用LUT并转换回可保存的格式 result_float = apply_LUT(img_float, lut) result_img = (result_float * 255).astype(np.uint8) result_bgr = cv2.cvtColor(result_img, cv2.COLOR_RGB2BGR) # 保存结果 cv2.imwrite('output.jpg', result_bgr)
注意事项
- 确保你的3D LUT数组形状为
(64,64,64,3),每个通道值范围为0-255(或0-1,需对应代码中的归一化逻辑) - 如果LUT是二进制格式,需要先自行解析为numpy数组再使用
内容的提问来源于stack exchange,提问作者Arthur Minas
相关产品推荐
相关产品推荐

