plotting 2 datasets in one image

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().

In reply to by JimProuty

JimProuty wrote:

There are useful routines in #include <colorSpaceConversions>,

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.

static function RGB2HSL(STRUCT RGBcolor &rgb, STRUCT HSLcolor &hsl)
	// 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.

static function RGB2LAB(STRUCT RGBcolor &rgb, STRUCT LABcolor &Lab)
	// 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

 

@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.

NewGizmo/junk=2
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

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.