CPE 101 Lecture 2
November 28, 2024
1 CPE 101 Lecture Demonstration: Image manipulations in
Python, with Loop Code, expressions, puzzle and grayscale
1.1 Using Python Image Library (Pillow)
1.1.1 Sani Godwin, Nov 2024
Begin by importing the needed libraries
[1]: from PIL import Image
import matplotlib.pyplot as plt
Opening the image x.png:
[2]: image=Image.open('x.png')
print(image)
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=5x5 at 0x1F93F3A7E00>
[3]: plt.imshow(image)
[3]: <matplotlib.image.AxesImage at 0x1f95e648f50>
1
[4]: # getting the RGB pixel value.
r, g, b, p = image.getpixel((2, 2))
print(r,g,b,p)
255 255 255 255
[5]: #Change the color of a pixel
img2=Image.open('x.png') #make a new image file
img2.putpixel((2,2),(225,0,0))
plt.imshow(img2)
[5]: <matplotlib.image.AxesImage at 0x1f95f72e330>
2
[6]: #let set the first pixel to green
img2.putpixel((0,0),(0,225,0))
plt.imshow(img2)
[6]: <matplotlib.image.AxesImage at 0x1f95f760860>
3
[7]: #let set the pixel(4,1) to blue
img2.putpixel((4,1),(0,0,255))
plt.imshow(img2)
[7]: <matplotlib.image.AxesImage at 0x1f95f7ee870>
4
[8]: #Zoom in on the original image by a factor of 10
w, h = image.size # Extracting the width and height of the image:
zoomedImage = image.resize((w*10,h*10)) #resize to zoom
plt.imshow(zoomedImage)
[8]: <matplotlib.image.AxesImage at 0x1f95f713e30>
5
1.2 Image Code: Loops and Loop Expressions
• Suppose you had 5,000 cardboard boxes in a warehouse and a robot
• You want the robot to move all the boxes from one corner to another
• All you need to do is to explain how to move one box in great detail
• Then tell the robot to repeat those same steps for all the boxes
• That is the loops - do some steps “for all these items” We’ll look how to use expressions to
greatly expand what we can do in a loop. With expressions, we’ll be able to write real image
manipulation code, and in particular solve some puzzles based on images.
[9]: # Let us look at the flower image and find out the size
imgFlower1=Image.open('flower1.png')
print(imgFlower1)
plt.imshow(imgFlower1)
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=246x192 at 0x1F95F8AFE30>
[9]: <matplotlib.image.AxesImage at 0x1f961a45010>
6
• Looking at the text on top of the image, we can see the size=246x192
• It means that the flower is 246 pixels wide by 192 pixels high = 47232 pixels
• We will now use For-Loop to change its properties.
But First, let us create a function that we can use to display the two images in one
row
[10]: def showtwo(left, right):
plt.subplot(1, 2, 1)
plt.imshow(left)
plt.subplot(1, 2, 2)
plt.imshow(right)
plt.show()
1.2.1 Let us create a “Red Channel Image” of the flower.
• The next code example computes the “red channel” image
• The red channel is just the red light of the image, with blue and green set to zero
• Note that in RGB scheme, Red=(255,0,0); Green=(0,255,0), and Blue=(0,0,255)
• Furthermore, White=(255,255,255), while Black=(0,0,0).
• We will also create the other two channels…
7
[11]: width = imgFlower1.width # get the width
height = imgFlower1.height # get the height
imgFlower2 = Image.new("RGB", (width, height)) # create a new image of␣
↪the same size
for x in range(width): # Loop through the width
for y in range(height): # For every width, loop␣
↪through the height
oldpixel = imgFlower1.getpixel((x, y)) # get the get the pixel␣
↪location. This is a loop expression
newpixel = (int(oldpixel[0]), int(0), int(0)) # maintain the red but␣
↪change the green and blue to 0
imgFlower2.putpixel((x, y), newpixel) # give the newly created␣
↪image the new color defined. Another loop expression
showtwo(imgFlower1, imgFlower2) # show the original image␣
↪(left) and manipulated image (right)
• As shown above, the image on the left is the original image, while the one on the right is the
“Red Channel Image”
• Let us do the same for the Green Channel
[12]: w1, h1 = imgFlower1.size # Extracting the width and height of the image:
imgFlower3 = Image.new("RGB", (w1, h1)) # create a new image of the same␣
↪size
for i in range(w1):
for j in range(h1):
oldpixel = imgFlower1.getpixel((i, j)) #This is a loop expression
newpixel = (0, oldpixel[1], 0)
imgFlower3.putpixel((i, j), newpixel) #Also a loop expression
showtwo(imgFlower1, imgFlower3)
8
• Finally, for the Blue Channel
[13]: # Blue Channel Image
imgFlower4 = Image.new("RGB", (w1, h1)) # create a new image of the same␣
↪size
for i in range(w1):
for j in range(h1):
oldpixel = imgFlower1.getpixel((i, j))
newpixel = (0, 0, oldpixel[2])
imgFlower4.putpixel((i, j), newpixel)
showtwo(imgFlower1, imgFlower4)
1.3 The For-Loop Conclusion
• The whole image is just the sum of the three channels: adding together all the light
• A powerful feature: we specify a few lines of code, and the computer takes care of running
them thousands of times
• Code inside the loop is special: it runs for every pixel
9
1.4 Next: Exploring the Loop Expressions
The loop expressions allow us to pass an expression like x+y as an argument to a function or
method(), e.g print(1+3) instead of print(4) Let us use this method to achieve image bright-
ness, grayscale, black & white, and blurring.
1.4.1 1. Brightness
[14]: bFactor = 1.2 # Brightness factor
w2, h2 = imgFlower1.size
imgFlower5 = Image.new("RGB", (w2, h2))
for x1 in range(w2):
for y1 in range(h2):
oldpixel = imgFlower1.getpixel((x1, y1))
newpixel = (int(min(oldpixel[0] * bFactor, 255)), int(min(oldpixel[1] *␣
↪bFactor, 255)), int(min(oldpixel[2] * bFactor, 255)))
imgFlower5.putpixel((x1, y1), newpixel)
showtwo(imgFlower1, imgFlower5)
1.4.2 2. Grayscale
Grayscale is achieved in two ways 1. Dividing each pixel by 3 and adding them togther 2. Us-
ing the expression G = (0.299R + 0.587G + 0.114B), in which each pixel has a different weight
multiplying the RGB
[15]: # First method- Grayscale
w, h = imgFlower1.size
imgFlower6 = Image.new("RGB", (w, h))
for x in range(w):
for y in range(h):
av = sum(imgFlower1.getpixel((x, y))) // 3
imgFlower6.putpixel((x, y), (av, av, av))
showtwo(imgFlower1, imgFlower6)
10
[16]: # Second method- Grayscale
w, h = imgFlower1.size
imgFlower7 = Image.new("RGB", (w, h))
for x in range(w):
for y in range(h):
r, g, b, p = imgFlower1.getpixel((x, y)) # getting the RGB pixel value
imgFlower7.putpixel((x, y), (int(0.299*r + 0.587*g + 0.114*b), int(0.299*r␣
↪+ 0.587*g + 0.114*b), int(0.299*r + 0.587*g + 0.114*b)))
showtwo(imgFlower1, imgFlower7)
1.4.3 3. The Black & White
[17]: threshold = 240 # Try changing the threshold value
w, h = imgFlower1.size
imgFlower8 = Image.new("RGB", (w, h))
for x in range(w):
for y in range(h):
11
avr = sum(imgFlower1.getpixel((x, y))) // 3
if avr >= threshold:
value = 255
else:
value = 0
imgFlower8.putpixel((x, y), (value, value, value))
showtwo(imgFlower1, imgFlower8)
1.4.4 4. The Blurring feature
[18]: w, h = imgFlower1.size
imgFlower9 = Image.new("RGB", (w, h))
for x in range(1,w-1):
for y in range(1,h-1):
newpixel=[0, 0, 0]
for dx in range(-1, 2):
for dy in range(-1, 2):
nearby=imgFlower1.getpixel((x + dx, y + dy))
for j in range(3):
newpixel[j] = newpixel[j] + nearby[j]
newpixel = tuple([x // 9 for x in newpixel])
imgFlower9.putpixel((x, y),newpixel)
showtwo(imgFlower1, imgFlower9)
12
1.4.5 Image manipulations using loop expressions help us to redefine the images in
various forms. We can filter and restore pictures from a puzzle as well.Try
other techniques for image rotation, cropping, and edge detection.
2 Assignment 2
2.0.1 Solving a puzzle with the following parameters!
Given the image shown below - The green and blue values are all just random values in the range
0 - 255 (“snow” or “speckle noise”) - The data of the real image is exclusively in the red values
- In addition, the red values have all been divided by 10 (made dark) - The green/blue snow is
obscuring the real image -Write code to recover the real image
[20]: plt.imshow(Image.open('gold-puzzle.png'))
[20]: <matplotlib.image.AxesImage at 0x1f961adf410>
13
14