在电脑上选择随机颜色比我想象的要难。
对R、G、B进行0..255的均匀随机抽样的天真方法往往会画出很多相似的绿色。从CIELUV这样的感知均匀空间进行采样是有意义的。
一个简单的方法是在规则网格上对L、u、v进行采样,并确保颜色实体包含在边界中(我看到了不同的边界)。如果采样落在嵌入的RGB实体之外(通过将其映射为XYZ然后映射为RGB进行测试),请拒绝它并再次采样。你可以接受一个笨拙但保证会终止的";救助;选择(就像天真的过程)如果你拒绝的次数超过某个任意的阈值。
测试样本是否在RGB范围内需要确保测试黑色的特殊情况(我相信,一些实现最终在被零除时是无声的)。如果L=0并且u=0或v=0,则需要拒绝样本,否则您将在Luv空间中对L=0平面进行过采样。
这个程序有明显的缺陷吗?这似乎奏效了,但我确实注意到,在我思考这种情况下发生了什么之前,我更多地陷入了困境。有人能给我指一下CIELUV网格上的正确边界,以确保我包围了RGB固体吗?
对于那些不知道的人来说,这是一个有用的参考:https://www.easyrgb.com/en/math.php
这方面的关键问题是,您需要边界来拒绝RGB之外的样本。我在这里找到了它(页面上的演示很好,API提供了方便的功能):https://www.hsluv.org/
我注意到在RGB中对CIELUV进行均匀采样的一些事情:
- 大多数颜色是绿色和紫色(这与RGB边界无关)
- 你很难采样我们认为的黄色(非常小的高亮度、高色度空间)
我实施了各种策略,重点是通过根据该亮度下的最大色度进行加权来采样色调(当我们想到"采样颜色"时,这确实是我们想要的)。这使得像彩色浅黄色这样的颜色更容易捕捉,并避免了对绿色和紫色的过采样。你可以在这里看到这些方法的作用(选择"随机化颜色"):
https://www.mysticsymbolic.art/
此处为颜色随机化器的来源:https://github.com/mittimithai/mystic-symbolic/blob/chromacorners/lib/random-colors.ts
好吧,虽然您没有显示用于生成随机数并将其应用于CIELUV颜色空间的代码,但我猜您正在从随机数生成器创建一个随机数0.0-100.0,然后将其分配给L*。
这很可能会给你带来很多黑色或非常暗的结果
让我解释
L*的Lu**v*对于光不是线性的
试试这个
要获得随机值为0-100:的L*
- 生成0.0到1.0之间的随机数
- 然后应用0.42的指数
- 然后乘以100得到L*
Lstar = Math.pow(Math.random(), 0.42) * 100;
这取代表光的随机数,并应用模拟人类亮度感知的功率曲线。
UV颜色
至于u和v的值,您可以将它们作为线性随机数。将u限制为大约-84和+176,将v约束为大约-132.5和+107.5
Urnd = (Math.random() - 0.5521) * 240;
Vrnd = (Math.random() - 0.3231) * 260;
极轴颜色
将uv转换为LChLUV或LshLUV可能很有趣
对于色调,它可能与H = Math.random() * 360
对于色度限制的0-178:C = Math.random() * 178
一样简单
下一个问题是,你应该找到色度吗?还是饱和?CIELUV可以提供Hue或Sat,但对于直接生成随机颜色,色度似乎要好一点。
当然,这些简单的例子并不能防止过度运行,所以它们的颜色值需要测试,看看它们是否是合法的sRGB。可以做一些事情来将生成的值限制为合法的颜色,但这里的目的是在没有过多黑/暗结果的情况下获得更好的分布。
有任何问题请告诉我。