如果您可以处理RAW文件,则将有一个由RGRGRG和GBGBGB行(或可能是RGBGRGBG行)组成的拜耳像素阵列。您可以忽略所有R和B像素,将G像素相加,取平方根( (因为绿色像素的数量是红色或蓝色像素的两倍),然后除以G像素数量的一半。这应该为您的照片中的“绿色”提供适当的加权平均值。然后,您可以取红色和蓝色的平均值,然后从所有三个平均值中计算出绿色百分比。
为了更准确,您可能需要考虑红色,绿色和蓝色传感器像素的适当权重,因为CMOS传感器对每种波长的光都有不同的灵敏度。权重通常取决于传感器。那将是简单的方法。
要考虑到由于一天中的时间,各种类型的人工照明等导致的偏色,则更合适的方法是先使用Lightroom等工具对每张照片进行预处理,以首先校正白平衡,然后对标准RGB像素图像执行计算。与处理RAW传感器数据不同,您希望基于像素“绿色纯度”对计算进行加权,而不是对整个绿色分量进行平均。绿色像素越纯,相对于红色或蓝色像素就越重。在处理之前对白平衡进行归一化应该消除使切线复杂化的复杂度,而这些切线旨在解决诸如云量,一天中的时间,季节等众多因素。
您可能仍要考虑大面积的非入射像素,例如天空。在没有确切了解您要实现的目标方面,我无法真正为您提供帮助。通过计算绿色与红色和蓝色的比率(其中包括“天空”像素),可能最好地满足“照片”整体的绿色要求。
对于您的步骤,不用说,如果您使用相同的相机设置,在相同的光源(相同的强度和色温)下,按照通用基准(例如18%的灰卡)进行测光,则照片显然可以拍摄使您的结果正常化还有很长的路要走。使用数码相机时,可以使用RAW处理软件和基本的白平衡选择器工具纠正任何差异,因此请确保以RAW拍摄。
为了提供更多有关计算照片“绿色”的见解。显然有简单的方法,例如计算绿色拜耳像素与蓝色和红色的权重,或计算与RGB像素的红色/蓝色纯度有关的绿色纯度。如果您转换到更合适的色彩空间(例如HSV(色相/饱和度/值,有时称为HSB,用亮度替换值),并使用色相空间中的曲线计算绿色量,则可能会更有运气。(注意:HSL是一种不同类型的色彩空间,因此可能不太适合计算照片中的“绿色”量,因此我将使用HSV。您可以在此处详细了解这些色彩空间。)纯绿色(无论饱和度或值如何)都以120°的色相角落下,并随着您向红色(0°)或向蓝色(240°)的方向从那里掉落。在240°和360°之间,无论饱和度或值如何,像素中的绿色量都为零。
图1.色相图-色相中的绿色纯度
您可以调整实际的权重曲线以满足您的特定需求,但是一条简单的曲线可能类似于以下内容:
range = 240
period = range * 2 = 240 * 2 = 480
scale = 360/period = 0.75
pureGreen = sin(scale * 120)
的值pureGreen
应为1.0。greenness
然后可以按如下方式计算公式:
sin(scale * hue) } 0 > hue > 240
greenness =
0 } 240 <= hue <= 360 || hue == 0
这hue
是HSV颜色值中的颜色度。这radius
是period
其中某种程度上存在绿色的一半。该scale
调整罪曲线给我们的期限,这样sin(scale * hue)
峰(返回1.0)正是你将有纯绿色(忽略绿色强度)。由于的数量greenness
仅在我们周期的前半部分有效,因此绿色计算仅在色度大于0°且小于240°且对于其他任何色度为零时才有效。
您可以通过调整周期来调整权重,定义的范围green
可能会存在(即,从0到240,而不是从0到240,您可能会设置类似的约束40 > hue > 200
),并定义该范围之外的任何东西以使绿色为0应该注意的是,这在数学上将是准确的,但是可能在感觉上并不是完全准确的。当然,您可以调整公式以将pure green
更多点调整为黄色(这可能会产生更直观的准确结果),将曲线的幅度增加到平稳状态,并将纯绿色的范围扩展到某个色调范围,而不是单个范围色调值等。要获得总体人类感知准确度,需要在CIE XYZ和CIE L a b *中处理更复杂的算法可能需要空间。(注意:在XYZ和实验室空间中工作的复杂性大大超出了我在此描述的范围。)
要计算照片的绿色度,您可以计算每个像素的绿色度,然后得出平均值。然后,您可以从那里获取算法,并针对您的特定需求进行调整。
您可以在EasyRGB上找到用于颜色转换的算法,例如用于RGB到HSV的算法:
var_R = ( R / 255 ) // Red percentage
var_G = ( G / 255 ) // Green percentage
var_B = ( B / 255 ) // Blue percentage
var_Min = min( var_R, var_G, var_B ) //Min. value of RGB
var_Max = max( var_R, var_G, var_B ) //Max. value of RGB
del_Max = var_Max - var_Min //Delta RGB value
V = var_Max //Value (or Brightness)
if ( del_Max == 0 ) //This is a gray, no chroma...
{
H = 0 //Hue (0 - 1.0 means 0° - 360°)
S = 0 //Saturation
}
else //Chromatic data...
{
S = del_Max / var_Max
del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max
if ( var_R == var_Max ) H = del_B - del_G
else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R
if ( H < 0 ) H += 1
if ( H > 1 ) H -= 1
}