Example RGB to Gray

From BoofCV
Revision as of 15:12, 17 January 2022 by Peter (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

There are different methods for converting color images into gray scale images. For RGB images. the standard method in BoofCV is just to compute an average across red, green, and blue bands. Human vision doesn't work that way and it's very common to compute a weighted average, gray = 0.299*r + 0.587*g + 0.114*b. The example below demonstrates how to perform both methods. The unweighted technique is about 4x faster, but normally this step isn't the bottle neck in your vision system.

Example Code:

Concepts:

  • Color Conversion
  • RGB

Example Code

/**
 * Example which demonstrates two different ways to convert RGB images to gray scale images. The two methods
 * are weighted and unweighted. The weighted method mimics how human vision works, while the unweighted is
 * much faster. Typically the unweighted method appears more washed out than the weighted method, but still works
 * very well when passed to other computer vision algorithms.
 *
 * @author Peter Abeles
 */
public class ExampleRgbToGray {
	public static void main( String[] args ) {
		// load the image and convert it into a BoofCV data type
		BufferedImage buffered = UtilImageIO.loadImageNotNull(UtilIO.pathExample("segment/berkeley_man.jpg"));
		Planar<GrayU8> color = ConvertBufferedImage.convertFrom(buffered, true, ImageType.pl(3, GrayU8.class));

		// Declare storage space for converted gray scale images
		var weighted = new GrayU8(color.width, color.height);
		var unweighted = new GrayU8(color.width, color.height);

		// Now run a benchmark to demonstrate the speed differences between the two approaches. Both are very fast...
		System.out.println("Running benchmark. Should take a few seconds on a modern computer.\n");
		long startTime;
		int N = 2000;
		startTime = System.nanoTime();
		for (int i = 0; i < N; i++) {
			ColorRgb.rgbToGray_Weighted(color, weighted); // weigh the bands based on how human vision sees each color
		}
		double weightedFPS = N/((System.nanoTime() - startTime)*1e-9);

		startTime = System.nanoTime();
		for (int i = 0; i < N; i++) {
			ConvertImage.average(color, unweighted); // this equally averages all the bands together
		}
		double unweightedFPS = N/((System.nanoTime() - startTime)*1e-9);

		System.out.println("FPS  averaged over " + N + " images");
		System.out.println("      (higher is better)");
		System.out.println();
		System.out.printf("  weighted    %8.2f\n", weightedFPS);
		System.out.printf("  unweighted  %8.2f\n", unweightedFPS);
		System.out.println();
		System.out.printf("Unweighted is %6.1f times faster.\n", (unweightedFPS/weightedFPS));
		System.out.println();
		System.out.println("WARNING:  This is a poorly implemented microbenchmark " +
				"and results might not be accurate or consistent.");

		// Display the results
		var gui = new ListDisplayPanel();
		gui.addImage(weighted, "Weighted");
		gui.addImage(unweighted, "Unweighted");
		gui.addImage(buffered, "RGB");

		ShowImages.showWindow(gui, "RGB to Gray", true);
	}
}