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.