Search code examples
javaimagepngjpeg

How to threshold any image (for black and white color seperation) in java?


SOLVED : Issue was "jpeg compression". Saving as ".png" worked.

I had detected edges of an image using a canny filter program in java. After applying filter ...

This is my image If zoomed in ... Zoomed

All have different shades of black and white.
I want all my edge pixels as pure white(#FFFFFF) and the remaining portion black.

Note: Different pixels may have different shades apart from the one above(#F7F7F7). The zoomed image above is just an example.

Edit: I had written this code to take effect on image ...

public void convert(){
    try{
        BufferedImage img = ImageIO.read(new File("input.jpg"));
        int rgb;
        int height = img.getHeight();
        int width = img.getWidth();
        File f = new File("newThreshold.jpg");
        Color white = new Color(255,255,255);
        int wh = white.getRGB();

        for (int h = 0; h<height; h++){
            for (int w = 0; w<width; w++){  

                rgb = img.getRGB(w, h);
                red = (rgb & 0x00ff0000) >> 16;
                green = (rgb & 0x0000ff00) >> 8;
                blue  =  rgb & 0x000000ff;
                if(red >= 200 || blue >= 200 || green >= 200){
                     img.setRGB(w,h,wh);
                }
            }
        }

        ImageIO.write(img,"jpg",f);
    }
    catch(Exception e){
    }
}

Even after running the code, there is no change in my image.
Even if the red, green and blue values are above 200, my image is not changing.

UPDATE: Saving the image as ".png" rather than ".jpg" worked!


Solution

  • You can go through each pixel in the image and determine if it is above a certain threshold, if it is set its value to pure white. You can also do the same for the darker areas if needed.

    Example:

    public Image thresholdWhite(Image in, int threshold)
    {
        Pixel[][] pixels = in.getPixels();
        for(int i = 0; i < pixels.length; ++i)
        {
            for(int j = 0; j < pixels[i].length; ++j)
            {
                byte red = pixels[i][j].getRed();
                byte green = pixels[i][j].getGreen();
                byte blue = pixels[i][j].getBlue();
                /* In case it isn't a grayscale image, if it is grayscale this if can be removed (the block is still needed though) */
                if(Math.abs(red - green) >= 16 && Math.abs(red - blue) >= 16 && Math.abs(blue- green) >= 16)
                {
                    if(red >= threshold || blue >= threshold || green >= threshold)
                    {
                        pixels[i][j] = new Pixel(Colors.WHITE);
                    }
                }
            }
        }
        return new Image(pixels);
    }