7

Is anyone aware of where to find or implement the Kubelka-Munk function to mix colour like natural paint? Emanuelle Tamponi implemented this function in Krita, an open source project, but I can't find anywhere that this, or a similar method, is shared to 'naturally' mix colours. It may be that it's commercially sensitive or private, but if you don't ask you won't find out!

Peter O.
  • 32,158
  • 14
  • 82
  • 96
glenstorey
  • 5,134
  • 5
  • 39
  • 71
  • Are you asking if anyone has implemented this in Cocoa? The function itself is [easily found](http://www.chemistry.nmsu.edu/studntres/chem435/Manuals/Cary_100/Cary_100_app_maths/source/app_maths/mt_kubelka_munk_function.htm) via Google. – Rob Keniger Apr 21 '12 at 00:40
  • Good spotting. No I'm asking how to use this function, or similar, to naturally mix colours - such as shown in the video. I think the tricky part will be converting rgb values to the inputs of the function. – glenstorey Apr 21 '12 at 01:17

3 Answers3

8

Feel free to re-use the code we have in krita. It's in calligra/krita/plugins/extensions/painterlyframework. It does need the pigment library as a back-up, but I guess you can easily abstract away from that.

Note however that the code is under the GPLv2+ license. If you reuse the code or the illuminants files your code also need to be GPL.

(for more info, please contact me -- boud@valdyas.org or boud on #krita on irc.freenode.net, I'm the maintainer for Krita).

  • Thanks so much for answering! I'm away for a week but will send you an email after that. – glenstorey Apr 22 '12 at 04:10
  • Looks like this is no longer in the current Krita code, did it ever evolve in to something else in Krita? Digital Colors Mixer seems closest. – Gnaural Dec 13 '17 at 14:01
  • 1
    The source is on github buried in the history: https://github.com/KDE/krita/tree/7036146c5a75e53196a20a3e4232313d796de9d9/krita/plugins/extensions/painterlyframework – CyberFox Nov 26 '19 at 04:02
4

Here's an implementation I created that uses a simplified Kubelka-Munk model. It assumes assumes all colors have the same concentration when blending and that all colors are opaque. If it is useful feel free to use it in whatever manner you wish.

https://github.com/benjholla/ColorMixer

Ben Holland
  • 2,309
  • 4
  • 34
  • 50
  • Thank you for sharing your color mixer implementation. However, I think that it doesn't work correctly. For example for mixing red (255, 0, 0) with yellow (255, 255, 0) I should get a kind of orange: (255, 128, 0 for example) but I get: 255, 2, 1, which is the same red. Any ideas? Am I doing something wrong? – Tamás Pap Feb 18 '13 at 12:16
  • No your are right, looks like there may be some mixing problems with my implementation still. I tried converting my RGB colorspace to RYB to work with, but that didn't fix it. I'm a little stumped by a few of the color mixes it is spitting out. Many seem correct however... – Ben Holland Mar 31 '13 at 18:00
4

There is not enough information provided by RGB values alone to perform a true Kubelka-Munk computation, as you need both absorbance and scattering curves across the visible spectrum. Instead, you could generate representative reflectance curves from RGB values, and then use the reflectance information to perform the subtractive mixture, for example, by computing the weighted geometric mean of the two reflectance curves.

Scott Burns
  • 81
  • 1
  • 4
  • 1
    This Matlab code will convert sRGB to wavelength-based spectral reflectance: `function reflectance=LSS(B12,sRGB) % compute target "linear rgb" values sRGB=sRGB(:)/255; % convert to 0-1 column vector for i=1:3 if sRGB(i)<0.04045 rgb(i)=sRGB(i)/12.92; else rgb(i)=((sRGB(i)+0.055)/1.055)^2.4; end end reflectance=B12*rgb;` Matrix B12 is found [here.](http://scottburns.us/wp-content/uploads/2015/04/B12-matrix.txt) Once two sRGB colors have been converted to reflectance curves, mix the curves (average them or better yet, get their "weighted geometric mean"). – Scott Burns May 01 '15 at 09:28
  • Sorry about the mashed code. I can't figure out how to get a line break in comments. – Scott Burns May 01 '15 at 09:36
  • Also, if any of the reflectance values come out negative in the above code, then a [somewhat more complex version](http://scottburns.us/wp-content/uploads/2015/04/ILSS.txt) needs to be used. – Scott Burns May 01 '15 at 11:45
  • Correction: don't average the reflectance curves as I suggested. That will give you the same result as simply averaging the RGB values! Instead, use the [weighted geometric mean](http://en.wikipedia.org/wiki/Weighted_geometric_mean) to simulate paint mixture, or multiply the curves together if you want to simulate overlapping color filters, which is a much "stronger" subtractive mixture. – Scott Burns May 07 '15 at 10:52
  • Why not just edit your answer instead of putting code in the comments? What is LSS? – slashdottir Feb 11 '23 at 20:29