简体   繁体   English

色彩混合的插值方法好吗?

[英]Good interpolation method for color mixing?

This question addresses in particular the question of curve fitting in the context of color mixing of paints, pigments, etc. 该问题尤其解决了在油漆,颜料等的颜色混合中曲线拟合的问题。

I am trying to guess the required proportions of two paints, let's say "Brown" (B) and "white" (W) to get to a given lightness value L. 我试图猜测两种涂料的比例,比如说“棕色”(B)和“白色”(W),以达到给定的亮度值L。

I have made a "calibration curve" in the same fashion as one does so for applying the Beer-lambert law in chemistry. 我已经按照将比尔-朗伯定律应用到化学中的方式制作了“校准曲线”。 However, the curve is not linear so I cannot use the Beer-Lambert law. 但是,曲线不是线性的,所以我不能使用比尔-朗伯定律。

Here's what I've done : 这是我所做的:

(1) (1)

  • I have measured the spectrum of paint samples for these proportions of mixture, labeled a, b, c, d, ... etc. 我已经测量了这些比例的混合物(标为a,b,c,d等)的油漆样品的光谱。

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

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

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

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

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

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

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

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

And these are the spectral reflectance curves that I got : 这些是我得到的光谱反射率曲线:

反射率曲线

If I pick-up one reflectance value at a given wavelength, eg 500 nm, I get this nice curve, where the x axis represents the proportion of white paint in the mix, and the y axis the reflected light at 500 nm : 如果我在给定的波长(例如500 nm)下获得一个反射率值,则会得到一条漂亮的曲线,其中x轴代表混合物中白色涂料的比例,y轴代表500 nm处的反射光: 500 nm处白色VS反射率的量

I'd like to guess by interpolation how much white I need to arrive at a certain amount of reflected light. 我想通过内插法猜测达到一定数量的反射光需要多少白色。

(2) (2)

I have tried to fit an exponential curve to the data with scipy.optimize.curve_fit but the fit is pretty poor: 我试图用scipy.optimize.curve_fit将指数曲线拟合到数据,但拟合度很差:

数据的指数拟合

What kind of function would fit the data closely? 什么样的功能可以非常适合数据?

I'll expand my comment since nobody has answered. 由于没有人回答,我将扩大我的评论。

From what I see in the figure, there is a pattern. 根据我在图中看到的,有一个模式。 The best way would be to fit a curve that fits that pattern as a whole. 最好的方法是使一条曲线适合整个模式。 You can do this without any math using Eureqa (the free trial should be enough): http://www.nutonian.com/products/eureqa/ 您可以使用Eureqa进行任何数学运算(免费试用就足够了): http ://www.nutonian.com/products/eureqa/

If you want to remain in python and fit an exponential distribution, you can do the following: How to do exponential and logarithmic curve fitting in Python? 如果要保留在python中并拟合指数分布,可以执行以下操作: 如何在Python中进行指数和对数曲线拟合? I found only polynomial fitting 我发现只有多项式拟合

So imagine you have for the wavelength 500nm the following values: 因此,假设您对于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]

Then the code to fit the exponential curve would be: 然后,适合指数曲线的代码将是:

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)

In this case we get that a,b, and c are: 在这种情况下,我们得出a,b和c为:

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

So to get the value of reflected light at a certain x (for instance 0.2), you can do: 因此,要获得特定x处反射光的值(例如0.2),可以执行以下操作:

func(0.2, 7.1907744 , -2.62804994,  2.45029842)

Which is 14.61 等于14.61

But you say it's a bad fit, if you don't need a model, you can do the following: If you don't really care about having a model you can use this: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html#scipy.interpolate.interp1d 但是您说这很不合适,如果不需要模型,则可以执行以下操作:如果您真的不关心模型,可以使用此方法: https : //docs.scipy.org/doc / scipy / reference /生成/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

And then to find a value (for instance x=0.2): 然后找到一个值(例如x = 0.2):

ynew = f(0.2)

Which is 6.549 那是6.549

Or to have many values so you can plot them: ynew = f(np.linspace(0,1,1000) 或者具有许多值,以便可以对其进行绘制:ynew = f(np.linspace(0,1,1000)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM