Reputation: 114290
If I call colormap('jet')
, I will get a 256-by-3 matrix with the colors of jet
. If I do jet(1000)
, I can get a much more densely sampled equivalent. I happen to need the more densely sampled colormaps, but for arbitrary named colormaps. How can I get a colormap with a variable number of elements by name.
I have considered something like eval(sprintf('%s(%d)', name, num))
, where e.g. name = 'parula'
and num = 1000
, but that carries all the problems inherent with eval
, and I would like to avoid using it, as I am sure there is a way to access colormap functions by name.
To avoid an X-Y problem, here is my background info:
I am trying to apply gamma-correction to an indexed image. I can not map ranges outside [0, 1]
using imadjust
. Also, I would like to display a colorbar with the image that maps to correct values. To that end, I am adjusting the colormap by resampling a higher-density version of it to the desired range with the inverted gamma function:
function imdisp(img, cmap, gamma)
density = 1000; % not really a good name, but w/e
x = linspace(0, 1, 10 * density);
y = x.^(1 / gamma);
z = linspace(0, 1, density);
ind = round(interp1(y, x, z, 'nearest', 'extrap') * (10 * density - 1) + 1);
% this is the problem line
colors = eval(sprintf('%s(%d)', cmap, 10 * density));
colors = colors(ind);
imshow(img, []);
colormap(colors);
colorbar();
end
If there is a better way to do this entirely, please feel free to post that instead of a direct answer.
Upvotes: 3
Views: 221
Reputation: 60494
This is what feval
is for:
colors = feval(cmap, 10 * density);
feval
is not as dangerous as eval
, because it doesn't execute arbitrary code, but it can execute an arbitrary function and therefore should still be used carefully. It also doesn't allow the JIT to know ahead of time what function will be called, so there's an additional overhead. On the other hand, you don't need to create a string for the arguments that then has to be parsed again.
Consider instead accepting a function handle into your function: call it as imdisp(img, @jet, gamma)
. Now your cmap
variable is a function that you can call: cmap(10 * density)
.
Upvotes: 6