1、CCM矩阵的作用是矫正整张图片的色彩表现,利用现象变换使图片的表现更接近理想状态。使用测试机在标准光源环境下拍摄24色卡,获取24个色块的三通道均值,矫正过程如下:
⎣⎡A00A10A20A01A11A21A02A12A22⎦⎤∗⎣⎡RGB⎦⎤=⎣⎡R′G′B′⎦⎤

2、收集调试机和target图片的24色卡数据,取前18个色块进行计算,针对R分量矫正误差如下:
err=i=0∑17(RiA00+GiA01+BiA02−Ri′)2
问题就变成了在约束条件:A00+A01+A02=1下求上式的极值点,构建拉格朗日函数:
L=i=0∑17(RiA00+GiA01+BiA02−Ri′)2+λ(A00+A01+A02−1)
于是对四个未知数求偏导数:
∂A00∂L=i=0∑17(2Ri2A00+2GiRiA01+2BiRiA02−2RiRi′)+λ=0
∂A01∂L=i=0∑17(2RiGiA00+2Gi2A01+2BiGiA02−2GiRi′)+λ=0
∂A02∂L=i=0∑17(2RiBiA00+2GiBiA01+2Bi2A02−2BiRi′)+λ=0
∂λ∂L=A00+A01+A02=1
对应的矩阵方程为:
i=0∑17⎣⎡Ri2RiGiRiBi1GiRiGi2GiBi1BiRiBiGiBi210.50.50.50⎦⎤⎣⎡A00A01A02λ⎦⎤=i=0∑17⎣⎡RiRi′GiRi′BiRi′1⎦⎤
由克莱姆法则可知方程的解如下:
A00=i=0∑17∣∣Ri2RiGiRiBi1GiRiGi2GiBi1BiRiBiGiBi210.50.50.50∣∣i=0∑17∣∣RiRi′GiRi′BiRi′1GiRiGi2GiBi1BiRiBiGiBi210.50.50.50∣∣
A01=i=0∑17∣∣Ri2RiGiRiBi1GiRiGi2GiBi1BiRiBiGiBi210.50.50.50∣∣i=0∑17∣∣Ri2RiGiRiBi1RiRi′GiRi′BiRi′1BiRiBiGiBi210.50.50.50∣∣
A02=i=0∑17∣∣Ri2RiGiRiBi1GiRiGi2GiBi1BiRiBiGiBi210.50.50.50∣∣i=0∑17∣∣Ri2RiGiRiBi1GiRiGi2GiBi1RiRi′GiRi′BiRi′10.50.50.50∣∣
3、同理可以求出:[A10A11A12][A20A21A22]
4、代码实现如下:
workBook = xlrd.open_workbook( 'D:/develop_simulate_tool/CCM.xls' )
allSheetNames = workBook.sheet_names()
sheet1_content1 = workBook.sheet_by_name( 'original' )
sheet1_content2 = workBook.sheet_by_name( 'target' )
original = np.zeros((24, 3), np.float)
target = np.zeros((24, 3), np.float)
for i in range(sheet1_content1.nrows):
for j in range(sheet1_content1.ncols):
original[i, j] = sheet1_content1.cell_value(i, j)
target[i, j] = sheet1_content2.cell_value(i, j)
result = np.zeros((3, 3), np.float)
for m in range(3):
coe = np.zeros((4, 4), np.float)
coe_x = np.zeros((4, 4), np.float)
coe_y = np.zeros((4, 4), np.float)
coe_z = np.zeros((4, 4), np.float)
for i in range(sheet1_content1.nrows * 3 // 4):
coe[0, 0] = coe[0, 0] + sheet1_content1.cell_value(i, 0) * sheet1_content1.cell_value(i, 0)
coe[0, 1] = coe[0, 1] + sheet1_content1.cell_value(i, 0) * sheet1_content1.cell_value(i, 1)
coe[0, 2] = coe[0, 2] + sheet1_content1.cell_value(i, 0) * sheet1_content1.cell_value(i, 2)
coe[1, 1] = coe[1, 1] + sheet1_content1.cell_value(i, 1) * sheet1_content1.cell_value(i, 1)
coe[1, 2] = coe[1, 2] + sheet1_content1.cell_value(i, 1) * sheet1_content1.cell_value(i, 2)
coe[2, 2] = coe[2, 2] + sheet1_content1.cell_value(i, 2) * sheet1_content1.cell_value(i, 2)
coe[1, 0] = coe[1, 0] + sheet1_content1.cell_value(i, 0) * sheet1_content2.cell_value(i, m)
coe[2, 0] = coe[2, 0] + sheet1_content1.cell_value(i, 1) * sheet1_content2.cell_value(i, m)
coe[2, 1] = coe[2, 1] + sheet1_content1.cell_value(i, 2) * sheet1_content2.cell_value(i, m)
rr = coe[1, 0]
gr = coe[2, 0]
br = coe[2, 1]
coe[0, 3] = 0.5
coe[1, 0] = coe[0, 1]
coe[1, 3] = 0.5
coe[2, 0] = coe[0, 2]
coe[2, 1] = coe[1, 2]
coe[2, 3] = 0.5
coe[3, 0] = 1
coe[3, 1] = 1
coe[3, 2] = 1
coe_x = copy.deepcopy(coe)
coe_x[0, 0] = rr
coe_x[1, 0] = gr
coe_x[2, 0] = br
coe_y = copy.deepcopy(coe)
coe_y[0, 1] = rr
coe_y[1, 1] = gr
coe_y[2, 1] = br
coe_z = copy.deepcopy(coe)
coe_z[0, 2] = rr
coe_z[1, 2] = gr
coe_z[2, 2] = br
result[m, 0] = np.linalg.det(coe_x) / np.linalg.det(coe)
result[m, 1] = np.linalg.det(coe_y) / np.linalg.det(coe)
result[m, 2] = np.linalg.det(coe_z) / np.linalg.det(coe)
5、运行结果如下:
