Computer Science 111 Fundamentals of Programming I Introduction to Digital Image Processing
Digital Images Input devices: –scanners –cameras –camcorders Output devices: –display screens –printers Processing: –file compression –various transformations
Transformations Convert from color to grayscale Adjust the brightness Adjust the contrast Adjust the size Rotate Morph into another image
Morph of the Day 1
Morph of the Day 2
Representing Images An image can be represented as a two-dimensional grid of RGB values (pixels) To capture an image (via camera or scanner), a continuous range of color info is sampled as a set of discrete color values All processing works with the grid of RGB values Output maps the grid to a file, display, or printer
The images Module A non-standard, open source module that includes a set of classes and methods for processing images Can edit scripts in IDLE, then run them from the shell or a terminal prompt python3 myprogram.py
The Image Class Image(fileName) Image(width, height) draw() clone() getWidth() getHeight() getPixel(x, y) setPixel(x, y, (r, g, b)) save(filename = "") Represents a grid of pixels Methods for display, examining the dimensions, examining or resetting pixels, and saving changes to a file A pixel is just a tuple of 3 integers Works with GIF image files
A Simple Session >>> from images import Image
A Simple Session The image file must be in the current working directory >>> from images import Image >>> image = Image('smokey.gif')
A Simple Session draw must be run to display the image >>> from images import Image >>> image = Image('smokey.gif') >>> image.draw()
A Simple Session >>> from images import Image >>> image = Image('smokey.gif') >>> image.draw() >>> image.getWidth(), image.getHeight() (300, 225) The comma creates a tuple of results
A Simple Session >>> from images import Image >>> image = Image('smokey.gif') >>> image.draw() >>> image.getWidth(), image.getHeight() (300, 225) >>> image.getPixel(0, 0) (206, 224, 122) Screen coordinates: the origin (0, 0) is the upper left corner y-values increase as you move down
Transformations: Black and White Compute the average of the three color components in a pixel If the average is less than 128, then set the pixel ’ s three color components to 0s (black) Otherwise, set them to 255s (white)
blackPixel = (0, 0, 0) whitePixel = (255, 255, 255) for y in range(image.getHeight()): for x in range(image.getWidth()): (r, g, b) = image.getPixel(x, y) average = (r + g + b) // 3 if average < 128: image.setPixel(x, y, blackPixel) else: image.setPixel(x, y, whitePixel) Transformations: Black and White
for y in range(3): for x in range(4): print((y, x), end = ' ') print() Processing a Grid (0, 0) (0, 1) (0, 2) (0, 3) (1, 0) (1, 1) (1, 2) (1, 3) (2, 0) (2, 1) (2, 2) (2, 3) 3 rows, 4 columns
Transformations: Inversion Should turn black into white or white into black Reset each color component of a pixel to 255 minus that component ’ s value
for each pixel in the image: subtract each color component from 255 Transformations: Inversion
Transformations: Grayscale Compute the average of the three color components in a pixel Reset each color component of the pixel to this average value
Transformations: Grayscale for y in range(image.getHeight ()) for x in range(image.getWidth()): (r, g, b) = image.getPixel(x, y) ave = (r + g + b) // 3 image.setPixel(x, y, (ave, ave, ave))
A Better Grayscale Algorithm The simple average of the RGB values does not take account of the human retina ’ s different sensitivities to the luminance of those values The human eye is most sensitive to green, then red, then blue Psychologists have determined the exact sensitivities Multiply each value by a weight factor and then add them up
A Better Grayscale Algorithm red = int(red * 0.299) green = int(green * 0.587) blue = int(blue * 0.114) gray = red + green + blue image.setPixel(x, y, (gray, gray, gray)) Old New
Package Code in a Function def grayScale(image): for y in range(image.getHeight ()): for x in range(image.getWidth()): (r, g, b) = image.getPixel(x, y) ave = (r + g + b) // 3 image.setPixel(x, y, (ave, ave, ave)) Note that this function does not return a new image, but modifies its argument Until now, functions did not modify arguments This is the most efficient way of modifying large data objects
For Monday More Image Transformations