如何向图像添加滤色器,使其平均 RGB 更接近该颜色?

How do I add a color filter to an image so that its average RGB gets closer to that color?

我有一张 100x100 的图片:

<img id="my-face" src="/my-face.jpg" />

我获取了它的所有像素,并且我 calculate the average RGB 该图像:

let img = document.getElementById('my-face')
let avgRgbOfImg = getAverageRGb(img)

我还有一个不同颜色的参考RGB:

let refRgb = [255, 244, 50] // yellow

我知道现在想给图像添加滤镜,这样 avgRgbOfImg 就非常接近我的 refRgb:

addFilter(refRgb).to(img)
let newAvgRgb = getAverageRGb(img) // should be pretty close to `refRgb` (yellow)

简单来说,我有一张图片,我想使用 canvas(或 p5.js)为其添加滤色器,使其 avgRgbOfImg 非常接近那种颜色。

是否有一些 canvas/p5 套方法可以实现这一目标?

使用 RGB 获得平均颜色的有趣方法。

过去我回答过一个含糊不清的类似问题,但是 doing basic image search based on average colour. Instead of RGB colour space I've used Lab* colour space which is a perceptual colour space. I simply used this implementation of the rgb2xyz -> xyz2lab and back formulas from here(如果你去掉一些关键字和类型,语法就差不多 javascript 顺便说一句)

您可能会得到更好的结果,但根据您发布的演示,希望不会有太大的不同。它是否证明了复杂性:不确定。

说到复杂性,您可以一路走到深度神经网络。进行快速搜索,Progressive Color Transfer with Dense Semantic Correspondences along with a related implementation. Maybe in a roundabout way that PyTorch model could be trained and exported to Tensorflow.js (PyTorch -> ONNX -> TensorFlow -> TensorFlow.js) and used directly or integrated with ml5.js similar to the StyleTransfer model。 也许它会产生有趣的结果,但这肯定是一种复杂的方法。

如果您已经知道图像的平均 RGB 颜色并且您正在寻找 approximation/similar 看看如何通过简单地通过 tint() 给图像着色来“伪装”它。您甚至可以使用第 4 个(alpha)参数控制色调量:

// apply 50% of refRgb
tint(refRgb[0], refRgb[1], refRgb[2], 128);
image(theImageYouWanTinted, 0, 0);

当然,输出将是源图像和 refRgb 的混合,但如果在视觉上达到您想要的效果,则非常容易测试。

然后您可以扩展并尝试其他内容,例如:

  • 使用要着色的图像的灰度版本而不是 rgb 版本
  • 根据图像内容,单一颜色通道可能具有更显着/更吸引人的特征(例如,使用红色、绿色或蓝色通道作为灰度而不是真正的灰度)
  • 进一步过滤源图像以尝试提取相关信息(例如,使用中值滤波器稍微平滑图像,尝试低通滤波器等)

很难衡量事情需要多么精确和复杂:我只是先选择 tint()。 (如果您需要将着色结果“冻结”为像素,请记住您始终可以获得使用 get() 绘制的内容的“快照”,使用 p5.Graphics 层可以实现更复杂的事情(请参阅 createGraphics()));