# Grayscale Images

In this section, we'll look at the structure of grayscale vs. color images, and some code to play with that difference.

## Gray Among The RGB

• Visit the RGB explorer
• Figure out how to make colors on the grayscale spectrum
• e.g. RGB values to make: dark gray, medium gray, light gray
• We'll say that these grays lack "hue"

Answer: the RGB scale is calibrated so that when all three red/green/blue numbers of a pixel are equal, the pixel is a shade of gray. Making all the numbers equal, like red=50 green=50 blue=50 drains any bias towards red, green, or blue. If a pixel were red=50 green=75 blue=50 it would be a bit greenish, but making them all equal, it's not towards any particular hue. This works because the displays and other systems using RGB are calibrated so that the all-equal cases are on the black..gray..white spectrum.

Examples of gray colors in RGB:
red green blue color
50 50 50 dark gray
120 120 120 medium gray
200 200 200 light gray
In fact, the original pure black/white colors fit this all-equal pattern too, just using the values 0 and 255.
0 0 0 pure black
255 255 255 pure white

## Red Liberty Example Problem

Here is an image of the Statue or Liberty where all of the data is in the red values, so the whole image looks red. The green and blue values are all zero. This image looks quite wrong.

For this example, we'll write code to fix this image by copying the red value over to be used as the green and blue value. So for a pixel, if red is 27, set green and blue to also be 27. What will be the visual result of this?

 image = new SimpleImage("liberty-red.jpg"); for (pixel: image) { // your code here } print(image);

Solution code:

## Converting Color To Grayscale • How to covert a regular color image to grayscale?
• Problem: for each pixel, how dark/light is it (ignoring hue)
• Choose a few pixels out of flowers.jpg, each in a row below
• Q: which pixel is brightest? darkest?
• We compute average for each pixel
• Reminder: to average 3 numbers, add them up and divide by 3
• average = (red + green + blue)/3
red green blue average
average = (red + green + blue) / 3
200 50 50 100 (medium bright)
0 75 75 50 (darkest)
100 250 250 200 (brightest)

Looking at just red or blue or green in isolation, it's hard to tell which pixel is brightest or darkest in the above table. The average combines and summarizes the three values into one number 0..255. The average shows how bright the pixel is, ignoring hue: 0 = totally dark, 255=totally bright, with intermediate average values corresponding to intermediate brightnesses. More complicated brightness measures are possible, but average is simple and works fine for our purposes.

• Average combines red/green/blue into one number
• The average measures how bright the pixel is 0..255
• Ignoring hue

## Grayscale Conversion Example

For this example, we'll write code to change the flowers.jpg image to grayscale, using the "average" strategy: for each pixel, compute the average of its red/green/blue values. This average number represents the brightness of the pixel 0..255. Then set the red, green, and blue values of the pixel to be that average number. The result is a grayscale version of the original color image. Once its working with flowers.jpg, try it with poppy.jpg or oranges.jpg. (Solution code available below)

 image = new SimpleImage("flowers.jpg"); for (pixel: image) { // your code here } print(image);

• Q: must the "avg = ... " line be inside the loop?
• A: yes, it must be inside the loop
• The equals sign (=) does not set up some formula to work for all time
• Computer code is not that powerful generally
• The = just does math when that line runs
• Each pixel has different red/green/blue values
• We need to re-do the addition / divide-3 for each pixel

Solution code:

## Grayscale Summary

• When red/green/blue values are equal .. shade of gray
• Average combines red/green/blue into one number
• The average measures how bright the pixel is 0..255
• Convert pixel to grayscale: set red, green, and blue to be the average
• Standard code line to compute average within loop. We'll use this line often for later problems.
`avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue())/3;`