为什么我的函数总是返回相同的值?

问题描述 投票:0回答:1

我有一个函数“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,但它总是输出相同的结果。它应该在 Planckian locus 上输出结果。

所以如果我输入 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。

r function loops colors
1个回答
0
投票

我能够复制您的问题,并且可以查明问题出在哪里(

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()
的误解,我也假设你也是这样。恐怕我无法进一步帮助你。

© www.soinside.com 2019 - 2024. All rights reserved.