developer tip

실제 색상을 혼합하는 것과 같은 색상 혼합 알고리즘이 있습니까?

optionbox 2020. 12. 26. 09:58
반응형

실제 색상을 혼합하는 것과 같은 색상 혼합 알고리즘이 있습니까?


RGB 색상의 일반적인 혼합은 그림을위한 색상 혼합과는 매우 다르며 안료를 혼합하는 대신 빛을 혼합하는 것입니다.

예를 들면 :

Blue (0,0,255) + Yellow (255,255,0) = Grey (128,128,128)

(파란색 + 노란색 = 녹색이어야 함)

실제 색상을 혼합하는 것처럼 작동하는 색상 혼합에 대한 알려진 알고리즘이 있습니까?


내 접근

나는 이미 다음을 시도했습니다.

두 색상을 HSV로 변환하고 색상 혼합 (채도에서 계산 된 계수로 곱함), 채도 및 값 채널에 대한 단순 평균. 그런 다음 두 색상에서 평균 휘도를 계산하고 결과 색상을이 휘도와 일치하도록 조정했습니다. 이것은 꽤 잘 작동했지만 색조 혼합이 때때로 잘못되었습니다. 예 :

Red (Hue 0°) + Blue (Hue 240°) = Green (Hue 120°)

때로는 색조 값을 360 ° (색조 차이가 180 °보다 클 때) 이동해야한다는 것을 알아 냈습니다.

Red (Hue 360°) + Blue (Hue 240°) = Magenta/fuchsia (Hue 300°)

그러나이 변화도 그다지 좋지 않았습니다. 예 :

Cyan (Hue 179°) + Red (Hue 0°) = Hue 89.5°
Cyan (Hue 181°) + Red (Hue 0°) --> shifting is performed (the difference is greater than 180°)
Cyan (Hue 181°) + Red (Hue 360°) = Hue 270.5°

(Hue 179 + Red)와 (Hue 181 + Red)는 완전히 다른 두 가지 색상을 만듭니다.


그런 다음 인간이 색상을 인식하는 방식에 더 가깝게 설계된 CIE Lab 색상 공간 (Photoshop에서와 같이)을 시도했습니다 .

각 해당 두 채널에 대해 단순한 평균을 사용했지만 결과는 만족스럽지 않았습니다. 예를 들어 파란색 (98, -16, 93) 중 분홍색 (64, 26, -9.5)과 노란색 (30, 68, -112). 이 계수는 Photoshop에서 가져 왔습니다.

평균과 다른 작업을 사용하면 작동 할 수 있지만 무엇인지 모르겠습니다.


CMYK도 작동하지 않았고 결과는 RGB 또는 LAB와 같습니다.


이러한 색상 공간에서 사소한 가산이나 감산 색상 혼합이 자연스러운 결과 얻지 못하는 것 같습니다 .


작업 구현

Krita – Painterly 믹서

래스터 그래픽 편집기 Krita는 어느 시점에서보다 사실적인 색상 혼합을 구현했습니다. http://commit-digest.org/issues/2007-08-12/ (Painterly 믹서 플러그인)

그들은 안료의 동작을 설명하는 Kubelka 및 Munk 방정식을 사용하여 특수 기술을 구현 한 최초의 공개 응용 프로그램이라고 말합니다.

다음은 Krita 색상 혼합에 대한 비디오입니다. https://www.youtube.com/watch?v=lyLPZDVdQiQ

FiftyThree의 논문

FiftyThree에서 개발 한 iOS 용 Paper 앱의 색상 혼합에 대한 기사 도 있습니다 . 그들은 그 지역에서 어떻게 혁신하고 실험하는지 설명하고 녹색을 만드는 파란색과 노란색을 혼합 한 샘플도 제공합니다. 그러나 실제 프로세스 또는 알고리즘은 실제로 설명되어 있지 않습니다.

인용 :

"좋은 블렌딩 알고리즘을 찾기 위해 처음에는 RGB, HSV, HSL, CieLAB 및 CieLUV와 같은 다양한 색상 공간에 걸쳐 보간을 시도했습니다. 결과는 실망 스러웠습니다."라고 Chen은 말합니다. "우리는 빨간색과 노란색이 주황색을 나타내거나 빨간색과 파란색이 보라색이되어야한다는 것을 알고 있습니다.하지만 어떤 색 공간을 사용하든 이러한 색상에 도달 할 수있는 방법은 없습니다. 엔지니어링 공리가 있습니다. 가능할 수도 있습니다. 이제 우리는 가능한 가장 쉬운 접근 방식을 시도했지만 원격으로도 옳다고 생각하지 않았습니다. "

Krita와 동일하게 Paper는 Kubelka-Munk 모델을 구현합니다.

[...] Kubelka-Munk 모델에는 각 RGB 색상에 대한 반사 및 흡수 값을 포함하여 각 색상에 대해 최소 6 개의 값이 있습니다. FiftyThree의 공동 설립자이자 CEO 인 Georg Petschnigg는 "화면에 나타나는 색상은 3 차원으로 설명 할 수 있지만 색상 혼합은 실제로 6 차원 공간에서 발생합니다."라고 설명합니다. Kubelka-Munk 논문을 통해 팀은 미적 문제를 수학적 프레임 워크로 변환 할 수있었습니다. [...]

이 모든 정보 에서 Kubelka-Munk 모델을 기반으로 한 구현이 앞으로 나아가고 현실에 훨씬 더 가까운 결과를 제공 할 수있는 것으로 보입니다 .

복잡한 프로세스처럼 보이지만 이와 같은 구현 방법에 대한 좋은 정보는 아직 많이 보지 못했습니다.


관련 질문

이 질문들은이 질문 뒤에 모두 같은 것에 관련된 것입니다.

그들 중 누구도 답을 가지고 있지 않습니다.


기타 관련 링크 및 리소스


올바른 전혀 없기 때문에 대답은 NO입니다 올바른 작업 "현실 세계에서 혼합 색상이"정말 작동하는 방법의 모델. 그것은 너무 복잡하고 조건 적이며 우리가 학교에서 배운 단순한 Red-Blue-Yellow와는 전혀 다릅니다 (사실 해결하려면 모든 화학과 많은 물리 및 생물학이 필요합니다).

그러나, 단순한 답은 YES, 사용 감산 보다는 혼합 첨가제가 혼합.

우리가 초등학교에서 배운 색상 혼합은 (매우 간단하게) 감산 색상 혼합의 한 형태 인 안료 조합을 기반으로합니다. 그것은 우리가 더 많은 색상을 더할수록 각 안료가 조금 더 많은 빛을 빼기 때문에 더 어두워집니다.

On the other hand, almost all computer color-schemes are additive in that they are based on combining light waves (very simplistically), so they get brighter, because each color adds a little bit more light.

The RGB+ scheme is somewhat, the additive complement to the subtractive scheme that we learned in most US elementary schools (which is RBY-). However, they do not match up exactly and it can be difficult to convert between them (researching now ...)


OK, if you just want to switch from additive combinations in RGB to subtractive ones, you can use the following reverse-bayesan type formula to combine two colors:

NewColor.R = (Color1.R * Color2.R)/255
NewColor.G = (Color1.G * Color2.G)/255
NewColor.B = (Color1.B * Color2.B)/255

Adjusting for the difference in the chromatic poles (G to Y, then back to G) is a lot harder ...


It has been pointed out that this produces Black for the example problem, and technically this is correct for a true subtractive system, however, if you want more diluting/subtractive system, you could try this instead:

NewColor.R = 255 - SQRT(((255-Color1.R)^2 + (255-Color2.R)^2)/2)
NewColor.G = 255 - SQRT(((255-Color1.G)^2 + (255-Color2.G)^2)/2)
NewColor.B = 255 - SQRT(((255-Color1.B)^2 + (255-Color2.B)^2)/2)

This produces a dark grey instead of Black. But to get Yellow or anything close, you still have to fix the color-scheme's pole-alignment problem.


there are two different possibilities combining colors:

  1. additive mixing (like RGB)

  2. subtractive mixing (like CMYK)

So in subtractive color mixing the result is what you expected, but there is no blue, instead there is cyan:

Yellow + cyan = green

In general subtractive color mixing is just "taking away" (filtering) from white while additive color mixing is adding up from black. (base colors of subtractive are inverse from additive: red ->cyan; green->magenta; blue->yellow)

So if you start with white screen applying filters:

min( white (255,255,255), yellow (255,255,0), cyan (0,255,255)) = green (0,255,0)


There is code to mix colors in a realistic way in krita: https://projects.kde.org/projects/calligra/repository/revisions/master/show/krita/plugins/extensions/painterlyframework.

Note that the code including the illuminants file is GPLv2+. It can convert from RGB to wavelengths, do composition and convert back.


I think your problem with combining hues is that you are doing it by adding together the two angles and dividing by two. As you've noticed, the result often makes no sense. I think you'd be better off converting the angles to Cartesian coordinates on the unit circle, averaging those, and finding the angle of the resulting point (ignoring the magnitude).


One way to do subtractive mixture of RGB colors is to first convert the RGB colors to spectral reflectance curves. The conversion is fairly simple, and once you've done it, you can do a true subtractive mixture of the reflectance curves, and then convert the result back to RGB. There is another similar question: stackoverflow.com/questions/10254022/, where this process is discussed in more detail.


Wondering if calculation of inversion of the RGB value work. Since it's about subtraction of lights, technically the subtraction part can be calculated by simple math.

For example cyan + yellow

cyan = 0x00ffff yellow = 0xffff00

Their inversions are 0xff0000 and 0x0000ff, meaning they absorbed red and blue lights completely. Their 1:1 mixture should absorb half of red and blue lights (since the other half of the mixture can still reflects some red and blue light), which is consistent with (0xff0000 + 0x00ffff) / 2 = 0x7f007f. Now we subtract the value from 0xffffff we have 0x80ff80 which is green!


Check this implementation for additive, substractive and other mixing alghoritms.

Is fully functional (writed in java), so you can test whatever colors you need to mix, and see if it fit your needs.

As other responses pointed, Blue + Yellow (exactly Cyan + Yellow) is Green on substractive CMYK alghoritm. See by yourself

ReferenceURL : https://stackoverflow.com/questions/1351442/is-there-an-algorithm-for-color-mixing-that-works-like-mixing-real-colors

반응형