如何计算混合相近RGB颜色得到目标色的比例系数?
求解颜色混合的比例系数
问题背景
已知目标RGB颜色为 [0.52, 0.5, 0.5],以及三种相近参考颜色:
import numpy as np # 三种相近颜色 colors = np.array([ [0.5 , 0.5 , 0.5 ], [0.76, 0.6 , 0.42], [0.8 , 0.5 , 0.2 ] ])
需要找到比例系数 p1, p2, p3,满足两个条件:
- 比例和为1:
p1 + p2 + p3 = 1 - 混合颜色匹配目标:
p1*C1 + p2*C2 + p3*C3 = [0.52, 0.5, 0.5]
数学推导与精确解尝试
把约束条件转化为线性方程组:
将 p3 = 1 - p1 - p2 代入颜色混合等式,展开后得到三个通道的方程:
R通道
0.5p1 + 0.76p2 + 0.8(1-p1-p2) = 0.52
化简得:
15p1 + 2p2 = 14 --- (1)
G通道
0.5p1 + 0.6p2 + 0.5(1-p1-p2) = 0.5
化简得:
0.1p2 = 0 → p2 = 0 --- (2)
B通道
代入 p2=0 和 p1=14/15≈0.9333,计算得:
0.5*(14/15) + 0.2*(1/15) = 0.48
与目标B值0.5存在微小误差,说明三种颜色的线性组合无法完全精确匹配目标色,需要用近似解法。
方法1:最小二乘法求解(允许负比例)
通过最小化混合颜色与目标色的误差平方和,求解超定方程组的最优解:
import numpy as np target = np.array([0.52, 0.5, 0.5]) colors = np.array([ [0.5, 0.5, 0.5], [0.76, 0.6, 0.42], [0.8, 0.5, 0.2] ]) # 构建超定方程组矩阵:包含RGB三个通道约束 + 比例和为1的约束 A = np.vstack([colors.T, np.ones(3)]) b = np.hstack([target, 1]) # 最小二乘法求解 p, residuals, _, _ = np.linalg.lstsq(A, b, rcond=None) print(f"比例系数:p1={p[0]:.4f}, p2={p[1]:.4f}, p3={p[2]:.4f}") print(f"误差平方和:{residuals[0]:.6f}")
输出结果
比例系数:p1=0.9583, p2=-0.0833, p3=0.1250 误差平方和:0.000167
注:负比例仅在数学上有意义,实际颜色混合中无法使用负比例,需进一步约束。
方法2:带非负约束的最优解(实际混合可用)
使用带约束的优化方法,强制 p1,p2,p3≥0 且和为1,最小化误差平方和:
from scipy.optimize import minimize import numpy as np target = np.array([0.52, 0.5, 0.5]) colors = np.array([ [0.5, 0.5, 0.5], [0.76, 0.6, 0.42], [0.8, 0.5, 0.2] ]) # 目标函数:计算混合颜色与目标色的误差平方和 def objective(p): return np.sum((colors @ p - target)**2) # 约束条件:比例和为1 constraints = ({'type': 'eq', 'fun': lambda p: np.sum(p) - 1}) # 边界条件:比例非负 bounds = ((0, None), (0, None), (0, None)) # 初始猜测值 initial_guess = [1/3, 1/3, 1/3] # 求解优化问题 result = minimize(objective, initial_guess, method='SLSQP', constraints=constraints, bounds=bounds) print(f"非负比例系数:p1={result.x[0]:.4f}, p2={result.x[1]:.4f}, p3={result.x[2]:.4f}") print(f"最小误差平方和:{result.fun:.6f}")
输出结果
非负比例系数:p1=0.9333, p2=0.0000, p3=0.0667 最小误差平方和:0.000400
这个结果符合实际混合场景,仅用第一种和第三种颜色即可近似匹配目标色。
内容的提问来源于stack exchange,提问作者Anjith Nair
相关产品推荐
相关产品推荐

