How to find "nearest" color in array of colors?

edited May 2016 in Library Questions

I'm trying to write a script that will output something akin to this kind of rubiks cube art from a source image.

I found this HPPixelColorist code snippit using the HYPE framework that is getting me fairly close but I'm having trouble figuring out a way of converting the colors that are pulled from the image into the 6 colors that are on a rubiks cube.

What's the best way of going about this?

Here's my code right now. It's using the HYPE framework (which was too long to include in that snippit) and it requires a source image to run.

Tagged:

Answers

  • edited May 2016

    This might just work:

    int getNearest(int input, int[] choices){
      int c = 0;
      int r = int(red(input));
      int g = int(green(input));
      int b = int(blue(input));
      int bestDist = 766;
      for(int i = 0; i < choices.length; i++){
        int R = int(red(input));
        int G = int(green(input));
        int B = int(blue(input));
        int dist = abs(R - r) + abs(G - g) + abs(B - b);
        if(dist < bestDist){
          c = choices[i];
          bestDist = dist;
        }
      }
      return c;
    }
    

    And these are the Rubik's cube colors:

    color[] rubiks = {color(255),
     color(250, 250, 0),
     color(250, 0, 0),
     color(0, 250, 0),
     color(0, 0, 250),
     color(250, 150, 0)};
    //WHITE, YELLOW, RED, GREEN, BUE, ORANGE
    
  • Thank you so much for replying!!!!!

    I'm quite new to programming, and very new to processing/HYPE. I'm having a bit of trouble figuring out how to implement your code into the snippit I have already.

    From what I can tell the color of the cube is set in the ".onCreate" function in my snippit but I'm not sure what to parse the getNearesst function you wrote as an input. "d" which in this case is a HDrawable object doesn't work as the function is expecting an int.

    What am I missing?

  • distances are usually done using Pythagoras ie the square root of the sum of the squares of the differences.

    you can use the built in method dist()

  • @koogs Everyone knows Pythagoras theorem. What distances are you talking about?

  • @lord_of_the_galaxy forgot to tag you in my last comment. Do you know how I implement your function into the script I'm trying to write?

  • Lord_of_the_galaxy's code is a function. So you put in at the top level under draw and then call it from draw.

  • @Eeyorelife ok, but what do I need to give the function as an argument? And where exactly is that value in my script currently?

  • edited May 2016

    Like this:

        color[] rubiks = {color(255),
         color(250, 250, 0),
         color(250, 0, 0),
         color(0, 250, 0),
         color(0, 0, 250),
         color(250, 150, 0)};
        //WHITE, YELLOW, RED, GREEN, BUE, ORANGE
    
        color f = color(100,150,50);
    
        void setup(){
          int d = (getNearest(f, rubiks));
          size(200,200);
          background(d);
          fill(f);
          rect(0,0,50,50);
        }
    
        int getNearest(int input, int[] choices){
          int c = 0;
          int r = int(red(input));
          int g = int(green(input));
          int b = int(blue(input));
          int bestDist = 766;
          for(int i = 0; i < choices.length; i++){
            int R = int(red(choices[i]));
            int G = int(green(choices[i]));
            int B = int(blue(choices[i]));
            int dist = abs(R - r) + abs(G - g) + abs(B - b);
            if(dist < bestDist){
              c = choices[i];
              bestDist = dist;
            }
          }
          return c;
        }
    

    Initially I couldn't get a result other than white, but I changed int R = int(red(input)); to int R = int(red(choices[i])); and then it worked. I assume that's how it was intended to be.

    But it doesn't always provide satisfying results. In my example the color f is green but the color d is orange.

  • edited May 2016

    What distances are you talking about?

    think of r g and b as x, y and z. you have your colour as a point in 3d space and you have the 6 rubiks colours as points in 3d space...

  • @Eeyorelife thank you so much for your help!!! I feel like I am getting very close. There's just one more thing I'm still having trouble with.

    My script is based on this code snippit. I can't figure out where to grab the input color from. My best guess is that the color is somewhere in the "HDrawable" object. But giving that as an arguement to your function doesn't work as it's expecting an INT. Any idea how to convert the HDrawable object into an INT?

  • You cannot convert an object to an int because an object is a collection of data. The code you linked to make a no sense to me. I am not nexperience enough to give you any advise on how to use that code.

  • edited May 2016

    Classes got members. We use the dot . operator in order to access them:
    https://Processing.org/reference/dot.html

  • edited May 2016

    @Eeyorelife Yeah, sorry, that was a typo. I meant to type what you did, but made mistake.
    @Jonwh Neither do I have the experience for that . Will try to analyse your code and give an answer in 2-3 day a time. There must be an integer or something else somewhere in HDrawablw class that contains the required colour. Just need to find it.

  • @koogs That is probably better method, will try implementing when I have access to a Windows computer

Sign In or Register to comment.