Nic Hooper
Nic Hooper

Reputation: 133

What am I doing wrong with this RGB to HSV colour conversion equation?

For a uni project I am making my own RGB to HSV colour converter.

Here is the code I have written

function calcSat() {
  s = (maxRGB() - minRGB()) / maxRGB();
  if (isNaN(s)) {
    s = 0;
  }
}

function calcVal() {
  v = maxRGB();
}

function calcHue() {
  var dr = (maxRGB() - r) /
    maxRGB() - minRGB();
  dr = Math.abs(dr);

  var dg = (maxRGB() - g) /
    maxRGB() - minRGB();
  dg = Math.abs(dg);

  var db = (maxRGB() - b) /
    maxRGB() - minRGB();
  db = Math.abs(db);

  console.log("red:" + r, "green:" + g, "blue:" + b);
  console.log("red d:" + dr, "green d:" + dg, "blue d:" + db);

  if (s == 0) {
    h = 0;
  } else if (r == maxRGB && g == minRGB) {
    h = 5 + db;
  } else if (r == maxRGB && g != minRGB) {
    h = 1 - dg;
  } else if (g == maxRGB && b == minRGB) {
    h = dr + 1;
  } else if (g == maxRGB && b != minRGB) {
    h = 3 - db;
  } else if (r == maxRGB) {
    h = 3 + dg;
  } else {
    h = 5 - dr;
  }

  h = h * 60;
}

You can also access a copy of the project here: https://editor.p5js.org/eeu8cc/sketches/tYfnkWrA-

Essentially, I am trying to create 3 functions to calculate the Hue, Saturation and Value of an RGB colour. Everything runs fine but my output is completely wrong.

As far as I can tell I have reproduced the equation correctly.

Here is the equation to that I am trying to re-write in code: enter image description here enter image description here

For those interested, the screenshots came from a PDF that can be found here.

Any help would be greatly appreciated.

Upvotes: 1

Views: 415

Answers (1)

Dan Mills
Dan Mills

Reputation: 589

Why are you taking absolute values for dr,dg,db? Not that there should be any way for these to go negative, and in fact if they do I would be taking that as indicating a bug further up.

I am a C and VHDL man rather then javascript, but surely

if (r == maxRGB && g == minRGB)

should rather be something like

if (r == maxRGB() && g == minRGB())?

I am assuming that == & && bind the right ways and that you don't need extra braces (I would put them in in C just because it has some obscure cases that are not worth remembering).

I also question the wisdom of floating point equality comparisons here, that seldom ends well. It would be ok, if not great design in a fixed point type but IIRC javascript tends to use FP for any numeric stuff which is just painful (And X86 does excess precision if there is not a register flush involved, which can sting with FP equalities). See Goldburgs classic paper if you want to get your math on, or this if you want something simpler https://floating-point-gui.de/

Should not maxRGB and minRGB be taking arguments (You don't show these functions) but I would expect them to take r,g,b as parameters?

I tend to deal with colour in broadcast (where we live in Y'CbCr spaces), but I also think you should probably be converting to a linear light space before doing your conversion as otherwise the gamma curves will screw you, but this is a nicety.

Upvotes: 1

Related Questions