Python 通過 .cube LUT 檔案對影像加濾鏡

醬_油發表於2021-10-02

Python 通過 .cube LUT 檔案對影像加濾鏡

一個好用的python給圖片加濾鏡的程式碼: 

https://github.com/CKboss/PyApplyLUT

這個是對C++程式碼的封裝, 並用上了openmp來並行處理, 速度很快, 4k圖片加濾鏡在本地測試也只要不到0.2秒.

需要編譯一下. 依賴pybind11和eigen. 好在這兩個庫都是隻包含標頭檔案就能用的那種. 到官網下好原始碼(pybind11 2.7.1, eigen 3.4), 在CMakeLists中指明pybind11和eigen的路徑, 編譯一下即可.

得到.so檔案後, 需要把它放到python能找到的地方. 這裡就直接把路徑寫死了.

 

用法如下:

 1 import cv2
 2 import numpy as np
 3 from pathlib2 import Path
 4 
 5 import sys
 6 # the path of .so where python can find it
 7 sys.path.append("Q:/WorkSpace/bfood/lut-master/build/Debug")
 8 from python.PyApplyLUT import PyApplyLUT
 9 from python.lut_tools import cube_to_npy
10 
11 INPUT_IMG = Path(r".\test\1.jpg")
12 LUT_FILE = Path(r".\test\1.cube")
13 
14 # normlizer the input picture to 0~1
15 img = cv2.imread(INPUT_IMG.as_posix())
16 img = img / 255
17 
18 # apply lut 
19 
20 # method 1 load lut from a .cube file
21 alut = PyApplyLUT(lut_file=LUT_FILE)
22 new_img = alut.apply_lut(img)
23 # recover to 0~255
24 new_img = new_img * 255
25 cv2.imwrite("./test/new_img_1.jpg",new_img)
26 
27 # method 2 load lut from the np array
28 cubenpy = cube_to_npy(LUT_FILE)
29 alut = PyApplyLUT(lut_dim=32, lut_cube=cubenpy)
30 new_img = alut.apply_lut(img)
31 # recover to 0~255
32 new_img = new_img * 255
33 cv2.imwrite("./test/new_img_2.jpg",new_img)

 

效果圖:

轉換前(原圖)   ----->    轉換後(加濾鏡)

 

有兩種用法: 

1. 使用.cube檔案

濾鏡(.cube)檔案格式如下:  裡面的值是0~1之間的

# Created by Adobe Lightroom plugin Export LUT (1.17.0)
LUT_3D_SIZE 32
DOMAIN_MIN 0.0 0.0 0.0
DOMAIN_MAX 1.0 1.0 1.0
0.000000 0.000000 0.000000
0.047791 0.000000 0.000000
0.080140 0.000000 0.000000
0.118013 0.000000 0.000000
0.169955 0.000000 0.000000
...

輸入的圖片也要歸一化到0~1之間, 最後輸出的時候要重新放大到0~255

 

2. 使用一個numpy的陣列格試的濾鏡檔案

格式是3,32,32,32這樣的陣列,  .cube轉換到npy的程式碼如下:

def load_lut_file_to_input_cube(cube_path,dim=None):
    with open(cube_path,'r') as f:
        lines = f.readlines()
        for i in range(len(lines)):
            lines[i] = lines[i].strip()
            if dim is None:
                if 'LUT_3D_SIZE' in lines[i]:
                    dim = int(lines[i].split(' ')[-1])
    lines = lines[-dim*dim*dim:]
    cube = np.zeros((3,dim,dim,dim),dtype=np.float32)
    for i in range(0,dim):
        for j in range(0,dim):
            for k in range(0,dim):
                n = i * dim*dim + j * dim + k
                line = lines[n].split(' ')
                x = line
                try:
                    cube[0,i,j,k] = float(x[0]) # r
                    cube[1,i,j,k] = float(x[1]) # g
                    cube[2,i,j,k] = float(x[2]) # b
                except Exception:
                    print(lines[n])
    cube = np.array(cube,dtype=np.float32)
    return cube

 

相關文章