Skip to content

02_ccm_useLstsq

复制本地路径 | 在线编辑

原始文件为 .py 代码,本文是转换后的 Markdown 文件。

'''
进行颜色矫正,用最小二乘法计算 CCM
'''
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))

import numpy as np
from func.cp_hw2 import read_colorchecker_gm, readHDR, writeHDR

# 该函数用于生成色卡块图,用于检测正确性;同时也顺便生成色卡每个块的平均值
def make_patches(coors, img, onerow=6):
    rows, cols = 24//onerow, onerow

    # patches: 色卡的图,patches_rgb:色卡的平均图(24*3)
    patches = np.zeros((rows*80, cols*80, 3))
    patches_rgb = np.zeros((24, 3))
    for i, coor in enumerate(coors):
        nowpatch = img[coor[1]:coor[3], coor[0]:coor[2]]

        x = (i // onerow) * 80
        y = (i % onerow) * 80
        patches[x:x+80, y:y+80] = nowpatch[0:80, 0:80]
        patches_rgb[i] = np.mean(nowpatch[0:80, 0:80].reshape(-1, 3), axis=0)
    return patches, patches_rgb

coors = []
with open('../data/24color_coor.txt', 'r') as f:
    for i, line in enumerate(f):
        coors.append([int(x) for x in line.split()])

# 保存的色卡坐标,索引有点不对,现在重排一下
coors = np.array(coors).reshape(6, 4, 4).transpose(1, 0, 2).reshape(24, 4)

# 加载基准 RGB
ok_rgb, ok_Lab = read_colorchecker_gm()

# 开始处理各个图片
os.makedirs('../result/stage-2', exist_ok=True)
for filename in os.listdir('../result/stage-1'):
    print(filename)

    hdrimg = readHDR(f'../result/stage-1/{filename}')

    # 先 AWB:提取色卡,只用白色块进行校准,最后一行第一个
    now_patches, patches_rgb = make_patches(coors, hdrimg)
    wr, wg, wb = patches_rgb[3*6+0]

    rgain, bgain = wg / wr, wg / wb
    hdrimg[..., 0] *= rgain
    hdrimg[..., 2] *= bgain


    # 根据coors记录的色卡坐标,生成色卡图,顺便把色卡的各个平均值计算一下
    now_patches, patches_rgb = make_patches(coors, hdrimg)

    # 计算 CCM 矩阵
    # Au = ok_rgb, A->26*4, u->4*3, ok_rgb->26*3
    A = np.hstack((patches_rgb, np.ones((24, 1))))
    u, *_ = np.linalg.lstsq(A, ok_rgb, rcond=None)

    # Make CCM
    rows, cols = hdrimg.shape[0:2]
    hdrimg = np.hstack((hdrimg.reshape(-1, 3), np.ones((rows*cols, 1))))
    hdrimg = np.dot(hdrimg.astype(np.longdouble), u.astype(np.longdouble))

    # ! 很重要:否则会有异色!!!
    hdrimg[hdrimg < 0] = 0
    hdrimg = hdrimg.astype(np.float32).reshape((rows, cols, 3))

    # WriteHDR, Good Job.
    writeHDR(f'../result/stage-2/{filename}', hdrimg)

Comments