How to find different shades of color in Java?

If I have an RBG number code, for example -16777216 (black), how can I find other similar shades of black using this color code?

I am trying to convert the image to monochrome, marking all pixels that are not -16777216 white. However, there are often various shades of black that are detected, but they are lost because they do not correspond to each other.

Edit: I have problems. When I try to use this color to search for shades of black, I can ignore them by converting other pixels to white, this is my result:

Source:

source

Result:

result

the code:

 package test; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.net.URL; import javax.imageio.ImageIO; public class Test { public static void main(String[] args) { try { BufferedImage source = ImageIO.read( new URL("http://i.imgur.com/UgdqfUY.png")); //-16777216 = black: BufferedImage dest = makeMonoChromeFast(source, -16777216); File result = new File("D:/result.png"); ImageIO.write(dest, "png", result); } catch (Exception e) { e.printStackTrace();; } } public static BufferedImage makeMonoChromeFast(BufferedImage source, int foreground) { int background = -1; //white; Color fg = new Color(foreground); int color = 0; for (int y = 0; y < source.getHeight(); y++) { for (int x = 0; x < source.getWidth(); x++) { color = source.getRGB(x, y); if ( color == foreground ) continue; if (! isIncluded(fg, color, 50)) source.setRGB(x, y, background);; } } return source; } public static boolean isIncluded(Color target, int pixelColor, int tolerance) { Color pixel = new Color(pixelColor); int rT = target.getRed(); int gT = target.getGreen(); int bT = target.getBlue(); int rP = pixel.getRed(); int gP = pixel.getGreen(); int bP = pixel.getBlue(); return( (rP-tolerance<=rT) && (rT<=rP+tolerance) && (gP-tolerance<=gT) && (gT<=gP+tolerance) && (bP-tolerance<=bT) && (bT<=bP+tolerance) ); } } 
0
source share
2 answers

You can use this search method with color difference.

 public static boolean isIncluded(Color target, Color pixel, int tolerance) { int rT = target.getRed(); int gT = target.getGreen(); int bT = target.getBlue(); int rP = pixel.getRed(); int gP = pixel.getGreen(); int bP = pixel.getBlue(); return( (rP-tolerance<=rT) && (rT<=rP+tolerance) && (gP-tolerance<=gT) && (gT<=gP+tolerance) && (bP-tolerance<=bT) && (bT<=bP+tolerance) ); } 

Here it is used to obtain the outline ( motorcycle-03.jpg ) of a motorcycle ( motorcycle.jpg ), while at the same time removing the “faint gray overlay”.

motorcycle.jpg

Original image

motorcycle 03.png

Processed image

ImageOutline.java

This code requires some patience (at startup). See Smoothing the jagged path for code that does the same thing much faster.

 import java.awt.*; import java.awt.image.BufferedImage; import java.awt.geom.Area; import javax.imageio.ImageIO; import java.io.File; import java.util.Date; import javax.swing.*; /* Motorcycle image courtesy of ShutterStock http://www.shutterstock.com/pic-13585165/stock-vector-travel-motorcycle-silhouette.html */ class ImageOutline { public static Area getOutline(BufferedImage image, Color color, boolean include, int tolerance) { Area area = new Area(); for (int x=0; x<image.getWidth(); x++) { for (int y=0; y<image.getHeight(); y++) { Color pixel = new Color(image.getRGB(x,y)); if (include) { if (isIncluded(color, pixel, tolerance)) { Rectangle r = new Rectangle(x,y,1,1); area.add(new Area(r)); } } else { if (!isIncluded(color, pixel, tolerance)) { Rectangle r = new Rectangle(x,y,1,1); area.add(new Area(r)); } } } } return area; } public static boolean isIncluded(Color target, Color pixel, int tolerance) { int rT = target.getRed(); int gT = target.getGreen(); int bT = target.getBlue(); int rP = pixel.getRed(); int gP = pixel.getGreen(); int bP = pixel.getBlue(); return( (rP-tolerance<=rT) && (rT<=rP+tolerance) && (gP-tolerance<=gT) && (gT<=gP+tolerance) && (bP-tolerance<=bT) && (bT<=bP+tolerance) ); } public static BufferedImage drawOutline(int w, int h, Area area) { final BufferedImage result = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = result.createGraphics(); g.setColor(Color.white); g.fillRect(0,0,w,h); g.setClip(area); g.setColor(Color.red); g.fillRect(0,0,w,h); g.setClip(null); g.setStroke(new BasicStroke(1)); g.setColor(Color.blue); g.draw(area); return result; } public static BufferedImage createAndWrite( BufferedImage image, Color color, boolean include, int tolerance, String name) throws Exception { int w = image.getWidth(); int h = image.getHeight(); System.out.println("Get Area: " + new Date() + " - " + name); Area area = getOutline(image, color, include, tolerance); System.out.println("Got Area: " + new Date() + " - " + name); final BufferedImage result = drawOutline(w,h,area); displayAndWriteImage(result, name); return result; } public static void displayAndWriteImage(BufferedImage image, String fileName) throws Exception { ImageIO.write(image, "png", new File(fileName)); JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(image))); } public static void main(String[] args) throws Exception { final BufferedImage outline = ImageIO.read(new File("motorcycle.jpg")); BufferedImage crop = outline.getSubimage(17,35,420,270); displayAndWriteImage(crop, "motorcycle-01.png"); BufferedImage crude = createAndWrite(crop, Color.white, false, 60, "motorcycle-02.png"); BufferedImage combo = createAndWrite(crude, Color.red, true, 0, "motorcycle-03.png"); } } 

With the code visible in the question, with a tolerance of 150, I see this.

enter image description here

+3
source

In general, I think that the way to use it is to use the sRGB gray conversion formulas described on this page on Wikipedia , and then select the specific “gray” value as the border between black and white. (The choice is up to you ...)

But say that you already have RGB values ​​representing gray dots, you should find that they all have the same red, green, and blue values. If so, then you just need to select one of the RGB color components and compare it with the same color value of your selected “gray”.

If you need to distinguish between several shades of black, gray, and white, select several boundary “colors.”


Edit: I have problems. When I try to use this color to search for shades of black, I can ignore them by converting other pixels to white, this is my result:

What you see is smoothing effects. In fact, there is very little “pure” black in the image. Many features of the human eye are actually dark or not very dark. You should make your border color (that is, the border between black and non-black) more gray.

+2
source

All Articles