【源码】产生N种视觉差异最大的不同颜色distinguishable_colors

在这里插入图片描述
当绘制多条线段时,你会希望通过颜色进行最明显的区分。

When plotting a set of lines, you may want to distinguish them by color.

默认情况下,Matlab只会选择一小部分的颜色集合,当绘制的线段数量大于颜色数量时,线段的颜色绘制将进行循环,这就导致某些线段的颜色会相同。

By default, Matlab chooses a small set of colors and cycles among them, and so if you have more than a few lines there will be confusion about which line is which.

要解决这个问题,需要能够选择更多数量的不同颜色,其中颜色的数量等于或大于要绘制的线段的数量。

To fix this problem, one would want to be able to pick a much larger set of distinct colors, where the number of colors equals or exceeds the number of lines you want to plot.

由于我们区分颜色的能力是有限的,所以人们应该选择特别的颜色来“最大限度地感知区分”。

Because our ability to distinguish among colors has limits, one should choose these colors to be “maximally perceptually distinguishable.”

本函数产生一组颜色,这些颜色通过参考“实验室”的颜色空间标准来区分,从而比RGB更接近于人的颜色感知。

This function generates a set of colors which are distinguishable by reference to the “Lab” color space, which more closely matches human color perception than RGB.

给定可能颜色的大型初始列表,该函数迭代地从所有先前已选择的颜色中选择最远的容易区分的颜色(在实验室空间中)。

Given an initial large list of possible colors, it iteratively chooses the entry in the list that is farthest (in Lab space) from all previously-chosen entries.

完整MATLAB源代码如下:

function colors = distinguishable_colors(n_colors,bg,func)

% DISTINGUISHABLE_COLORS: pick colors that are maximally perceptually distinct

%

% When plotting a set of lines, you may want to distinguish them by color.

% By default, Matlab chooses a small set of colors and cycles among them,

% and so if you have more than a few lines there will be confusion about

% which line is which. To fix this problem, one would want to be able to

% pick a much larger set of distinct colors, where the number of colors

% equals or exceeds the number of lines you want to plot. Because our

% ability to distinguish among colors has limits, one should choose these

% colors to be “maximally perceptually distinguishable.”

%

% This function generates a set of colors which are distinguishable

% by reference to the “Lab” color space, which more closely matches

% human color perception than RGB. Given an initial large list of possible

% colors, it iteratively chooses the entry in the list that is farthest (in

% Lab space) from all previously-chosen entries. While this “greedy”

% algorithm does not yield a global maximum, it is simple and efficient.

% Moreover, the sequence of colors is consistent no matter how many you

% request, which facilitates the users’ ability to learn the color order

% and avoids major changes in the appearance of plots when adding or

% removing lines.

%

% Syntax:

% colors = distinguishable_colors(n_colors)

% Specify the number of colors you want as a scalar, n_colors. This will

% generate an n_colors-by-3 matrix, each row representing an RGB

% color triple. If you don’t precisely know how many you will need in

% advance, there is no harm (other than execution time) in specifying

% slightly more than you think you will need.

%

% colors = distinguishable_colors(n_colors,bg)

% This syntax allows you to specify the background color, to make sure that

% your colors are also distinguishable from the background. Default value

% is white. bg may be specified as an RGB triple or as one of the standard

% “ColorSpec” strings. You can even specify multiple colors:

% bg = {‘w’,‘k’}

% or

% bg = [1 1 1; 0 0 0]

% will only produce colors that are distinguishable from both white and

% black.

%

% colors = distinguishable_colors(n_colors,bg,rgb2labfunc)

% By default, distinguishable_colors uses the image processing toolbox’s

% color conversion functions makecform and applycform. Alternatively, you

% can supply your own color conversion function.

%

% Example:

% c = distinguishable_colors(25);

% figure

% image(reshape(c,[1 size©]))

%

% Example using the file exchange’s ‘colorspace’:

% func = @(x) colorspace(‘RGB->Lab’,x);

% c = distinguishable_colors(25,‘w’,func);

% Copyright 2010-2011 by Timothy E. Holy

% Parse the inputs

if (nargin < 2)

bg = [1 1 1];  % default white background

else

if iscell(bg)

  % User specified a list of colors as a cell aray

  bgc = bg;

  for i = 1:length(bgc)

bgc{i} = parsecolor(bgc{i});

  end

  bg = cat(1,bgc{:});

else

  % User specified a numeric array of colors (n-by-3)

  bg = parsecolor(bg);

end

end

% Generate a sizable number of RGB triples. This represents our space of

% possible choices. By starting in RGB space, we ensure that all of the

% colors can be generated by the monitor.

n_grid = 30; % number of grid divisions along each axis in RGB space

x = linspace(0,1,n_grid);

[R,G,B] = ndgrid(x,x,x);

rgb = [R(? G(? B(?];

if (n_colors > size(rgb,1)/3)

error('You can''t readily distinguish that many colors');

end

% Convert to Lab color space, which more closely represents human

% perception

if (nargin > 2)

lab = func(rgb);

bglab = func(bg);

else

C = makecform('srgb2lab');

lab = applycform(rgb,C);

bglab = applycform(bg,C);

end

% If the user specified multiple background colors, compute distances

% from the candidate colors to the background colors

mindist2 = inf(size(rgb,1),1);

for i = 1:size(bglab,1)-1

dX = bsxfun(@minus,lab,bglab(i,:)); % displacement all colors from bg

dist2 = sum(dX.^2,2);  % square distance

mindist2 = min(dist2,mindist2);  % dist2 to closest previously-chosen color

end

% Iteratively pick the color that maximizes the distance to the nearest

% already-picked color

colors = zeros(n_colors,3);

lastlab = bglab(end,:); % initialize by making the “previous” color equal to background

for i = 1:n_colors

dX = bsxfun(@minus,lab,lastlab); % displacement of last from all colors on list

dist2 = sum(dX.^2,2);  % square distance

mindist2 = min(dist2,mindist2);  % dist2 to closest previously-chosen color

[~,index] = max(mindist2);  % find the entry farthest from all previously-chosen colors

colors(i,:) = rgb(index,:);  % save for output

lastlab = lab(index,:);  % prepare for next iteration

end

end

function c = parsecolor(s)

if ischar(s)

c = colorstr2rgb(s);

elseif isnumeric(s) && size(s,2) == 3

c = s;

else

error('MATLAB:InvalidColorSpec','Color specification cannot be parsed.');

end

end

function c = colorstr2rgb©

% Convert a color string to an RGB value.

% This is cribbed from Matlab’s whitebg function.

% Why don’t they make this a stand-alone function?

rgbspec = [1 0 0;0 1 0;0 0 1;1 1 1;0 1 1;1 0 1;1 1 0;0 0 0];

cspec = ‘rgbwcmyk’;

k = find(cspec==c(1));

if isempty(k)

error('MATLAB:InvalidColorString','Unknown color string.');

end

if k~=3 || length©==1,

c = rgbspec(k,:);

elseif length©>2,

if strcmpi(c(1:3),'bla')

  c = [0 0 0];

elseif strcmpi(c(1:3),'blu')

  c = [0 0 1];

else

  error('MATLAB:UnknownColorString', 'Unknown color string.');

end

end

end

完整MATLAB源代码下载地址:

http://page5.dfpan.com/fs/3lc1j2121729e16d137/

更多精彩文章请关注微信号:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值