混色的好插值方法?

Posted

技术标签:

【中文标题】混色的好插值方法?【英文标题】:Good interpolation method for color mixing? 【发布时间】:2017-01-23 09:25:49 【问题描述】:

这个问题特别解决了油漆、颜料等颜色混合背景下的曲线拟合问题。

我试图猜测两种颜料所需的比例,比如说“棕色”(B)和“白色”(W),以获得给定的亮度值 L。

我以与在化学中应用比尔-朗伯定律相同的方式制作了“校准曲线”。但是,曲线不是线性的,所以我不能使用 Beer-Lambert 定律。

这是我所做的:

(1)

我已经测量了这些混合物比例的油漆样品的光谱,标记为 a、b、c、d 等。

a >>> W = 1,B = 0(纯白)

b >>> W = 63/64,B = 1/64

c >>> W = 31/32,B = 1/32

d >>> W = 15/16,B = 1/16

e >>> W = 7/8,B = 1/8

f >>> W = 3/4,B = 1/4

g >>> W = 1/2,B = 1/2

h >>> W = 0,B = 1(纯棕色)

这些是我得到的光谱反射曲线:

如果我在给定波长处获得一个反射率值,例如500 nm,我得到了这条漂亮的曲线,其中 x 轴代表混合物中白色涂料的比例,y 轴代表 500 nm 处的反射光:

我想通过插值来猜测我需要多少白色才能达到一定的反射光量。

(2)

我尝试使用scipy.optimize.curve_fit 为数据拟合指数曲线,但拟合效果很差:

什么样的函数可以紧密拟合数据?

【问题讨论】:

我会拟合指数曲线:***.com/questions/3433486/… @Javier 你能帮我理解如何将它拟合到指数曲线,我不确定我是否理解如何去做...... Use of curve_fit to fit data的可能重复 请记住,您希望过渡在感知上是一致的,而不是在数学上一致:这里有点讨论:matplotlib.org/users/colormaps.html;颜色之间的变化率在 LAB 空间(而不是 RGB/HSV 空间)中应该是恒定的。另请参阅:github.com/matplotlib/viscm、matplotlib.org/cmocean 和 wiki.seg.org/wiki/How_to_evaluate_and_compare_color_maps。 @Benjamin 当然!我知道,谢谢!这正是我需要一个好的插值方法的原因......几何级数(1:1、3:1、7:1、15:1,......等)通常是第一次拍摄的一个很好的近似方法,并且它为测量 Lab* 值提供了良好的基础。 ;) 【参考方案1】:

由于没有人回答,我将扩展我的评论。

从我在图中看到的,有一个模式。最好的方法是拟合一条适合整个模式的曲线。使用 Eureqa 无需任何数学运算即可完成此操作(免费试用就足够了):http://www.nutonian.com/products/eureqa/

如果您想留在 python 中并拟合指数分布,您可以执行以下操作: How to do exponential and logarithmic curve fitting in Python? I found only polynomial fitting

所以想象一下,对于 500nm 波长,您有以下值:

y = [10,20,30,30,50,60,70,80,90,100]
x = [0.,0.3,0.5,0.6,0.72,0.77,0.84,0.9,0.95,1]

那么拟合指数曲线的代码是:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def func(x, a, b, c):
    return a * np.exp(-b * x) + c

popt, pcov = curve_fit(func, x, y)

在这种情况下,我们得到 a、b 和 c 是:

popt = array([ 7.1907744 , -2.62804994,  2.45029842])

所以要获得某个 x 处的反射光值(例如 0.2),您可以这样做:

func(0.2, 7.1907744 , -2.62804994,  2.45029842)

14.61

但是你说它不合适,如果你不需要模型,你可以这样做:如果你真的不关心有一个模型你可以使用这个:https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html#scipy.interpolate.interp1d

from scipy import interpolate
f = interpolate.interp1d(x, y, kind="quadratic") #you can try different kinds of interpolation

然后找到一个值(例如 x=0.2):

ynew = f(0.2)

6.549

或者有很多值,所以你可以绘制它们: ynew = f(np.linspace(0,1,1000)

【讨论】:

抱歉,我没有选中您的答案,因为指数拟合给出的数据近似值非常差。有什么建议吗? 我做了这个解决方案,但我不确定它是否聪明:***.com/questions/41856164/…

以上是关于混色的好插值方法?的主要内容,如果未能解决你的问题,请参考以下文章

两条曲线之间的二维插值(长度不等的数组)

Pandas 使用日期时间索引重新排列和插值时间序列

第一章:插值方法

三种插值方法的比较

拉格朗日插值方法

《数值分析》-- 插值方法中基础名词概念解释