How do I change a black and white grating to red and green?

2 views (last 30 days)
I have a sine-wave black and white grating (matrix with values between 0-255). However I want to create a version of this that changes from red to green. I'm using psychtoolbox. Does anyone know how I might do this? Thanks!

Answers (1)

DGM
DGM on 31 Dec 2023
I'm going to do this with MIMT tools because I'm lazy, and that's why convenient tools exist.
Assume we have a single-channel grating image of any standard numeric class, scaled correctly for its class.
We will consider three different ways to use this image:
  • basic color blending, using the grating as a graduated mask
  • hue rotation, using the grating as an angle map
  • scaled colormapping using any arbitrary colormap
Basic color blending
MIMT replacepixels() makes this simple, since it supports tuple inputs. You could use sRGB like everyone does, but that's not really how it should be done, and you'll tend to end up with muddy, dark transitions, especially between these two colors.
mask = imread('sinmask.png'); % read the input image (uint8)
fgc = [1 0 0]; % the colors
bgc = [0 1 0];
outpict = replacepixels(fgc,bgc,mask); % alpha compositing in sRGB
Instead, you can do the work in linear RGB.
outpict = replacepixels(fgc,bgc,mask,'linear'); % alpha compositing in linear RGB
If you feel that winds up letting bright colors (i.e. green) dominate too much, you can always shift the gamma a bit to compensate.
mask = imlnc(mask,'sg',0.7); % adjust gamma
outpict = replacepixels(fgc,bgc,mask,'linear'); % then do the blend
Hue sweeps
This could be done with MIMT imblend()'s 'permute' mode, but it's really not meant for swinging between primaries like this. Let's just do it directly in HSV. Obviously, R and G are 120 degrees apart in HSV. We have two choices. We could swing on the short angle or on the long angle.
mask = imread('sinmask.png'); % read the input image (uint8)
sz = imsize(mask,2);
H = simnorm(mask)*0.33; % short angle R-Y-G rotation
SV = ones(sz); % say S and V are 100%
outpict = hsv2rgb(cat(3,H,SV,SV));
H = mod(1-simnorm(mask)*0.67,1); % long-angle R-M-B-C-G rotation
SV = ones(sz); % say S and V are 100%
outpict = hsv2rgb(cat(3,H,SV,SV));
Colormapping
Another approach is to simply use a colormap to express the intensity image in color. This could be any colormap that progresses from red to green -- or any other colors. It could be of any length.
mask = imread('sinmask.png');
% any color table of any length > 2
% i'm using only 8 colors for emphasis here
CT = makect([1 0 0],[0 1 0],8); % red and green as before
outpict = gray2pcolor(mask,CT); % do the colormapping
Again, it could be any colormap. There are built-in map generators, and there are plenty of them on the File Exchange.
CT = magma(8); % see FEX #62729
outpict = gray2pcolor(mask,CT); % do the colormapping
replacepixels(), imlnc(), makect(), gray2pcolor() are from MIMT. I've posted plenty of non-MIMT solutions for these sorts of problems on the forum. You're free to browse for them.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!