이번 포스트에서는 공개된 자료를 이용해, 이전 포스트의 내용을 실제로 계산하며 밝기에 대해서 좀더 구체적인 예시를 들어보겠습니다.
같은 에너지를 발산하고 있는 조명들이 있다고 할때, 에너지가 같다면 밝기 또한 같을까요?
전기에너지 에서 빛 에너지로 변환되는 효율의 차이나, 발열등은 모두 무시하고, 빛의 형태로 방출되는 에너지가 동일한 조명들이 있다고 가정해보겠습니다.
SPD(Spectral power distribution) 을 그리기 쉬운 pc-LED 와, python 에서 라이브러리 형태로 배포되어 관련 자료를 찾을 수 있는, Kinotion_75P, H38HT-100 두 조명을 대상으로 실제 밝기 효율을 계산해보겠습니다.
pc-LED (phosphor-converted LED) 라는 LED 의 한 종류가 있습니다.
백색의 조명원으로 주로 사용되는데요, 이 LED 의 구조는 아레와같이
광원으로 450nm 대의 청색광을 내는 LED 위, 그 빛을 받아 여러 파장의 빛을 방출하는 형광체를 덮은 형태의 LED 입니다.
그 구조가 가지는 특징에 따라서, pc-LED 의 SPD 그래프는 LED 가 발산하는 청색광에서 피크를 가진 뒤,
500~700nm 파장까지 넓은 주파수 대역을 가지는데요,
출처에서 볼 수 있는 그래프의 개형을 보면,
P1 의 상대적으로 뾰족한 값을 가지는 커브와, P2 의 완만한 값을 가지는 커브가 있습니다.
P1 의 값은 원 광원 소스인 blue-LED 에서 나오는 파장이고,
그 뒤 완만한 P2 의 값은 이 빛을 흡수한 이후 형광체에서 다시 나오는 파장이겠군요.
이러한 특성때문에, pc-LED 의 SPD 는 정규분포 함수의 합으로 근사가 가능합니다.
또한, 같은 출처에서 완벽하진 않지만, 해당 그레프를
으로 근사 할 수 있습니다. 이를 통해 합성함수를 만들어보면,
(위 출처의 내용은, 우리가 사용하는 근사식을 개선해 실제의 데이터와 어떻게 가깝게 표현할 수 있는지에 대한 내용입니다.)
wavelengths = np.arange(200, 1300, 5)
# 가우시안을 2개 더한 pc-LED의 SPD 개형
# 출처: https://www.researchgate.net/publication/235522168_Spectral_power_distribution_deconvolution_scheme_for_phosphor-converted_white_light-emitting_diode_using_multiple_Gaussian_functions
centerA = 444
centerB = 558
widthA = 16.5
widthB = 52
spdA = 1.0 * np.exp(-(wavelengths - centerA)**2 / widthA**2)
spdB = 0.54 * np.exp(-(wavelengths - centerB)**2 / widthB**2)
spd = spdA + spdB
plt.plot(wavelengths, spd, label='SPD (interpolated)', color='blue')
다음과 같이 어느정도 사용할 수 있는 그래프를 볼 수 있습니다.
전 포스트에서, SPD 에 시감함수(Photopic curve) 를 곱한 합성함수로, 유효한 밝기를 계산 할 수 있다고 말씀드렸었죠.
다행이 python 에 이를 제공하는 colour
라이브러리가 있습니다. 이를 사용하면,
# 이 함수의 의미는 다음 포스트에서 설명됩니다.
cmf_2deg = colour.MSDS_CMFS['cie_2_1931']
photopic_curve = cmf_2deg.values[:, 1]
original_wv = cmf_2deg.wavelengths
# 정의된 영역보다 좀더 넓은 range 에서 보기 위해 보간.
y_bar_extended = np.zeros_like(wavelengths, dtype=float)
# 360~830 구간에만 interp로 값을 넣어준다.
mask_valid = (wavelengths >= original_wv[0]) & (wavelengths <= original_wv[-1])
wavelengths_valid = wavelengths[mask_valid]
y_bar_extended[mask_valid] = np.interp(
wavelengths_valid,
original_wv,
y_bar
)
plt.plot(wavelengths, y_bar_extended, label='CIE 1931 2° - y_bar', color='red')
다음과 같은 시감함수를 얻을 수 있습니다.
이 둘을 곱한 합성함수로, SPD 로 나타내는 조명의 주파수별 에너지를 실제 체감하는 밝기로 옮길 수 있는데요,
plt.plot(wavelengths, spd, label='SPD (interpolated)', color='blue')
plt.plot(wavelengths, y_bar_extended, label='CIE 1931 2° - y_bar', color='red')
plt.plot(wavelengths, spd * y_bar_extended, label='SPD * CIE 1931 2° - y_bar', color='green')
파랑색 곡선 안의 면적과, 초록색 곡선 안의 면적의 비율은 광원의 조사하는 에너지 대비 인간의 시각이 느끼는 밝기 효율을 의미하게 됩니다.
우리에게는 다행이도, python 에서는 numpy 를 이용해 함수의 면적을 쉽게 구할 수 있습니다.
# 전체 SPD (광원 에너지)의 적분값 (분모)
integral_spd = np.trapezoid(spd, wavelengths)
# 인간 시각 가중치가 적용된 SPD (SPD * y_bar_extended)의 적분값 (분자)
integral_weighted = np.trapezoid(spd * y_bar_extended, wavelengths)
# 두 적분값의 비율: 전체 에너지 중 인지되는 에너지의 비율
ratio = integral_weighted / integral_spd
# 플롯 상에 적분값 및 비율 결과 텍스트 추가
textstr = (
f'Ratio (Weighted / Total): {ratio:.3f}'
)
Colour
라이브러리에서 다양한 조명에 대해 SPD 데이터를 제공하니,
이를 통해 각 조명별 예시를 추가로 계산해 볼 수 있습니다.
# Colour 라이브러리에서 Kinoton 75P SPD 불러오기
light_data_source = colour.colorimetry.datasets.light_sources.sds.DATA_LIGHT_SOURCES_COMMON["Kinoton 75P"]
# Colour 라이브러리에서 Natural SPD 불러오기
light_data_source = colour.colorimetry.datasets.light_sources.sds.DATA_LIGHT_SOURCES_RIT["Natural"]
# Colour 라이브러리에서 H38HT-100 (Mercury) SPD 불러오기
light_data_source = colour.colorimetry.datasets.light_sources.sds.DATA_LIGHT_SOURCES_NIST_PHILIPS["H38HT-100 (Mercury)"]
# SPD의 유효 파장과 값을 추출
spd_wavelengths = np.array(list(light_data_source.keys()))
spd_values = np.array(list(light_data_source.values()))
# SPD 값을 0~1로 정규화: 최대값으로 나눔
spd_values_normalized = spd_values / spd_values.max()
# SPD의 정의된 파장 범위 내에 해당하는 부분만 보간
mask_spd_valid = (wavelengths >= spd_wavelengths.min()) & (wavelengths <= spd_wavelengths.max())
wavelengths_spd_valid = wavelengths[mask_spd_valid]
light_data_valid[mask_spd_valid] = np.interp(
wavelengths_spd_valid,
spd_wavelengths,
spd_values_normalized
)
제가 예시로 삼은 세가지의 조명은,
영화관에서 사용되었던 영사기의 광원과,
실행 가능한 예제
한낮의 야외에서 받을 수 있는 자연광,
과거에는 널리 쓰였던, 수은등을 사용했습니다.
간단한 파이썬 코드로 이 세가지의 다양한 조명들의 특징이 반영된 실제 SPD 데이터의 개형을 보며,
이 데이터들의 차이가 어떤 결과를 나타내느지를 계산해볼 수 있는데요,
아래의 그래프는 차례대로 Kinotion_75p, 자연광, H38HT-100 의 케이스입니다.
계산된 광원당 각 밝기 효율을 보면 주파수 대역이 전 영역에 고르게 분포하는것 보단,
인간의 시각이 민감한 500~550nm 에 집중되어있는것이 중요함을 알 수 있는데요,
그렇기 때문에 같은 조건에서는 해당 영역에서 가장 뾰족한 스파이크를 가진 수은등의 경우가 가장 밝기 효율이 높은것을 알 수 있습니다.
(전기 - 빛 변환등의 조건을 무시한 경우이기 때문에, 조명의 실제 에너지 효율하고는 다릅니다.)
Pesudo 그래프가 아닌, 실제 SPD 데이터인 kinotion_75p, 자연광, h38ht_100 의 경우에는,
638 lumens/W
로 정의된 상수를 이용해, 조명의 밝기를 실제로 계산 할 수도 있겠습니다.
계산 식은
Spd photopic cie curve 683 lumens/W (555nm) 으로 정의되는데요,
단순히 638 lumens/W 를 곱하면 되는 이유는, photopic curve 가 0~1 로 정규화 되어 있으면서,
주파수별 효율이 이미 계산되었기 때문입니다.
# 638 lumens/W (555nm)
print(integral_weighted * 638)
# h38ht-100: 8622.96246513 lumens
# natural: 21616.7073389 lumens
# Kinoton_79P: 49773.3649838 lumens
이번 포스트에서는 실제 예시를 통해 우리가 직관적으로 알 수 있는 밝기 라는 개념이 실제로는 어떤 복잡한 구조로 이루어지는지를 알아보았습니다.
이러한 특성은, 색과 밝기는 정신물리학적 현상(Psychophysical phenomenon)이기 때문입니다
이는 물리학적으로 정의되는 자극과, 이를 인간이 인지하는 지각 형태가 결합되어 나타내는 현상을 의미하는데요,
이러한 현상을 이용하거나, 예측하기 위해선
정신 물리학적 현상을 구성하는 두 요소를 모두 충분히 고려해야만 의도하는 결과를 가져갈 수 있기 때문입니다.
다음 포스트에서는 이제 정말로... 색이란 어떻게 정의할 수 있는가, 이를 '잘' 표현하기 위해선 어떤 기술이 필요한가에 대한 이야기를 진행해보겠습니다.
출처