图像处理: 可见光波长(wavelength)与RGB之间的转换

2024-03-15 22:58

本文主要是介绍图像处理: 可见光波长(wavelength)与RGB之间的转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于颜色转换,有时间看标准当然最好,不过我手头一时没有相关标准,所以参考了一些网上的资料,

380nm 到 760nm的可见光 对应的RGB大概是这个样子的,

C语言版本程序,

//指定波长转换成RGBA颜色
std::vector<int> lambdaToColor(double lambda,double gamma = 0.8,double intensityMax = 255.0)
{double r, g, b, alpha;if (lambda >= 380.0 && lambda < 440.0) {r = -1.0 * (lambda - 440.0) / (440.0 - 380.0);g = 0.0;b = 1.0;}else if (lambda >= 440.0 && lambda < 490.0) {r = 0.0;g = (lambda - 440.0) / (490.0 - 440.0);b = 1.0;}else if (lambda >= 490.0 && lambda < 510.0) {r = 0.0;g = 1.0;b = -1.0 * (lambda - 510.0) / (510.0 - 490.0);}else if (lambda >= 510.0 && lambda < 580.0) {r = (lambda - 510.0) / (580.0 - 510.0);g = 1.0;b = 0.0;}else if (lambda >= 580.0 && lambda < 645.0) {r = 1.0;g = -1.0 * (lambda - 645.0) / (645.0 - 580.0);b = 0.0;}else if (lambda >= 645.0 && lambda <= 780.0) {r = 1.0;g = 0.0;b = 0.0;}else {r = 0.0;g = 0.0;b = 0.0;}//在可见光谱的边缘处强度较低。if (lambda >= 380.0 && lambda < 420.0) {alpha = 0.30 + 0.70 * (lambda - 380.0) / (420.0 - 380.0);}else if (lambda >= 420.0 && lambda < 701.0) {alpha = 1.0;}else if (lambda >= 701.0 && lambda < 780.0) {alpha = 0.30 + 0.70 * (780.0 - lambda) / (780.0 - 700.0);}else {alpha = 0.0;}//1953年在引入NTSC电视时,计算具有荧光体的监视器的亮度公式如下int Y = static_cast<int>(0.212671*r + 0.715160*g + 0.072169*b);//伽马射线 gamma//照明强度 intensityMaxint R = r == 0.0 ? 0 : static_cast<int>(std::round(intensityMax * std::pow(r * alpha, gamma)));int G = g == 0.0 ? 0 : static_cast<int>(std::round(intensityMax * std::pow(g * alpha, gamma)));int B = b == 0.0 ? 0 : static_cast<int>(std::round(intensityMax * std::pow(b * alpha, gamma)));int A = static_cast<int>(alpha);return std::vector<int>{R, G, B, A, Y};
}

另一个转换是通过建立一个事先计算好的表来计算的,这个还没细看,不过感觉通过建立查找表,牺牲一点点空间,可以极大减少运算量,这也是高速程序的一般处理方式。

static class RgbCalculator {const intLEN_MIN = 380,LEN_MAX = 780,LEN_STEP = 5;static readonly double[]X = {0.000160, 0.000662, 0.002362, 0.007242, 0.019110, 0.043400, 0.084736, 0.140638, 0.204492, 0.264737,0.314679, 0.357719, 0.383734, 0.386726, 0.370702, 0.342957, 0.302273, 0.254085, 0.195618, 0.132349,0.080507, 0.041072, 0.016172, 0.005132, 0.003816, 0.015444, 0.037465, 0.071358, 0.117749, 0.172953,0.236491, 0.304213, 0.376772, 0.451584, 0.529826, 0.616053, 0.705224, 0.793832, 0.878655, 0.951162,1.014160, 1.074300, 1.118520, 1.134300, 1.123990, 1.089100, 1.030480, 0.950740, 0.856297, 0.754930,0.647467, 0.535110, 0.431567, 0.343690, 0.268329, 0.204300, 0.152568, 0.112210, 0.081261, 0.057930,0.040851, 0.028623, 0.019941, 0.013842, 0.009577, 0.006605, 0.004553, 0.003145, 0.002175, 0.001506,0.001045, 0.000727, 0.000508, 0.000356, 0.000251, 0.000178, 0.000126, 0.000090, 0.000065, 0.000046,0.000033},Y = {0.000017, 0.000072, 0.000253, 0.000769, 0.002004, 0.004509, 0.008756, 0.014456, 0.021391, 0.029497,0.038676, 0.049602, 0.062077, 0.074704, 0.089456, 0.106256, 0.128201, 0.152761, 0.185190, 0.219940,0.253589, 0.297665, 0.339133, 0.395379, 0.460777, 0.531360, 0.606741, 0.685660, 0.761757, 0.823330,0.875211, 0.923810, 0.961988, 0.982200, 0.991761, 0.999110, 0.997340, 0.982380, 0.955552, 0.915175,0.868934, 0.825623, 0.777405, 0.720353, 0.658341, 0.593878, 0.527963, 0.461834, 0.398057, 0.339554,0.283493, 0.228254, 0.179828, 0.140211, 0.107633, 0.081187, 0.060281, 0.044096, 0.031800, 0.022602,0.015905, 0.011130, 0.007749, 0.005375, 0.003718, 0.002565, 0.001768, 0.001222, 0.000846, 0.000586,0.000407, 0.000284, 0.000199, 0.000140, 0.000098, 0.000070, 0.000050, 0.000036, 0.000025, 0.000018,0.000013},Z = {0.000705, 0.002928, 0.010482, 0.032344, 0.086011, 0.197120, 0.389366, 0.656760, 0.972542, 1.282500,1.553480, 1.798500, 1.967280, 2.027300, 1.994800, 1.900700, 1.745370, 1.554900, 1.317560, 1.030200,0.772125, 0.570060, 0.415254, 0.302356, 0.218502, 0.159249, 0.112044, 0.082248, 0.060709, 0.043050,0.030451, 0.020584, 0.013676, 0.007918, 0.003988, 0.001091, 0.000000, 0.000000, 0.000000, 0.000000,0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,0.000000};static readonly double[]MATRIX_SRGB_D65 = {3.2404542, -1.5371385, -0.4985314,-0.9692660,  1.8760108,  0.0415560,0.0556434, -0.2040259,  1.0572252};public static byte[] Calc(double len) {if(len < LEN_MIN || len > LEN_MAX)return new byte[3];len -= LEN_MIN;var index = (int)Math.Floor(len / LEN_STEP);var offset = len - LEN_STEP * index;var x = Interpolate(X, index, offset);var y = Interpolate(Y, index, offset);var z = Interpolate(Z, index, offset);var m = MATRIX_SRGB_D65;var r = m[0] * x + m[1] * y + m[2] * z;var g = m[3] * x + m[4] * y + m[5] * z;var b = m[6] * x + m[7] * y + m[8] * z;r = Clip(GammaCorrect_sRGB(r));g = Clip(GammaCorrect_sRGB(g));b = Clip(GammaCorrect_sRGB(b));return new[] { (byte)(255 * r),(byte)(255 * g),(byte)(255 * b)};}static double Interpolate(double[] values, int index, double offset) {if(offset == 0)return values[index];var x0 = index * LEN_STEP;var x1 = x0 + LEN_STEP;var y0 = values[index];var y1 = values[1 + index];return y0 + offset * (y1 - y0) / (x1 - x0);}static double GammaCorrect_sRGB(double c) {if(c <= 0.0031308)return 12.92 * c;var a = 0.055;return (1 + a) * Math.Pow(c, 1 / 2.4) - a;}static double Clip(double c) {if(c < 0)return 0;if(c > 1)return 1;return c;}
}

另外有一个python版本在这里,暂时用不到,挂个号在这里吧

#!/usr/bin/env python
# vim:set ft=python fileencoding=utf-8 sr et ts=4 sw=4 : See help 'modeline''''== A few notes about color ==Color   Wavelength(nm) Frequency(THz)Red     620-750        484-400Orange  590-620        508-484Yellow  570-590        526-508Green   495-570        606-526Blue    450-495        668-606Violet  380-450        789-668f is frequency (cycles per second)l (lambda) is wavelength (meters per cycle)e is energy (Joules)h (Plank's constant) = 6.6260695729 x 10^-34 Joule*seconds= 6.6260695729 x 10^-34 m^2*kg/secondsc = 299792458 meters per secondf = c/ll = c/fe = h*fe = c*h/lList of peak frequency responses for each type of photoreceptor cell in the human eye:S cone: 437 nmM cone: 533 nmL cone: 564 nmrod:    550 nm in bright daylight, 498 nm when dark adapted. Rods adapt to low light conditions by becoming more sensitive.Peak frequency response shifts to 498 nm.'''import sys
import os
import traceback
import optparse
import time
import loggingdef wavelength_to_rgb(wavelength, gamma=0.8):'''This converts a given wavelength of light to an approximate RGB color value. The wavelength must be givenin nanometers in the range from 380 nm through 750 nm(789 THz through 400 THz).Based on code by Dan Brutonhttp://www.physics.sfasu.edu/astro/color/spectra.html'''wavelength = float(wavelength)if wavelength >= 380 and wavelength <= 440:attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)R = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gammaG = 0.0B = (1.0 * attenuation) ** gammaelif wavelength >= 440 and wavelength <= 490:R = 0.0G = ((wavelength - 440) / (490 - 440)) ** gammaB = 1.0elif wavelength >= 490 and wavelength <= 510:R = 0.0G = 1.0B = (-(wavelength - 510) / (510 - 490)) ** gammaelif wavelength >= 510 and wavelength <= 580:R = ((wavelength - 510) / (580 - 510)) ** gammaG = 1.0B = 0.0elif wavelength >= 580 and wavelength <= 645:R = 1.0G = (-(wavelength - 645) / (645 - 580)) ** gammaB = 0.0elif wavelength >= 645 and wavelength <= 750:attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)R = (1.0 * attenuation) ** gammaG = 0.0B = 0.0else:R = 0.0G = 0.0B = 0.0R *= 255G *= 255B *= 255return (int(R), int(G), int(B))def main(options=None, args=None):#    import ppm_dump
#    import png_canvasimport canvasif options.ppm:canvas = canvas.ppm_canvas(371, 278)canvas.is_ascii = Trueelse:canvas = canvas.png_canvas(371, 278)for wl in range(380, 751):r, g, b = wavelength_to_rgb(wl)for yy in range(0, 278):canvas.pixel(wl - 380, yy, r, g, b)sys.stdout.write(str(canvas))if __name__ == '__main__':try:start_time = time.time()parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(),usage=globals()['__doc__'],version='1')parser.add_option('-v', '--verbose', action='store_true',default=False, help='verbose output')parser.add_option('--png', action='store_true',default=True, help='Output as PNG.')parser.add_option('--ppm', action='store_true',default=False, help='Output as PPM ASCII (Portable Pixmap).')(options, args) = parser.parse_args()#if len(args) < 1:#    parser.error ('missing argument')if options.verbose:print(time.asctime())exit_code = main(options, args)if exit_code is None:exit_code = 0if options.verbose:print(time.asctime())print('TOTAL TIME IN MINUTES: %f'% ((time.time() - start_time) / 60.0))sys.exit(exit_code)except KeyboardInterrupt as e:  # The user pressed Ctrl-C.raise eexcept SystemExit as e:  # The script called sys.exit() somewhere.raise eexcept Exception as e:print('ERROR: Unexpected Exception')print(str(e))traceback.print_exc()os._exit(2)

【1】 https://stackoverflow.com/questions/1472514/convert-light-frequency-to-rgb

【2】http://www.noah.org/wiki/Wavelength_to_RGB_in_Python

 

这篇关于图像处理: 可见光波长(wavelength)与RGB之间的转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/813534

相关文章

Java实现字符串大小写转换的常用方法

《Java实现字符串大小写转换的常用方法》在Java中,字符串大小写转换是文本处理的核心操作之一,Java提供了多种灵活的方式来实现大小写转换,适用于不同场景和需求,本文将全面解析大小写转换的各种方法... 目录前言核心转换方法1.String类的基础方法2. 考虑区域设置的转换3. 字符级别的转换高级转换

Python轻松实现Word到Markdown的转换

《Python轻松实现Word到Markdown的转换》在文档管理、内容发布等场景中,将Word转换为Markdown格式是常见需求,本文将介绍如何使用FreeSpire.DocforPython实现... 目录一、工具简介二、核心转换实现1. 基础单文件转换2. 批量转换Word文件三、工具特性分析优点局

使用C#实现将RTF转换为PDF

《使用C#实现将RTF转换为PDF》RTF(RichTextFormat)是一种通用的文档格式,允许用户在不同的文字处理软件中保存和交换格式化文本,下面我们就来看看如何使用C#实现将RTF转换为PDF... 目录Spire.Doc for .NET 简介安装 Spire.Doc代码示例处理异常总结RTF(R

OFD格式文件及如何适应Python将PDF转换为OFD格式文件

《OFD格式文件及如何适应Python将PDF转换为OFD格式文件》OFD是中国自主研发的一种固定版式文档格式,主要用于电子公文、档案管理等领域,:本文主要介绍OFD格式文件及如何适应Python... 目录前言什么是OFD格式文档?使用python easyofd库将PDF转换为OFD第一步:安装 eas

基于Java实现PPT到PDF的高效转换详解

《基于Java实现PPT到PDF的高效转换详解》在日常开发中,经常会遇到将PPT文档批量或单文件转换为PDF的需求,本文将详细介绍其使用流程、核心代码与常见问题解决方案,希望对大家有所帮助... 目录一、环境配置Maven 配置Gradle 配置二、核心实现:3步完成PPT转PDF1. 单文件转换(基础版)

使用C#实现Excel与DataTable的相互转换

《使用C#实现Excel与DataTable的相互转换》在软件开发中,Excel文件和DataTable是两种广泛使用的数据存储形式,本文将介绍如何通过C#实现Excel文件与Data... 目录安装必要的库从 Excel 导出数据到 DataTable从 DataTable 导入数据到 Excel处理 E

利用Python将PDF文件转换为PNG图片的代码示例

《利用Python将PDF文件转换为PNG图片的代码示例》在日常工作和开发中,我们经常需要处理各种文档格式,PDF作为一种通用且跨平台的文档格式,被广泛应用于合同、报告、电子书等场景,然而,有时我们需... 目录引言为什么选择 python 进行 PDF 转 PNG?Spire.PDF for Python

Java轻松实现PDF转换为PDF/A的示例代码

《Java轻松实现PDF转换为PDF/A的示例代码》本文将深入探讨Java环境下,如何利用专业工具将PDF转换为PDF/A格式,为数字文档的永续保存提供可靠方案,文中的示例代码讲解详细,感兴趣的小伙伴... 目录为什么需要将PDF转换为PDF/A使用Spire.PDF for Java进行转换前的准备通过

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H