Jake Webber Jake Webber - 2 months ago 16
Java Question

Detect & remove a range of colors from Java BufferedImage

I'm building an application that uses OCR to read text from an image (using Tess4J for Google's Tesseract), but I want to ignore the tan-colored text and only read the grey.

In the image below, for instance, I only want to read "Ricki" and ignore "AOA".
http://i.imgur.com/daCuTbB.png

To accomplish this, I figured removing the tan color from the image before performing OCR was my best option.

/* Remove RGB Value for Group Tag */
int width = image.getWidth();
int height = image.getHeight();
int[] pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);
for (int i = 0; i < pixels.length; i++) {
//If pixel is between dark-tan value and light-tan value
if (pixels[i] > 0xFF57513b && pixels[i] < 0xFF6b6145) {
// Set pixel to black
System.out.println("pixel found");
pixels[i] = 0xFF000000;
}
}
image.setRGB(0, 0, width, height, pixels, 0, width);


But this code removes almost all of the grey text as well. You aren't able to simply compare hex color values for a range of values the way I have. Is there another way to approach detecting a range of colors? Or a better different approach to this problem?

Answer

haraldK pointed me in the right direction by mentioning converting RGB. Bit shifting to get individual r, g, and b int values from the hex value allowed me to compare the color within a range and black out a range of colors from the image.

int baser = 108; //base red 
int baseg = 96;  //base green
int baseb = 68;  //base blue
int range = 10;  //threshold + and - from base values

/* Set all pixels within +- range of base RGB to black */
for (int i = 0; i < pixels.length; i++) {
        int a = (pixels[i]>>24)     &0xFF; //alpha
        int r = (pixels[i]>>16)     &0xFF; //red
        int g = (pixels[i]>>8)      &0xFF; //green
        int b = (pixels[i]>>0)      &0xFF; //blue

        if ( (r > baser-range && r < baser+range) && 
           (g > baseg-range && g < baseg+range) && 
           (b > baseb-range && b < baseb+range) ) {
                pixels[i] = 0xFF000000; //Set to black
        }
    }