I'm working on something that is able to count the number of blue/red/yellow/... pixels in an image. So far I've got this code as a test:
public class Main {
/*
Black: 0,0,0
White: 255, 255, 255
Red: 255, 0, 0
Orange: 255, 127, 0
Yellow: 255, 255, 0
Green: 0, 255, 0
Blue: 0, 0, 255
Indigo: 111, 0, 255
Violet: 143, 0, 255
*/
static int blackCount = 0;
static int whiteCount = 0;
static int redCount = 0;
static int orangeCount = 0;
static int yellowCount = 0;
static int greenCount = 0;
static int blueCount = 0;
static int indigoCount = 0;
static int violetCount = 0;
static int otherCount = 0;
static int totalCount = 0;
public static void main(String[] args) {
try {
String path = "src/colors.jpg";
BufferedImage image = ImageIO.read(new File(path));
int w = image.getWidth();
int h = image.getHeight();
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Color c = new Color(image.getRGB(x, y));
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
countColor(red, green, blue);
totalCount++;
}
}
printColors();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
private static void countColor(int red, int green, int blue) {
if (red == 0 && green == 0 && blue == 0) blackCount++;
else if (red == 255 && green == 255 && blue == 255) whiteCount++;
else if (red == 255 && green == 0 && blue == 0) redCount++;
else if (red == 255 && green == 127 && blue == 0) orangeCount++;
else if (red == 255 && green == 255 && blue == 0) yellowCount++;
else if (red == 0 && green == 255 && blue == 0) greenCount++;
else if (red == 0 && green == 0 && blue == 255) blueCount++;
else if (red == 111 && green == 0 && blue == 255) indigoCount++;
else if (red == 143 && green == 0 && blue == 255) violetCount++;
else otherCount++;
}
private static void printColors() {
System.out.println("Black: " + blackCount);
System.out.println("White: " + whiteCount);
System.out.println("Red: " + redCount);
System.out.println("Orange: " + orangeCount);
System.out.println("Yellow: " + yellowCount);
System.out.println("Green: " + greenCount);
System.out.println("Blue: " + blueCount);
System.out.println("Indigo: " + indigoCount);
System.out.println("Violet: " + violetCount);
System.out.println("Other: " + otherCount);
System.out.println("Total: " + totalCount);
}
But you might notice the problem... In RGB, the color "Red" is defined as (255, 0, 0). Therefore, an image containing a lot of red may return "0" because the color used in the image is (254, 0, 0) and not (255, 0, 0).
So I actually want to count not only the pure red pixels, but all "redish" pixels. I assume there is an easier way to pull this off than writing an insane long if (red = 255), if (red = 254),... structure?
You can convert pixels being processed into more convenient color model, namely HSL or HSV.
Then it could be simplier to define ranges of component values that belong to particular groups (reddish/blueish/etc).
I would consider trying to determine which of the three constants is the greater in your color. If the amount of red is greater than the amount of blue and the amount of green, you might suppose that your color is "redish". The same goes with blue and green.
However, you might want to take into account some corner cases:
xkcd conveyed a very interesting survey on the subject of colors. I recommend you check it out for more details about how colors works, and it might give you some hits as to which values make a color "redish", "greenish" and "blueish". The results are very interesting, but shows a lot of interesting cases where color detection is non trivial. Colors can be perceived differently by different people, influenced by sex, color-blindness and LOT of others factors.
Also, the survey includes lots of color names for lots of RGB constants that you could use. And it also comes with a map of color names!
I truly believe that colors are a very interesting topic, however it is really complicated and you should get as much information on the subject before actually deciding how to write your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With