CCM计算

import os
import cv2
import random
import copy
import numpy as np
import math
import colour
from scipy.optimize import minimize

matXYZ2RGB_sRGB = np.array([
        [3.241, -1.5374, -0.4986],
        [-0.9692, 1.876, 0.0416],
        [0.0556, -0.204, 1.057]])
  
matRGB2XYZ_sRGB = np.array([
    [ 0.4124,  0.3576,  0.1805],
    [ 0.2126,  0.7152,  0.0722],
    [ 0.0193,  0.1192,  0.9505]])

def cal_deltaE(mat, stdRGB, camRGB):
    preRGB = mat @ camRGB
    preXYZ = matRGB2XYZ_sRGB @ preRGB
    stdXYZ = matRGB2XYZ_sRGB @ stdRGB

    prelab = colour.XYZ_to_Lab(preXYZ.T)
    stdlab = colour.XYZ_to_Lab(stdXYZ.T)

    de = colour.delta_E(prelab, stdlab, 'CIE 2000')
    print(de)
    print(np.mean(de), np.max(de))

def myfun(mat, stdRGB, camRGB):
    preRGB = mat.reshape(3, 3) @ camRGB

    preXYZ = matRGB2XYZ_sRGB @ preRGB
    stdXYZ = matRGB2XYZ_sRGB @ stdRGB

    prelab = colour.XYZ_to_Lab(preXYZ.T)
    stdlab = colour.XYZ_to_Lab(stdXYZ.T)

    de = colour.delta_E(prelab, stdlab, 'CIE 2000')
    # print(de)
    # print(np.mean(de), np.max(de))
    return np.mean(de)

def get_adaptation(srcxyz, dstxyz):
    mat = colour.adaptation.CAT_CAT02

    srclms= np.matmul(mat, srcxyz)
    dstlms = np.matmul(mat, dstxyz)

    gainmat = np.zeros((3, 3), np.float32)
    gainmat[0, 0] = dstlms[0] / srclms[0]
    gainmat[1, 1] = dstlms[1] / srclms[1]
    gainmat[2, 2] = dstlms[2] / srclms[2]

    matinv = np.linalg.inv(mat)
    camat = matinv @ gainmat @ mat
    return camat

def cal_stdXYZ_camRGB_color24():
    illum = colour.SDS_ILLUMINANTS['D65']
    cmfs = colour.MSDS_CMFS['cie_2_1931']
    colorchecker = colour.SDS_COLOURCHECKERS['ColorChecker N Ohta']
    camera_sensitivities = colour.MSDS_CAMERA_SENSITIVITIES['Nikon 5100 (NPL)']
    stdXYZ = np.zeros((24, 3), np.float)
    camRGB = np.zeros((24, 3), np.float)
    n=0
    for k, v in colorchecker.items():
        # print(k)
        stdXYZ[n, :] = colour.sd_to_XYZ(colorchecker[k], cmfs, illum)
        camRGB[n, :] = colour.sd_to_XYZ(colorchecker[k], camera_sensitivities, illum)
        n=n+1

    stdXYZ = stdXYZ / stdXYZ[18, 1]
    # print(stdXYZ[18,:])
    dstxyz_wp = np.array([0.95050874, 1, 1.08847814])
    camat = get_adaptation(stdXYZ[18, :], dstxyz_wp)
    # print(camat)
    stdXYZ = (camat @ stdXYZ.T).T

    camRGB = camRGB / camRGB[18, 1]
    camRGB = camRGB / camRGB[18, :]  # awb
    # print(stdXYZ[18,:])
    # print(camRGB)

    return stdXYZ, camRGB

def cal_ccm_color24_new():
    stdXYZ, camRGB = cal_stdXYZ_camRGB_color24()
    stdRGB = matXYZ2RGB_sRGB @ stdXYZ.T
    camRGB = camRGB.T
    matA = stdRGB - camRGB[2, :]
    matB = camRGB - camRGB[2, :]
    matB = matB[0:2, :]
    mat = (matA @ matB.T) @ np.linalg.inv(matB @ matB.T)
    matout = np.zeros((3, 3), float)
    matout[:, 0:2] = mat
    matout[:, 2] = 1 - matout[:, 0] - matout[:, 1]
    print(matout)
    cal_deltaE(matout, stdRGB, camRGB)

def cal_ccm():
    stdXYZ, camRGB = cal_stdXYZ_camRGB_color24()
    stdRGB = matXYZ2RGB_sRGB @ stdXYZ.T
    camRGB = camRGB.T
    mat = np.zeros((3, 3), float)
    mat[0, 0] = 1.0
    mat[1, 1] = 1.0
    mat[2, 2] = 1.0
    lowd = -0.5
    highd = 0.5
    cons = (
        {'type': 'eq', 'fun': lambda x: x[0] + x[1] + x[2] - 1},
        {'type': 'eq', 'fun': lambda x: x[3] + x[4] + x[5] - 1},
        {'type': 'eq', 'fun': lambda x: x[6] + x[7] + x[8] - 1},
        {'type': 'ineq', 'fun': lambda x: x[1:4] - lowd},
        {'type': 'ineq', 'fun': lambda x: highd - x[1:4]},
        {'type': 'ineq', 'fun': lambda x: x[5:8] - lowd},
        {'type': 'ineq', 'fun': lambda x: highd - x[5:8]},
    )
    res = minimize(myfun, mat.reshape(9,), args=(stdRGB, camRGB),  method='SLSQP', constraints=cons)
    print(res.fun)
    print(res.success)
    matout = res.x.reshape(3,3)
    print(matout)
    cal_deltaE(matout, stdRGB, camRGB)



if __name__ == "__main__":
    # cal_stdXYZ_camRGB_color24()
    cal_ccm_color24_new()
    cal_ccm()
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值