Compute opponent colour of RGB values

19 次查看(过去 30 天)
Devin
Devin 2011-1-25
I'm looking for a script in which I can compute the RGB values corresponding to the opponent color of another set of RGB values.
So, I would provide the three RGB values for a colour (e.g., red) and then get the RGB values for the opponent colour (green).
Any thoughts/suggestions on this, would be great.
  1 个评论
Walter Roberson
Walter Roberson 2011-1-25
编辑:Walter Roberson 2021-9-19
Please define what you mean by "opponent colour". Is that the Gaussian Color model, such as is illustrated in
Would it be sufficient to use CIE 1964 and the transformation shown on page 9 of the above pdf?

请先登录,再进行评论。

回答(5 个)

the cyclist
the cyclist 2011-1-25
I think, but I am not sure, that you are talking about the "complementary" color.
If your RGB color vector is [r g b], where each value is in the range [0,1], then I believe your complementary color vector is ([1 1 1]- [r g b]).
Note, the complement of red is cyan, not green, so maybe I just misunderstand your question.
  4 个评论
Image Analyst
Image Analyst 2021-9-19
What I'd probably do is to convert the RGb value to HSV color space, then swing the hue around by 180 degrees (add or subtract .5):
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
fprintf('Beginning to run %s.m ...\n', mfilename);
rgbImage = imread('peppers.png');
subplot(2, 1, 1);
imshow(rgbImage);
impixelinfo; % Show RGB as you mouse over image.
title('Original RGB Image', 'FontSize', fontSize);
% Convert to HSV color space.
hsvImage = rgb2hsv(rgbImage);
hImage = hsvImage(:, :, 1);
sImage = hsvImage(:, :, 2);
vImage = hsvImage(:, :, 3);
% rotate hues around by 180 degrees.
newHueImage = rem(hImage + 0.5, 1);
hsvImage(:, :, 1) = newHueImage;
% Convert back to RGB color space.
newRGBImage = hsv2rgb(hsvImage);
subplot(2, 1, 2);
imshow(newRGBImage);
impixelinfo; % Show RGB as you mouse over image.
title('New RGB Image', 'FontSize', fontSize);
g = gcf;
g.WindowState = 'maximized';
fprintf('Done running %s.m.\n', mfilename);
Adam Danz
Adam Danz 2021-9-19
编辑:Adam Danz 2021-9-19
Thanks for the demo @Image Analyst. I'll have to look into the differences between that and imcomplement.
rgbImage = imread('peppers.png');
subplot(1,2,1);
imshow(rgbImage);
title('Original RGB Image');
newRGBImage = imcomplement(rgbImage);
subplot(1,2,2);
imshow(newRGBImage);
title('New RGB Image');

请先登录,再进行评论。


Kenneth Eaton
Kenneth Eaton 2011-1-25
If you are talking about a color opponent process, I figured out a simple function that will compute opponent colors for the six colors involved in the three opponent channels: black vs. white, red vs. green, and blue vs. yellow:
opp_color = @(c) [~c(1:2) ~c(3).*~xor(c(1),c(2))];
Given one of the six colors, it will return the opponent color. Here is a test where I have generalized opp_color to operate on rows of an input N-by-3 matrix of colors:
>> opp_color = @(C) [~C(:,1:2) ~C(:,3).*~xor(C(:,1),C(:,2))];
>> cmat = [0 0 0; 1 1 1; 1 0 0; 0 1 0; 0 0 1; 1 1 0]; % Six colors
cmat =
0 0 0
1 1 1
1 0 0
0 1 0
0 0 1
1 1 0
>> opp_color(cmat) % Opponent colors
ans =
1 1 1
0 0 0
0 1 0
1 0 0
1 1 0
0 0 1
This of course only works for these six colors. I don't know exactly how the theory works for lighter or darker versions or for mixtures of colors, but maybe this will still be useful to you. ;)
EDIT:
Here's a different version of the function opp_color, still only applicable to the six colors given above:
opp_color = @(C) (1-C).*[ones(size(C,1),2) C(:,1)==C(:,2)];
  1 个评论
Walter Roberson
Walter Roberson 2011-1-25
Unfortunately this is not extensible to fractional colors. The ~ could possibly be replaced by subtraction from 1, but the equivalent to the xor is not obvious.

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2011-1-26
I approached this as a system of simultaneous equations that had to be satisfied. For example, it is not as easy as Red being in opposition to Green, as Red and Green combine to make yellow and we have to make the yellow opposite to the Blue.
I had to make some assumptions about how to measure "yellowness"; I decided to use the geometric mean of red and green, sqrt(R*G). Possibly min(R,G) would be a better measure, but one more difficult to work with analytically.
For black versus white, I used the typical luminance, 0.3*R + 0.59*G + 0.11*B and assumed that "blackness" is 1 minus the luminance.
I used R, G, B in the 0 to 1 range.
Proceeding symbolically in Maple with R0, G0, B0 being the initial values, and R1, G1, B1 being the complimentary values, I defined
L := (R, G, B) -> (3/10)*R+(59/100)*G+(11/100)*B;
and then
solve({R0-G0 = G1-R1, sqrt(R0*G0)-B0 = B1-sqrt(R1*G1), L(R0, G0, B0) = 1-L(R1, G1, B1)}, [R1, G1, B1]);
this resulted in an expression with some resolvable quadratics. Expanding the quadratics and collecting terms, I got
S := sqrt(40000 - 8800*sqrt(R0)*sqrt(G0) - 35600*G0 - 35600*R0 + 31926*R0*G0 + 3916*sqrt(R0)*G0^(3/2) + 3916*R0^(3/2)*sqrt(G0) + 121*G0^2 + 121*R0^2);
[
R1 = -(15721/15600)*R0 - (121/15600)*G0 + 89/78 - (979/7800)*sqrt(R0)*sqrt(G0) + (11/15600)*S
G1 = 89/78 - (979/7800)*sqrt(R0)*sqrt(G0) - (15721/15600)*G0 - (121/15600)*R0 + (11/15600)*S
B1 = (979/15600)*G0 - B0 - 11/78 + (7921/7800)*sqrt(R0)*sqrt(G0) + (979/15600)*R0 - (89/15600)*S
]
and
[
R1 = -(15721/15600)*R0 - (121/15600)*G0 + 89/78 - (979/7800)*sqrt(R0)*sqrt(G0) - (11/15600)*S
G1 = 89/78 - (979/7800)*sqrt(R0)*sqrt(G0) - (15721/15600)*G0 - (121/15600)*R0 - (11/15600)*S
B1 = (979/15600)*G0 - B0 - 11/78 + (7921/7800)*sqrt(R0)*sqrt(G0) + (979/15600)*R0 + (89/15600)*S
]
In testing these out, the second set produces reasonable answers more often than the first. Both sets produce unreasonable answers for some triples: presumably my model of "yellowness" computed from the RGB triple is flawed.

Devin
Devin 2011-1-26
Greetings. Thanks for all of your responses. Yes, I was referring to the opponent color - so I did mean green as the opponent to red. It seems that Walter's script is getting quite close, but as you mention it still has some flaws. Kenneth, thanks for your response as well. We will actually be needing to compute the opponent RGB value for a large variety of different colors, so six, as you sugggest, would be too small of a pool.
Nevertheless, thanks for your help.
If anyone else has any ideas I would be appreciative.
cheers, Devin

shima
shima 2011-2-27
hello guys...
im doing a research on image processing to find the most suitable technique to get the range of red color... as i do not have any background on image processing please tell me what are different techniques of color detection? thank you
  1 个评论
Walter Roberson
Walter Roberson 2011-2-27
Hi, I see you have created a new Question for this topic, as is appropriate, as it does not have anything to do with the opponent color process.

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by