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()
CCM计算
最新推荐文章于 2024-06-07 10:49:04 发布