Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Color Reduction Python 3.4 help please Many years ago computers couldn’t display

ID: 3762252 • Letter: C

Question

Color Reduction Python 3.4 help please

Many years ago computers couldn’t display 1000’s of colors. Images would have their color

reduced. Now color reduction can be used to create image effects to give it a cartoonish look.

Reduction is also used for some visual systems in robotics and other applications to help

recognize objects. For this assignment we will read an image in the PPM format, and adjust the

colors to be the closest of a choice of colors.

The image on the left has the possibility of 16,777,216 colors, while the picture on the right uses

5 possible colors

PPM Files

Portable PixMap format or PPM is a simple image file format. There are a few variants of the

PPM format, but we will be concentrating on one particular specification of the text file versions.

Since it’s just a normal text file, we can open, read and write the image files just like they were

any normal text document. This makes it very convenient since we can use all the Python file

handling techniques we’ve learned this semester. We have included ppmReader.htmlto view

the ppm files that have been supplied. You may also want to use an image editor like gimp to

view the images ( http://www.gimp.org). You will also want to examine the files in a text editor.

PPM Format ( Ocean.ppm )

Line # Example Data Description

1 P3 PPM Header information. P followed by a number.

We’ll be using the P3 format.

2 3072 2304 Size of the image in pixels. This 3072 wide and 2304

pixels tall.

3 255 Color Depth of the Image. Each Red, Green, Blue

component will be 0­255 in value. This is always 255

in our examples.

4 143 Red Component of the first pixel.

5 211 Green component of the first pixel

6 255 Blue Component of the first pixel

7 144 Red component of the second pixel

... ... ...

21233665 80 Red component of last pixel

21233666 112 Green component of last pixel

21233667 135 Blue Component for the last pixel.

The PPM format is very flexible. In our incarnation each color component is on a separate line.

We also will not have any comments in the header. If you save an ASCII ppm file from gimp

you will have to edit the resulting text file and remove the comment from the header.

Color Reduction

We will be reducing an image down to 5 colors Red, Green, Blue, White, and Black. Each pixel

is made up of a red, green and blue component. In the files we will be working with each has

256 values from 0 ­ 255. You can imagine each pixel color being a point in a 3 dimensional

model.

You’ll notice that the color at the back of 0, 0, 0 is black. If you follow out the red direction you’ll

notice the color getting redder. Same with green and blue. The white point shown is directly

opposite the black point in the cube and is located at 255, 255, 255.

We will convert our image into the following color points

Color Red Green Blue

Red 255 0 0

Green 0 255 0

Blue 0 0 255

Black 0 0 0

White 255 255 255

The first pixel in Ocean.ppm is 255, 143, 211. We want to convert that color to one of our 5

choices of colors. We can use the Euclidean distance to find which color point is closest to our

color. You may know how to get the Euclidean distance of 2 points in a 2d plane.

This diagram shows a 2d plane with points at (2, 3) and (5, 7). The distance between them is

calculated by distance = (x . The distance here is 5. To find the distances in 1 x2)

2

+ (y1 y2)

2

a 3d plane we can extend this formula with x, y’s and z’s. We can replace those with r for red,

g, for green and b for blue. To find the distance from one color to another we would use

distance = (r . The color we want to choose for our color reduced 1 r2)

2

+ (g1 g2)

2

+ (b1 b2)

2

image will be the color that is the shortest distance from the original color.

The triangle is the original color, pixel 1 from Ocean.ppm. In our final output image it will be

replaced with one of the 5 colors that it is closest to.

Requirements

Display a menu for the user. On an invalid entry warn the user and ask for input. 1.

Reduce Color PPM, Q. to Quit

Ask the user for a valid file. If the file does not exist the user should be warned and

prompted again.

The PPM files that are loaded should be validated to make sure the first line is P3,

signifying that is a PPM file, and the color depth is 255..

Ask for an output image to save our changes to. If the file cannot be created the user

should be warned and prompted again..

Notes

There is a test_pattern.ppm file that can be used to help validate your program. The image size

is 200 x 200. The first 50 lines are variations of red, 50 lines of greens, 50 lines of blue. The

last 50 lines is half white and half black. ( See the example image above. ). Your resulting

output image should look like the example given earlier.

Definitions

Pixel ­ any one of the very small dots that together form the picture on a television screen,

computer monitor, etc.

1

Example

>>>================================RESTART================================

>>>

ColorReduction

1.ConvertPPMImage

Q.Quit

==>1

Enteravalidfilenametoconvert.==>nofile.m

Thefileyouspecifieddoesnotexist. Pleaseenteravalidfilename

Enteravalidfilenametoconvert.==>BadHeader1.ppm

ThefilesfirstlineshouldbeP3

Enteravalidfilenametoconvert.==>BadHeader2.ppm

Thecolordepthmustbe255

Enteravalidfilenametoconvert.==>umkc.ppm

Whatisthenameofthefileyouwanttosaveto?==>umkc_out.ppm

Yourfilehasbeensaved.

ColorReduction

1.ConvertPPMImage

Q.Quit

==>q

>>>

Explanation / Answer

import sys


class PPM_Exception(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)

def partition(s,ch):
if (ch in s):
m = s.index(ch)
return (s[0:m],s[m],s[m+1:])
else:
return (s,None,None)


def strip_comments(s):
  
(rval,junk1,junk2) = partition(s,"#")
return rval.rstrip(" ")


def load_ppm(fname):
return loadPPM(fname);

def loadPPM(fname):

  
inf = open(fname,"r")

  
magic = strip_comments(inf.readline())
if (magic != "P3"):
raise PPM_Exception, 'The file being loaded does not appear to be a valid ASCII PPM file'

dimensions = strip_comments(inf.readline())

(width, sep, height) = partition(dimensions," ")
width = int(width)
height = int(height)
if (width <= 0) or (height <= 0):
raise PPM_Exception, "The file being loaded does not appear to have valid dimensions (" + str(width) + " x " + str(height) + ")"


max = inf.readline()
max = int(strip_comments(max))
if (max != 255):
sys.stderr.write("PPM file does not have a maximum value of 255. Image may not be handled correctly.")

  
color_list = []
for line in inf:
line = strip_comments(line)
color_list += line.split(" ")

inf.close() # We are done with the file -- be nice and close it

image = []
for x in range(0,width):
image.append([])
for y in range(0,height):
image[x].append([int(color_list[(y * width + x) * 3]),
   int(color_list[(y * width + x) * 3 + 1]),
       int(color_list[(y * width + x) * 3 + 2])])

return image


def limit(high, low, value):
if (value < low) or (value > high):
raise PPM_Exception, str(value) + " is outside of the range " + str(high) + " to " + str(low)

def displayImage(x, y, img, outf=sys.stdout):

outf.write("pixelsx " + str(x) + " " + str(y) + " " + str(len(img)) + " " + str(len(img[0])))
for n in range(0, len(img[0])):
for m in range(0, len(img)):
limit(255.9,-0.9,img[m][n][0])
limit(255.9,-0.9,img[m][n][1])
limit(255.9,-0.9,img[m][n][2])
outf.write(" %02x%02x%02x" % (int(img[m][n][0]),int(img[m][n][1]),int(img[m][n][2])))
outf.write(" ")

def createImage(x, y):
retval = []
for m in range(0, x):
retval.append([])
for n in range(0, y):
retval[m].append([0,0,0])

return retval

def width(image):
return len(image)

def height(image):
return len(image[0])