1

Function parameters: input image, first color, second color

I am taking an image, looking at the height and width of it then iterating through to find a pixel. If the pixel color is closest to the first color (color1) then change that pixel color to color1, if the pixel color is closest to color2 then change it to color2. My problem is believed to be at the code abs(color2-color1)/2 when trying to compare the two parameter colors.

void Preprocessor(BMP pix, RGB color1, RGB color2) {
    int height = pix.GetHeight();
    int width = pix.GetWidth();

    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (pix[i][j]->red + pix[i][j]->green + pix[i][j]->blue >
                abs(color2 - color1) / 2) { // pixel color closest to color1

                pix[i][j] = color1;
                pix[i][j] = color1;
                pix[i][j] = color1;
            } else { // pixel color closest to color2
                pix[i][j] = color2;
                pix[i][j] = color2;
                pix[i][j] = color2;
            }
        }
    }
}
NetVipeC
  • 4,402
  • 1
  • 17
  • 19
user3602550
  • 39
  • 1
  • 7
  • 1
    Is there an implementation of `operator-( RGB, RGB )` and `operator/( RGB, int )`? – Khouri Giordano Oct 06 '14 at 17:42
  • 1
    The statements `pix[i][j] = color1` and `pix[i][j] = color2` only need to be executed once, but that's mostly harmless. – Khouri Giordano Oct 06 '14 at 17:44
  • I don't think you can substract colors in the way you do at the abs(). You are also comparing a color with a difference in color. I would recommend looking at this answer: http://stackoverflow.com/a/9018153/1928529 With the comparison described there you could get the distance pix[i][j]<->color1 en pix[i][j]<->color2, and then simply check which color is nearest to the pixel. – Dennis van der Schagt Oct 06 '14 at 17:48

1 Answers1

1

Choosing the correct metric

The problem of which color is closer to this one is non trivial problem. There can be several approaches to combat this question. You might want to roughly have the same luminosity or maybe hue or vibrance, or something else for that matter.

So you chose abs(color2 - color1) / 2 and this does not have any intuitive value. You may consider explaining what was your reasoning for this exact approach.

I suggest that you start with brightness (kind of). Lets say that you want to estimate the distance of a color from a different color in a Taxicab metric. And then choosing the smaller one.

// Taxicab metric (Manhattan)
double distance(RGB c1, RGB c2) {
  return 
          abs(c1->red - c2->red) 
        + abs(c1->green - c2->green) 
        + abs(c1->bule - c2->blue);
}

void Preprocessor(BMP pix, RGB color1, RGB color2) {
  int height = pix.GetHeight();
  int width = pix.GetWidth();

  for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        double d1 = distance(color1, pix[i][j]);
        double d2 = distance(color2, pix[i][j]);

        if (d1 < d2) { // pixel color closest to color1
            pix[i][j] = color1;
        } else { // pixel color closest to color2
            pix[i][j] = color2;
        }
    }
  }
}

Considerations

You might want to also experiment with other metrics (Euclidean) and also with other color schemes that are more suitable to comapre in this way HSV, HSL

mrVoid
  • 995
  • 7
  • 17