我有一个函数“xy_from_Temperature”,它应该根据光谱功率分布计算 XYZ 颜色坐标。然而,无论我放入什么温度,它总是输出
[1] 0.2398770 0.2340373
我的代码是
xy_from_Temperature <- function (Temperature){
X_vector <- c()
Y_vector <- c()
Z_vector <- c()
repetition_counter <- 1
wavelength_counter <- 360
for (i in 360:830){
X <- Color_Matching_Function[,2][repetition_counter]
Y <- Color_Matching_Function[,3][repetition_counter]
Z <- Color_Matching_Function[,4][repetition_counter]
Spectral_Radiance <- Spectral_Radiant_Exitance (wavelength_counter, Temperature)
X <- X * Spectral_Radiance
Y <- Y * Spectral_Radiance
Z <- Z * Spectral_Radiance
X_vector <- c(X_vector, X)
Y_vector <- c(Y_vector, Y)
Z_vector <- c(Z_vector, Z)
repetition_counter <- repetition_counter + 1
wavelength_counter <- wavelength_counter + 1
}
sum_X <- sum(X_vector)
sum_Y <- sum(Y_vector)
sum_Z <- sum(Z_vector)
XYZ <- c(sum_X, sum_Y, sum_Z)
xy <- XYZ_to_xy(XYZ)
return (xy)
}
Spectral_Radiant_Exitance 是一个函数,它采用波长(以纳米为单位)和温度(以开尔文为单位)并输出光谱辐射出射度(如此处所述)。 XYZ_to_xy 是一个函数,它采用 XYZ 颜色坐标向量并输出 xy 颜色坐标向量(也如此处所述)。
Color_Matching_Function 是 xyz 颜色空间的 CIE 1931 2 度颜色匹配函数的数据帧,我从文件中复制粘贴在此页面上。
我基于“xy_from_Temperature”我在此网页中找到的方程。
我尝试输入各种温度,例如10、2000和40000,但它总是输出相同的结果。它应该在 上输出结果。
所以如果我输入 4000,我应该得到
[1] 0.38 0.38
(大约),如果我输入 10000,我应该得到
[1] 0.53 0.42
(也大约)。我真的不知道我做错了什么。任何帮助将不胜感激!
编辑: Spectral_Radiant_Exitance 定义为
Spectral_Radiant_Exitance <- function (wavelength, temperature){
M <- 1 / (wavelength^5 * ((exp(c2 / (wavelength * temperature))) - 1))
return (M)
}
其中 c2 为 0.01438786。
我能够复制您的问题,并且可以查明问题出在哪里(
XYZ_to_xy()
)。但我无法提供修复它的解决方案,因为我对此的领域知识为零。
从广义上讲,您的代码没有利用 R 的矢量化能力。您根本不需要执行 for 循环,只需对
Color_Matching_Function
数据框进行矢量化即可。以下代码将您的代码压缩为更加紧凑、可读的形式:
library(tidyverse)
Color_Matching_Function <- read_csv("CIE_xyz_1931_2deg.csv", col_names = FALSE) |>
rename(wavelength = X1, x_bar = X2, y_bar = X3, z_bar = X4)
Spectral_Radiant_Exitance <- function(wavelength, temperature){
1 / (wavelength^5 * ((exp(0.01438786 / (wavelength * temperature))) - 1))
}
XYZ_to_xy <- function(x, y, z) {
x_t <- x / (x + y + z)
y_t <- y / (x + y + z)
list(x_t, y_t)
}
calculate_radiance <- function(Temperature, Color_Matching = Color_Matching_Function) {
Color_Matching |>
mutate(Spectral_Radiance = Spectral_Radiant_Exitance(wavelength, Temperature),
across(x_bar:z_bar, ~ .x * Spectral_Radiance, .names = "{col}_Radiance")) |>
summarize(across(x_bar_Radiance:z_bar_Radiance, sum))
}
res <- calculate_radiance(4000)
res
# A tibble: 1 × 3
x_bar_Radiance y_bar_Radiance z_bar_Radiance
<dbl> <dbl> <dbl>
1 0.000328 0.000320 0.000718
res2 <- calculate_radiance(10000)
res2
# A tibble: 1 × 3
x_bar_Radiance y_bar_Radiance z_bar_Radiance
<dbl> <dbl> <dbl>
1 0.000819 0.000799 0.00180
我不能说这些值是否正确,但它们肯定是不同的。
但是,无论应用于
Temperature
的值如何,以下内容都会得到与您提到的相同的结果。
XYZ_to_xy(res$x_bar_Radiance, res$y_bar_Radiance, res$z_bar_Radiance)
XYZ_to_xy(res2$x_bar_Radiance, res2$y_bar_Radiance, res2$z_bar_Radiance)
双双回归
[[1]]
[1] 0.239877
[[2]]
[1] 0.2340373
这指出了我对如何定义
XYZ_to_xy()
的误解,我也假设你也是这样。恐怕我无法进一步帮助你。