GoPiGo 小汽車︰格點圖像算術《彩色世界》【顏色ABC】四

若講『色彩空間』就是人類所能『感知』之『顏色』形成的空間。怕是講了也像沒講的吧!科學家依據『紅綠藍三原色說』想將之『量化』,首先得面對『單色光』的『光譜』選擇哩?然後才能作『實驗』,將『測試色』與『 RGB 可調光』成『批配』,逐步完善『標準化』的也︰

Definition of the CIE XYZ color space

CIE RGB color space

The CIE RGB color space is one of many RGB color spaces, distinguished by a particular set of monochromatic (single-wavelength) primary colors.

In the 1920s, W. David Wright[3] and John Guild[4] independently conducted a series of experiments on human sight which laid the foundation for the specification of the CIE XYZ color space. Wright carried out trichromatic color matching experiments with ten observers. Guild actually conducted his experiments with seven observers.

 Gamut of the CIE RGB primaries and location of primaries on the CIE 1931 xy chromaticity diagram.

The experiments were conducted by using a circular split screen (a bipartite field) 2 degrees in diameter, which is the angular size of the human fovea. On one side of the field a test color was projected and on the other side, an observer-adjustable color was projected. The adjustable color was a mixture of three primary colors, each with fixed chromaticity, but with adjustable brightness.

The observer would alter the brightness of each of the three primary beams until a match to the test color was observed. Not all test colors could be matched using this technique. When this was the case, a variable amount of one of the primaries could be added to the test color, and a match with the remaining two primaries was carried out with the variable color spot. For these cases, the amount of the primary added to the test color was considered to be a negative value. In this way, the entire range of human color perception could be covered. When the test colors were monochromatic, a plot could be made of the amount of each primary used as a function of the wavelength of the test color. These three functions are called the color matching functions for that particular experiment.

 The CIE 1931 RGB color matching functions. The color matching functions are the amounts of primaries needed to match the monochromatic test color at the wavelength shown on the horizontal scale.

Although Wright and Guild’s experiments were carried out using various primaries at various intensities, and although they used a number of different observers, all of their results were summarized by the standardized CIE RGB color matching functions {\overline {r}}(\lambda ) {\overline {g}}(\lambda ), and  {\overline {b}}(\lambda ), obtained using three monochromatic primaries at standardized wavelengths of 700 nm (red), 546.1 nm (green) and 435.8 nm (blue). The color matching functions are the amounts of primaries needed to match the monochromatic test primary. These functions are shown in the plot on the right (CIE 1931). Note that {\overline {r}}(\lambda ) and  {\overline {g}}(\lambda ) are zero at 435.8 nm {\overline {r}}(\lambda ) and  {\overline {b}}(\lambda ) are zero at 546.1 nm and  {\overline {g}}(\lambda ) and  {\overline {b}}(\lambda ) are zero at 700 nm, since in these cases the test color is one of the primaries. The primaries with wavelengths 546.1 nm and 435.8 nm were chosen because they are easily reproducible monochromatic lines of a mercury vapor discharge. The 700 nm wavelength, which in 1931 was difficult to reproduce as a monochromatic beam, was chosen because the eye’s perception of color is rather unchanging at this wavelength, and therefore small errors in wavelength of this primary would have little effect on the results.

The color matching functions and primaries were settled upon by a CIE special commission after considerable deliberation.[11] The cut-offs at the short- and long-wavelength side of the diagram are chosen somewhat arbitrarily; the human eye can actually see light with wavelengths up to about 810 nm, but with a sensitivity that is many thousand times lower than for green light. These color matching functions define what is known as the “1931 CIE standard observer”. Note that rather than specify the brightness of each primary, the curves are normalized to have constant area beneath them. This area is fixed to a particular value by specifying that

{\displaystyle \int _{0}^{\infty }{\overline {r}}(\lambda )\,d\lambda =\int _{0}^{\infty }{\overline {g}}(\lambda )\,d\lambda =\int _{0}^{\infty }{\overline {b}}(\lambda )\,d\lambda .}

The resulting normalized color matching functions are then scaled in the r:g:b ratio of 1:4.5907:0.0601 for source luminance and 72.0962:1.3791:1 for source radiance to reproduce the true color matching functions. By proposing that the primaries be standardized, the CIE established an international system of objective color notation.

Given these scaled color matching functions, the RGB tristimulus values for a color with a spectral power distribution {\displaystyle S(\lambda )} would then be given by:

  {\displaystyle R=\int _{0}^{\infty }S(\lambda )\,{\overline {r}}(\lambda )\,d\lambda ,}
{\displaystyle G=\int _{0}^{\infty }S(\lambda )\,{\overline {g}}(\lambda )\,d\lambda ,}
  {\displaystyle B=\int _{0}^{\infty }S(\lambda )\,{\overline {b}}(\lambda )\,d\lambda .}

These are all inner products and can be thought of as a projection of an infinite-dimensional spectrum to a three-dimensional color.

Grassmann’s law

One might ask: “Why is it possible that Wright and Guild’s results can be summarized using different primaries and different intensities from those actually used?” One might also ask: “What about the case when the test colors being matched are not monochromatic?” The answer to both of these questions lies in the (near) linearity of human color perception. This linearity is expressed in Grassmann’s law.

The CIE RGB space can be used to define chromaticity in the usual way: The chromaticity coordinates are r and g where:

{\displaystyle r={\frac {R}{R+G+B}},}
  {\displaystyle g={\frac {G}{R+G+B}}.}

 

由於『RGB』配色會遭遇『負值』,大自然果有『負能量』之光子哉??此所以不得不用『虛擬光譜源』耶!!

Color matching functions

The CIE standard observer color matching functions.

The CIE’s color matching functions  {\overline {x}}(\lambda ) {\overline {y}}(\lambda ) and  {\overline {z}}(\lambda ) are the numerical description of the chromatic response of the observer (described above). They can be thought of as the spectral sensitivity curves of three linear light detectors yielding the CIE tristimulus values X, Y and Z. Collectively, these three functions are known as the CIE standard observer.[10]

Other observers, such as for the CIE RGB space or other RGB color spaces, are defined by other sets of three color-matching functions, and lead to tristimulus values in those other spaces.

Computing XYZ From Spectral Data

Emissive Case

The tristimulus values for a color with a spectral radiance Le,Ω,λ are given in terms of the standard observer by:

  {\displaystyle X=\int _{\lambda }L_{\mathrm {e} ,\Omega ,\lambda }(\lambda )\,{\overline {x}}(\lambda )\,d\lambda ,}
  {\displaystyle Y=\int _{\lambda }L_{\mathrm {e} ,\Omega ,\lambda }(\lambda )\,{\overline {y}}(\lambda )\,d\lambda ,}
  {\displaystyle Z=\int _{\lambda }L_{\mathrm {e} ,\Omega ,\lambda }(\lambda )\,{\overline {z}}(\lambda )\,d\lambda .}

where  \lambda is the wavelength of the equivalent monochromatic light (measured in nanometers), and the standard limits of the integral are {\displaystyle \lambda \in [380,780]}.

The values of X, Y, and Z are bounded if the radiance spectrum Le,Ω,λ is bounded.

Reflective and Transmissive Cases

The reflective and transmissive cases are very similar to the emissive case, with a few differences. The spectral radiance Le,Ω,λ is replaced by the spectral reflectance (or transmittance) S(λ) of the object being measured, multiplied by the spectral power distribution of the illuminant I(λ).

{\displaystyle X={\frac {K}{N}}\int _{\lambda }S(\lambda )\,I(\lambda )\,{\overline {x}}(\lambda )\,d\lambda ,}
  {\displaystyle Y={\frac {K}{N}}\int _{\lambda }S(\lambda )\,I(\lambda )\,{\overline {y}}(\lambda )\,d\lambda ,}
{\displaystyle Z={\frac {K}{N}}\int _{\lambda }S(\lambda )\,I(\lambda )\,{\overline {z}}(\lambda )\,d\lambda ,}

where

{\displaystyle N=\int _{\lambda }I(\lambda )\,{\overline {y}}(\lambda )\,d\lambda ,}

K is a scaling factor (usually 1 or 100), and  \lambda is the wavelength of the equivalent monochromatic light (measured in nanometers), and the standard limits of the integral are  {\displaystyle \lambda \in [380,780]}.

CIE xy chromaticity diagram and the CIE xyY color space

Since the human eye has three types of color sensors that respond to different ranges of wavelengths, a full plot of all visible colors is a three-dimensional figure. However, the concept of color can be divided into two parts: brightness and chromaticity. For example, the color white is a bright color, while the color grey is considered to be a less bright version of that same white. In other words, the chromaticity of white and grey are the same while their brightness differs.

The CIE XYZ color space was deliberately designed so that the Y parameter is a measure of the luminance of a color. The chromaticity of a color is then specified by the two derived parameters x and y, two of the three normalized values being functions of all three tristimulus values X, Y, and Z:

x={\frac {X}{X+Y+Z}}
y={\frac {Y}{X+Y+Z}}
  z={\frac {Z}{X+Y+Z}}=1-x-y

The derived color space specified by x, y, and Y is known as the CIE xyY color space and is widely used to specify colors in practice.

The X and Z tristimulus values can be calculated back from the chromaticity values x and y and the Y tristimulus value:

  {\displaystyle X={\frac {Y}{y}}x,}
  {\displaystyle Z={\frac {Y}{y}}(1-x-y).}

The figure on the right shows the related chromaticity diagram. The outer curved boundary is the spectral locus, with wavelengths shown in nanometers. Note that the chromaticity diagram is a tool to specify how the human eye will experience light with a given spectrum. It cannot specify colors of objects (or printing inks), since the chromaticity observed while looking at an object depends on the light source as well.

Mathematically the colors of the chromaticity diagram occupy a region of the real projective plane.

The chromaticity diagram illustrates a number of interesting properties of the CIE XYZ color space:

  • The diagram represents all of the chromaticities visible to the average person. These are shown in color and this region is called the gamut of human vision. The gamut of all visible chromaticities on the CIE plot is the tongue-shaped or horseshoe-shaped figure shown in color. The curved edge of the gamut is called the spectral locus and corresponds to monochromatic light (each point representing a pure hue of a single wavelength), with wavelengths listed in nanometers. The straight edge on the lower part of the gamut is called the line of purples. These colors, although they are on the border of the gamut, have no counterpart in monochromatic light. Less saturated colors appear in the interior of the figure with white at the center.
  • It is seen that all visible chromaticities correspond to non-negative values of x, y, and z (and therefore to non-negative values of X, Y, and Z).
  • If one chooses any two points of color on the chromaticity diagram, then all the colors that lie in a straight line between the two points can be formed by mixing these two colors. It follows that the gamut of colors must be convex in shape. All colors that can be formed by mixing three sources are found inside the triangle formed by the source points on the chromaticity diagram (and so on for multiple sources).
  • An equal mixture of two equally bright colors will not generally lie on the midpoint of that line segment. In more general terms, a distance on the CIE xy chromaticity diagram does not correspond to the degree of difference between two colors. In the early 1940s, David MacAdam studied the nature of visual sensitivity to color differences, and summarized his results in the concept of a MacAdam ellipse. Based on the work of MacAdam, the CIE 1960, CIE 1964, and CIE 1976 color spaces were developed, with the goal of achieving perceptual uniformity (have an equal distance in the color space correspond to equal differences in color). Although they were a distinct improvement over the CIE 1931 system, they were not completely free of distortion.
  • It can be seen that, given three real sources, these sources cannot cover the gamut of human vision. Geometrically stated, there are no three points within the gamut that form a triangle that includes the entire gamut; or more simply, the gamut of human vision is not a triangle.
  • Light with a flat power spectrum in terms of wavelength (equal power in every 1 nm interval) corresponds to the point (x, y) = (1/3, 1/3).

The CIE 1931 color space chromaticity diagram. The outer curved boundary is the spectral (or monochromatic) locus, with wavelengths shown in nanometers. Note that the colors your screen displays in this image are specified using sRGB, so the colors outside the sRGB gamut are not displayed properly. Depending on the color space and calibration of your display device, the sRGB colors may not be displayed properly either. This diagram displays the maximally saturated bright colors that can be produced by a computer monitor or television set.

The CIE 1931 color space chromaticity diagram rendered in terms of the colors of lower saturation and value than those displayed in the diagram above that can be produced by pigments, such as those used in printing. The color names are from the Munsell color system.

 

本就晨昏恐遇『色度』不同乎!!??

Chromaticity

Chromaticity is an objective specification of the quality of a color regardless of its luminance. Chromaticity consists of two independent parameters, often specified as hue (h) and colorfulness (s), where the latter is alternatively called saturation, chroma, intensity,[1] or excitation purity.[2][3] This number of parameters follows from trichromacy of vision of most humans, which is assumed by most models in color science.

The CIE 1931 xy chromaticity space, also showing the chromaticities of black-body light sources of various temperatures, and lines of constant correlated color temperature

 

如何言人世間有人有

四色視覺

四色視覺英語:Tetrachromacy)是指生物體擁有四種獨立的感光通道,或指眼球中有四種感色的視錐細胞(較人類多出感應紫外線錐狀細胞),大部分鳥類具有此種特徵。一般人類所繪製出的圖案對四色視覺者可能是難以理解的。

梅花雀視錐細胞的感光響應曲線,其感光範圍從可見光到紫外線[1]

 

的呀??!!

且權充稍補足 ColorPy 文本而已矣☆

Fundamentals – Mapping spectra to three-dimensional color values

We are interested in working with physical descriptions of light spectra, that is, functions of intensity vs. wavelength.  However, color is perceived as a three-dimensional quantity, as there are three sets of color receptors in the eye, which respond approximately to red, green and blue light.  So how do we reduce a function of intensity vs. wavelength to a three-dimensional value?

This fundamental step is done by integrating the intensity function with a set of three matching functions.  The standard matching functions were defined by the Commission Internationale de l’Eclairage (CIE), based on experiments with viewers matching the color of single wavelength lights.  The matching functions generally used in computer graphics are those developed in 1931, which used a 2 degree field of view.  (There is also a set of matching functions developed in 1964, covering a field of view of 10 degrees, but the larger field of view does not correspond to typical conditions in viewing computer graphics.)  So the mapping is done as follows:

X = ∫ I (λ) * CIE-X (λ) * dλ
Y = ∫ I (λ) * CIE-Y (λ) * dλ
Z = ∫ I (λ) * CIE-Z (λ) * dλ

where I (λ) is the spectrum of light intensity vs. wavelength, and CIE-X (λ), CIE-Y (λ) and CIE-Z (λ) are the matching functions.  The CIE matching functions are defined over the interval of 360 nm to 830 nm, and are zero for all wavelengths outside this interval, so these are the bounds for the integrals.

So what do these matching functions look like?  Let’s take a look at a plot (made with ColorPy, of course.)


Figure 1 – The 1931 CIE XYZ matching functions.

This plot shows the three matching functions vs. wavelength.  The colors underneath the curve, at each wavelength, are the (approximate) colors that the human eye will perceive for a pure spectral line at that wavelength, of constant intensity.  The apparent brightness of the color at each wavelength indicates how strongly the eye perceives that wavelength – the intensity for each wavelength is the same.  (The next section will explain how we get the RGB values for the colors.)

Each of the three plots was generated via colorpy.plots.spectrum_subplot (spectrum), where spectrum is the value of the matching function vs. wavelength.

All three of the matching functions are zero or positive everywhere.  Since the light intensity at any wavelength is never negative, this means that the resulting XYZ color values are never negative.  Also, the Y matching function corresponds exactly to the luminous efficiency of the eye – the eye’s response to light of constant luminance.  (These facts are some of the reasons that make this particular set of matching functions so useful.)

So now we can map a spectrum of intensity vs. wavelength into a three-dimensional value.  Before we consider how to convert this into an RGB color value that we can draw, we will first discuss some typical scaling operations on XYZ colors.

Often, it is useful to consider the ‘chromaticity’ of a color, that is, the hue and saturation, independent of the intensity.  This is typically done by scaling the XYZ values so that their sum is 1.0.  The resulting scaled values are conventionally written as lower case letters x,y,z.  With this scaling, x+y+z = 1.0.  The chromaticity can be specified by the resulting x and y values, and the z component can be reconstructed as z = 1.0 – x – y.  It is also common to specify colors with their chromaticity (x and y), as well as the total brightness (Y).  Occasionally, one also wants to scale an XYZ color so that the resulting Y value is 1.0.

ColorPy represents XYZ colors (and other types of colors) as three-component vectors.  There are some ‘constructor’ like functions to create such arrays, and perform these kinds of scaling:

colorpy.colormodels.xyz_color (x, y, z = None)
colorpy.colormodels.xyz_normalize (xyz)
colorpy.colormodels.xyz_color_from_xyY (x, y, Y)
colorpy.colormodels.xyz_normalize_Y1 (xyz)

Notice that color types are generally specified in ColorPy with lower case letters, as this is more readable.  (I.e., xyz_color instead of XYZ_color.)  The user must keep track of the particular normalization that applies in each situation.

Fundamentals – Converting XYZ colors to RGB colors

So how do we convert one of these XYZ colors to an RGB color that I can draw on my computer?

The short answer, is to call colorpy.colormodels.irgb_from_xyz (xyz), where xyz is the XYZ color vector.  This will return a three element integer vector, with each component in the range 0 – 255.  There is also a function colorpy.colormodels.irgb_string_from_xyz (xyz) that will return a hex string, such as ‘#FF0000’ for red.

There are several subtleties and approximations in the behavior of these functions, which are important to understand what is happening.

The first step in the conversion, is to convert the XYZ color to a ‘linear’ RGB color.  By ‘linear’, we mean that the light intensity is proportional to the numerical color values.  ColorPy represents such linear RGB values as floats, with the nominal range of 0.0 – 1.0 covering the range of intensity that the monitor display can produce.  (This implies an assumption as to the physical brightness of the display.)  The conversion from XYZ to linear RGB is done by multiplication by a 3×3 element array.  So, which array to use?  The specific values of the array depend on the physical display in question, specifically the chromaticities of the monitor phosphors.  Not all displays have the exact same red, green and blue monitor primaries, and so any conversion matrix cannot apply to all displays.  This can be a considerable complication, but fortunately, there is a specification of monitor chromaticities that we can assume, part of the sRGB standard, and are likely to be a close match to most actual displays.  ColorPy uses this assumption by default, although you can change the assumed monitor chromaticities to nearly anything you like.

So for now, let’s assume the standard sRGB chromaticities, which gives us the correct 3×3 matrix, and so we can convert our XYZ colors to linear RGB colors.

We then come to the next obstacle…  The RGB values that we get from this process are often out of range – meaning that they are either greater than 1.0, or even that they are negative!  The first case is fairly straightforward, it means that the color is too bright for the display.  The second case means that the color is too saturated and vivid for the display.  The display must compose all colors from some combination of positive amounts of the colors of its red, green and blue phosphors.  The colors of these phosphors are not perfectly saturated, they are washed out, mixed with white, to some extent.  So not all colors can be displayed accurately.  As an example, the colors of pure spectral lines, all have some negative component.  Something must be done to put these values into the 0.0 – 1.0 range that can actually be displayed, known as color clipping.

In the first case, values larger than 1.0, ColorPy scales the color so that the maximum component is 1.0.  This reduces the brightness without changing the chromaticity.  The second case requires some change in chromaticity.  By default, ColorPy will add white to the color, just enough to make all of the components non-negative.  (You can also have ColorPy clamp the negative values to zero.  My personal, qualitative, assessment is that adding white produces somewhat better results.  There is also the potential to develop a better clipping function.)

So now we have linear RGB values in the range 0.0 – 1.0.  The next subtlety in the conversion process, is that the intensity of colors on the display is not simply proportional to the color values given to the hardware.  This situation is known as ‘gamma correction’, and is particularly significant for CRT displays.  The voltage on the electron gun in the CRT display is proportional to the RGB values given to the hardware to display, but the intensity of the resulting light is *not* proportional to this voltage, in fact the relationship is a power law.  The particular correction for this depends on the physical display in question.  LCD displays add another complication, as it is not clear (at least to me) what the correct conversion is in this case.  Again, we rely on the sRGB standard to decide what to do.  That standard assumes a physical ‘gamma’ exponent of about 2.2, and ColorPy applies this correction by default.  You can change this to a different exponent if you like.

The final step after gamma correction, is to convert the RGB components from the range 0.0 – 1.0 to 0 – 255, which is the typical range needed to pass to the hardware.  This is done with simple scaling and rounding.  The final result of all of these conversions, RGB color values in the range 0 – 255, is referred to as an irgb_color.  This is the color type that can be passed to drawing functions.

Summarizing of these conversions, with the functions that ColorPy uses internally:

colorpy.colormodels.rgb_from_xyz (xyz) – Converts an XYZ color to a linear RGB color, with components in the nominal range 0.0 – 1.0, but possibly out of range (greater than 1.0, or negative).  The resulting linear RGB color cannot be directly passed to drawing functions.

colorpy.colormodels.irgb_from_rgb (rgb) – Converts a linear RGB color in the nominal range 0.0 – 1.0 to a displayable irgb color, definitely in the range 0 – 255.  Color clipping may be applied (intensity as well as chromaticity), and gamma correction is accounted for.  This result can be passed to drawing functions.


With all of this, let’s plot some real colors.  First, consider the pure spectral lines – that is, spectra that are all black (zero intensity), except at a single wavelength.  We consider all the wavelengths from 360 nm to 830 nm, which covers the range of human vision (and the range of the CIE XYZ matching functions.)

The two-part plot below shows the result.  The top section, shows the best colors that ColorPy can draw for each wavelength.  The amount of light intensity for each wavelength is the same.  But since the human eye has different sensitivity to different wavelengths, the apparent brightness looks different for different colors.  For example, the color for 750 nm is quite dark, while the color for 550 nm is quite bright.  They represent lines with the same physical luminance, however.  The bottom section shows the linear RGB values corresponding to each wavelength.  You can see that there are negative RGB values on this plot.  In fact, there is a negative component at every wavelength – none of the pure spectral lines can be displayed with full saturation.  (The overall intensity scale is arbitrary, and has been chosen so that the largest RGB component for any wavelength is 1.0.)


Figure 2 – RGB values for the pure spectral lines.

This specific plot was made with colorpy.plots.visible_spectrum_plot (), and the real work was done with colorpy.plots.color_vs_param_plot (param_list, rgb_colors, title, filename, tight=False, plotfunc=pylab.plot, xlabel='param', ylabel='RGB Color').  This function accepts two lists, one of an arbitrary parameter (wavelength in this case), and one of linear RGB colors.  (The two lists must be of the same size.)  You also must supply a title and filename for the plot.  Optional arguments include a request that the x-axis be ‘tightened’ to only include the range of the parameters, a different plotting function from the default, and different labels for the axes.  This is a very handy function, useful for many other plots besides this one.

You can see that there are negative RGB values for these colors, and those actually drawn have been clipped to something displayable.

Another way to understand the limited color gamut (range of displayable colors) of physical displays, is to consider the ‘shark fin’ CIE chromaticity diagram.  On this plot, we draw the chromaticities of the pure spectral lines.  These trace out a fin shaped region.  The low wavelength colors start at the lower left corner of the fin, and as the wavelength increases, moves up on the plot towards green, and then down and to the right towards yellow and red.  The longest wavelength corresponds to the red corner at the far right.  The straight line connecting the long wavelength red to the short wavelength blue is not composed of pure spectral lines, rather these ‘purples’ are a linear combination of the extreme red and blue colors.  The outer boundary of this diagram represents the spectrally pure colors.  Just inside this boundary, we draw the best color match for each wavelength.

The triangle inside the fin represents the range (gamut) of colors that the physical display can show.  The vertices labeled Red, Green and Blue represent the chromaticities of the monitor primaries, and the point labeled White represents the white point with all primaries at full strength.  (This plot assumes the standard sRGB primaries and white point.)  The points inside the inner triangle are the only colors that the display can render accurately.  (This figure could use a little work.  It would be nice to label the outer boundary of the fin with the corresponding wavelength.)  The points outside the inner triangle are colors that must be approximated.  (Points outside the outer ‘fin’ do not correspond to any color at all.)

You can see that the standard monitor is much more limited in displaying greens than blues and reds.  If someone is able to invent a much purer green colored phosphor, with low persistence so it is suitable for animations and hence real displays, then the world of computer graphics will get significantly more richly colored!  Also notice that there is no possible set of of three monitor phosphor chromaticities that can cover the entire visible gamut.  For any three points inside the ‘fin’, the enclosed triangle must necessarily exclude some of the pure spectral colors, even if the monitor phosphors were perfectly spectrally pure.


Figure 3 – CIE chromaticity diagram of the visible gamut.
Colors inside the inner triangle can be accurately drawn on the display, points outside (but inside the fin) must be approximated.

This figure is drawn with colorpy.plots.shark_fin_plot().  This is kind of a specialized figure, probably not that useful for other things.