plotting 2 datasets in one image
mas1126
Hi all,
I'm looking for a way to plot an image that uses values from two different waves to determine the color output at each x,y point. Specifically, I have two 2D waves- one containing magnitudes, and one containing phase information. I'd like to display them in one image so that the phase determines the hue of the pixel, but the magnitude determines the brightness.
Does anyone have any pointers for accomplishing this?
Make a real-valued 2-D RGB matrix with Make/U/B/O/N=(rows,cols,3) and set the first layer to red, (0-255), second to green, third to blue.
Write a routine to decide what RGB you get from the corresponding point in your 2D complex wave.
As expressed, you need a way to convert from hue and brightness to RGB (constant saturation?)
There are useful routines in #include <colorSpaceConversions>, especially HSL2RGB().
October 4, 2021 at 04:35 pm - Permalink
In reply to Make a real-valued 2-D RGB… by JimProuty
I should look more carefully at the WM utility procedures. I wasted a bit of time rolling my own for several of these functions.
Incidentally, I don't see an RGB2HSL function in colorSpaceConversions. Here's the one I have used. There may be some reason that this is incorrect, perhaps something to do with which colors can be mapped between color spaces in this direction? It worked for my needs.
// R, G and B input range = 0 - 65535
// H, S and L output range = 0 - 1
variable red = rgb.red/65535, green = rgb.green/65535, blue = rgb.blue/65535
variable var_Min = min(red,green,blue), var_Max = max(red,green,blue)
variable del_Max = var_Max - var_Min
hsl.L = (var_Max + var_Min) / 2
if (del_Max == 0) // grey
hsl.H = 0
hsl.S = 0
else // Chromatic data
hsl.S = (hsl.L < 0.5) ? del_Max/(var_Max + var_Min) : del_Max/(2 - var_Max - var_Min)
variable del_R = ( (var_Max - red)/6 + del_Max/2 ) / del_Max
variable del_G = ( (var_Max - green)/6 + del_Max/2 ) / del_Max
variable del_B = ( (var_Max - blue)/6 + del_Max/2 ) / del_Max
if(red == var_Max)
hsl.H = del_B - del_G
elseif (green == var_Max)
hsl.H = (1/3) + del_R - del_B
elseif (blue == var_Max)
hsl.H = (2/3) + del_G - del_R
endif
hsl.H += (hsl.H < 0)
hsl.H -= (hsl.H > 1)
endif
return 1
end
static structure HSLcolor
float H, S, L
endstructure
Also, the RGB2XYZ and RGB2LAB functions are for linearized RGB values, not sRGB. Here is my function with an extra step to 'linearize' standard RGB values.
// X, Y and Z output refer to a D65/2° standard illuminant.
Make /free w={rgb.red, rgb.green, rgb.blue}
w /= 65535
w = w > 0.04045 ? ((w + 0.055) / 1.055)^2.4 : w / 12.92
w *= 100
Make /free/N=3 xyz
xyz[0] = w[0] * 0.4124 + w[1] * 0.3576 + w[2] * 0.1805
xyz[1] = w[0] * 0.2126 + w[1] * 0.7152 + w[2] * 0.0722
xyz[2] = w[0] * 0.0193 + w[1] * 0.1192 + w[2] * 0.9505
Make /free XYZref={95.047,100,108.883}
w = xyz / XYZref
w = (w > 0.008856) ? w^(1/3) : 7.787 * w + (16 / 116)
Lab.L = (116 * w[1]) - 16
Lab.a = 500 * (w[0] - w[1])
Lab.b = 200 * (w[1] - w[2])
end
static structure LABcolor
float L, a, b
endstructure
October 5, 2021 at 03:24 am - Permalink
@Tony:
rgb2hsl is a keyword in ImageTransform that also supports a number of other conversions.
@mas1126:
I'd use Gizmo. Display the first image as a surface object and then use the second wave to create a color wave for the surface object.
Here is a quick example of creating some default surface and then using a function to map the colors.
Duplicate ddd,eee
eee=1/(1+ddd) // same size wave as the surface simulating your second image
// create a color wave from the second image:
ModifyGizmo makeSurfaceColorWave={eee,rainbow,0}
// apply to the surface object:
ModifyGizmo ModifyObject=sampleSurface,objectType=surface,property={ surfaceColorType,3}
ModifyGizmo ModifyObject=sampleSurface,objectType=surface,property={ surfaceColorWave,root:eee_C}
AG
October 5, 2021 at 12:49 pm - Permalink
Tony brings up a good point: many of our conversions presume a linear RGB color space (because our routines were implemented before sRGB was a thing).
sRGB is a "gamma-compressed" color space:
https://en.wikipedia.org/wiki/SRGB
October 5, 2021 at 04:41 pm - Permalink
yes, colorSpaceConversions.ipf is not self consistent, some functions are for sRGB and some for linear RGB.
Reading this makes me realize that I should post related functions to quantify color difference as a code snippet.
October 6, 2021 at 05:07 am - Permalink