Difference between revisions of "CSC111 Lab 10 2018"

From dftwiki3
Jump to: navigation, search
(Created page with "~~~~ ---- <br /> <bluebox> This lab presents image-processing operations in Python using Zelle's Graphics Library. The purpose of this lab is to get you to explore image...")
 
 
(6 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
----
 
----
  
 
+
<onlydft>
 
<br />
 
<br />
  
  
 
<bluebox>
 
<bluebox>
This lab presents image-processing operations in Python using Zelle's Graphics Library.  The purpose of this lab is to get you to explore image processing with Python.  Some of you will go faster than others.  The goal is for you to answer correctly some of the challenges, but it is understood that not all of you will be able to go through all the challenges before the due date.  For this reason, to get full credit, you only need to submit the program corresponding to the last challenge you were able to solve before the due date.  You will submit both the program and a screen capture of the image you generated.  Make sure '''you code your name as the title of the window''', so that the screen capture can be easily assigned to you.<br />
+
This lab presents image-processing operations in Python using Zelle's Graphics Library.  The purpose of this lab is to get you to explore image processing with Python.  Some of you will go faster than others.  The goal is for you to answer correctly some of the challenges, but it is understood that not all of you will be able to go through all the challenges before the due date.  For this reason, to get full credit, you only need to submit the program corresponding to the last challenge you were able to solve before the due date.  You will submit both the program and a screen capture of the image you generated.  Make sure '''you code your name(s) as the title of the window''', so that the screen capture can be easily assigned to you.<br />
You should work in pair-programming mode, as always!
+
You are encouraged to keep working in pair-programming mode, as always!
 
<br />
 
<br />
 
'''Note:''' While you are not required to finish the lab before the due date, you '''should''' look at the solution programs at the end of the page when they become available, you should run them and understand them, as the final exam will have one problem dealing with graphics and image processing.  You don't want to find yourself not understanding the challenges in today's lab during the final exam, as there won't be any more help from TAs or instructors during the final exam...   
 
'''Note:''' While you are not required to finish the lab before the due date, you '''should''' look at the solution programs at the end of the page when they become available, you should run them and understand them, as the final exam will have one problem dealing with graphics and image processing.  You don't want to find yourself not understanding the challenges in today's lab during the final exam, as there won't be any more help from TAs or instructors during the final exam...   
Line 49: Line 49:
 
</source><br /><br />
 
</source><br /><br />
  
 +
<br />
 +
==Some Images to Play With==
 +
<br />
 +
<br />
 +
[[File:catGlasses.gif|center]]
 +
<br />
 +
<center>catGlasses.gif, 424 × 418</center>
 +
<br />
 +
[[File:FlowersSmith.gif | center]]
 +
<br />
 +
<center>FlowersSmith.gif, 661 × 255 </center>
 +
<br />
 +
[[File:catHat.gif | center]]
 +
<br />
 +
<center>catHat.gif, 243 × 207 </center>
 
<br />
 
<br />
  
 +
 +
<br />
 
==Skeleton Program #1==
 
==Skeleton Program #1==
 
<br />
 
<br />
The program you need to submit at the end of this lab will be called '''lab10.py'''. You may wa
+
The program you need to submit at the end of this lab will be called '''lab10.py'''.  
  
 
Below is a program you should copy/paste into your Idle window.  Make sure you enter your name for the title of the window in the highlighted line.  This will allow you later to get a grade for this lab!
 
Below is a program you should copy/paste into your Idle window.  Make sure you enter your name for the title of the window in the highlighted line.  This will allow you later to get a grade for this lab!
Line 114: Line 131:
 
     for x in range( WIDTH ):
 
     for x in range( WIDTH ):
 
         for y in range( HEIGHT ):
 
         for y in range( HEIGHT ):
 +
            # get the R, G, B values for the pixel at (x,y)
 
             red, green, blue = img.getPixel( x, y )
 
             red, green, blue = img.getPixel( x, y )
 +
 +
            # set the R, G, B values of the pixel at (x,y)
 +
            # to different values (here we set red to 255)
 
             img.setPixel( x, y, color_rgb(255, green, blue ) )
 
             img.setPixel( x, y, color_rgb(255, green, blue ) )
  
Line 145: Line 166:
 
* Create this program as '''lab9.py''' and save it to your usual folder.  Make sure you change the title of the window to be your name.
 
* Create this program as '''lab9.py''' and save it to your usual folder.  Make sure you change the title of the window to be your name.
 
<br />
 
<br />
 +
 
=Problem 1: Andy Warhol's Cat=
 
=Problem 1: Andy Warhol's Cat=
 
<br />
 
<br />
Line 227: Line 249:
 
* Make your main program call ''blackAndWhite( img, win )'' instead of the previous function it was calling.
 
* Make your main program call ''blackAndWhite( img, win )'' instead of the previous function it was calling.
 
* Run your program.
 
* Run your program.
* Notice how it "sweeps" through the image as it processes it.  The '''win.update()''' line forces the graphics window to refresh the image and show the state of all the pixels.  Normally the graphic window will show the changes only after the for-loops are done with the pixel modification.  Now we can better see how the '''for x''' and '''for y''' loop operate.
+
* Notice how it "sweeps" through the image as it processes it.  The '''win.update()''' line forces the graphics window to refresh the image and show the state of all the pixels.  Normally the graphic window will show the changes only after the for-loops are done with the pixel modification.  Now we can better see how the '''for x''' and '''for y''' loops operate.
 
<br />
 
<br />
 
<br />
 
<br />
Line 272: Line 294:
 
=Problem 4: Sideways=
 
=Problem 4: Sideways=
  
Pick one of the functions you have written for the problems above and make a new copy of it under a different name, say, '''sideways( img )'''.
+
* Add the function '''sideways( img, win )''' show below to your program.  Make your main program call this new function.
 +
* Before running your program, analyze the code of the new function.  See if you can accurately predict the way the image is going to be transformed by these nested for-loops.  Do you and your partner agree on what will happen to the image?
 +
* Run the program!  Does what you observe make sense?  Look at your loop again, and at the resulting image.  Make sure the logic of the code explains the resulting image transformation.
  
Replace the nested for-loop with this loop:
 
 
<br />
 
<br />
<source lang="python">
+
::<source lang="python">
for x in range( WIDTH ):
+
def sideways( img, win ):
    for y in range( x ):
+
    """transforms the image in a (currently) mysterious way"""
          # make sure y does not get larger than height of image
+
    global WIDTH, HEIGHT
          if y < HEIGHT:
+
    for x in range( WIDTH ):
                # modify color of pixel at x, y...
+
        win.update()
                # keep your pixel color-modification code here
+
        for y in range( x ):
 +
            if y < HEIGHT:
 +
                red, green, blue = img.getPixel( x, y )
 +
                grey  = int( 0.3 * red +0.6 * green +0.11 * blue )
 +
                color = color_rgb( grey, grey, grey )
 +
                img.setPixel( x, y, color )
 
</source>
 
</source>
 
<br />
 
<br />
* Look at the code.  See if you can accurately predict the way the image is going to be transformed by these nested for-loops. 
 
* Run the program!  Does it make sense?  Look at your loop again, and at the resulting image.  Make sure the logic of the code explains the resulting image transformation.
 
 
 
* Modify your new function so that the transformation affects another side of the image.
 
* Modify your new function so that the transformation affects another side of the image.
 
<br />
 
<br />
Line 409: Line 434:
 
Note that Moodle cannot run and display graphics program.  This is why you are submitting a copy of the image you generated.  This is also why you won't be able to run or evaluate the program on Moodle.
 
Note that Moodle cannot run and display graphics program.  This is why you are submitting a copy of the image you generated.  This is also why you won't be able to run or evaluate the program on Moodle.
 
<br />
 
<br />
 
+
</onlydft>
 
<br />
 
<br />
 
<!-- ================================================================= -->
 
<!-- ================================================================= -->

Latest revision as of 14:00, 1 June 2018

D. Thiebaut (talk) 11:30, 8 April 2018 (EDT)



...


<showafterdate after="20180414 13:00" before="20180601 00:00">

Solution Program


# lab10sol.py
# D. Thiebaut
# A collection of functions for manipulating an image
# using nested for loops.  Each function corresponds to a 
# transformation that was introduced in the lab.

from graphics import *

# We measured the image dimensions to be 243x207
# We make the window the same size
WIDTH  = 243
HEIGHT = 207


def sideways( img ):
    global WIDTH, HEIGHT
    for x in range( WIDTH ):
       for y in range(  x  ):
           # make sure y does not get larger than height of image
           if y < HEIGHT:
                # modify color of pixel at x, y...
                red, green, blue = img.getPixel( x, y )
                grey  = int( 0.3 * red +0.6 * green +0.11 * blue )
                color = color_rgb( grey, grey, grey )
                img.setPixel( x, y, color )
                
def blackAndWhite( img, win ):
    """sets the red component of the pixels of the image
    to their maximal value"""
    global WIDTH, HEIGHT
    for x in range( WIDTH ):
        win.update()
        for y in range( HEIGHT ):
            red, green, blue = img.getPixel( x, y )
            grey  = int( 0.3 * red +0.6 * green +0.11 * blue )
            color = color_rgb( grey, grey, grey )
            img.setPixel( x, y, color )


def saturate( component ):
    """transforms component into min or max value depending
    on its intensity."""
    if component < 125:
       return 0
    return 255


def AndyWarhol( img ):
    """saturates the image by saturating the 
    RGB components.  If the R component is less than 125, then
    set it to 0, otherwise set it to 255.   Same for blue and green."""

    global WIDTH, HEIGHT
    for x in range( WIDTH ):
        for y in range( HEIGHT ):
            red, green, blue = img.getPixel( x, y )
      
            # the line below replaces the pixel with its original color.  Change
            # the amount of red, green and blue to see some change in the colors
            newColor = color_rgb( saturate(red), saturate(green), saturate(blue) )
            img.setPixel( x, y, newColor )

def makeRed( img ):
    """sets the red component of the pixels of the image
    to their maximal value"""
    global WIDTH, HEIGHT
    for x in range( WIDTH ):
        for y in range( HEIGHT ):
            red, green, blue = img.getPixel( x, y )
            img.setPixel( x, y, color_rgb(255, green, blue ) )

def pixelate( img, win ):
    global WIDTH, HEIGHT
    img.undraw(  )
    for x in range( 0, WIDTH, 10 ):
        for y in range( 0, HEIGHT, 10 ):
            red, green, blue = img.getPixel( x, y )
            circ = Circle( Point( x, y ), 5 )
            circ.setFill( color_rgb( red, green, blue ) )
            circ.draw( win )
                      
def addBorder( img ):
    """add a red border around the image"""
    global WIDTH, HEIGHT
    for x in range( WIDTH ):
        for y in range( 6 ):
            img.setPixel( x, y, color_rgb(255, 0, 0 ) )
        for y in range( HEIGHT-5, HEIGHT ):
            img.setPixel( x, y, color_rgb(255, 0, 0 ) )

    for y in range( HEIGHT ):
        for x in range( 6 ):
            img.setPixel( x, y, color_rgb(255, 0, 0 ) )
        for x in range( WIDTH-5, WIDTH ):
            img.setPixel( x, y, color_rgb(255, 0, 0 ) )

def addRedDiagonal( img ):
    """draws a red diagonal going from the top-left corner
    of the image down."""
    global WIDTH, HEIGHT
    for x in range( 0, WIDTH ):
        y = x
        if y < HEIGHT:
            red, green, blue = img.getPixel( x, y )
            img.setPixel( x, y, color_rgb( 255, 0, 0 ) )

def addRedCross( img ):
    """draws a red cross going from the top-left corner
    of the image down, and from top-right corner down to
    lower left side of the image."""
    global WIDTH, HEIGHT
    for x in range( 0, WIDTH ):
        y = x
        if y < HEIGHT:
            red, green, blue = img.getPixel( x, y )
            img.setPixel( x, y, color_rgb( 255, 0, 0 ) )

    for x in range( WIDTH-1, -1, -1 ):
        y = WIDTH-1-x
        if y < HEIGHT:
            red, green, blue = img.getPixel( x, y )
            img.setPixel( x, y, color_rgb( 255, 0, 0 ) )
    
def symmetry( img ):
    """draws the image horizontally symmetrical around the
    vertical middle of the image"""
    global WIDTH, HEIGHT
    for x in range( 0, WIDTH//2 ):
        x2 = WIDTH-1-x
        for y in range( 0, HEIGHT ):
            red, green, blue = img.getPixel( x, y )
            img.setPixel( x2, y, color_rgb(red, green, blue ) )

def fog( img ):
    """creates a fog effect, making the pixels more and more
    white as we get closer to the bottom of the window."""
    global WIDTH, HEIGHT
    for x in range( 0, WIDTH ):
        for y in range( 0, HEIGHT ):
            red, green, blue = img.getPixel( x, y )
            percent = 1.0 * y / HEIGHT
            red   = int( red + (255-red)*percent )
            green = int( green + (255-green)*percent )
            blue  = int( blue + (255-blue)*percent )
            img.setPixel( x, y, color_rgb(red, green, blue ) )
    
def waitForClick( win, message ):
    """ waitForClick: stops the GUI and displays a message.  
    Returns when the user clicks the window. The message is erased."""

    # wait for user to click mouse to start
    startMsg = Text( Point( win.getWidth()/2, win.getHeight()-15 ), message )
    startMsg.draw( win )    # display message
    win.getMouse()          # wait
    startMsg.undraw()       # erase



def main():
    # open the graphic window
    win = GraphWin( "Your name here", WIDTH, HEIGHT )

    # create an image with its center corresponding to the center
    # of the window.  
    img = Image( Point(WIDTH//2, HEIGHT//2), "catHat.gif", )

    # make the image appear in the window
    img.draw( win )

    # transform the pixels of the image
    #makeRed( img )

    # create Andy Warhl image
    #AndyWarhol( img )

    # make the image black and white
    #blackAndWhite( img, win )

    # apply a sideways transformation
    #sideways( img )

    # add a border
    #addBorder( img )

    # add a red diagonal to the image
    #addRedDiagonal( img )

    # add a red cross to the image
    #addRedCross( img )

    
    # pixelate the image
    pixelate( img, win )

    # symmetrical cat in fog
    #symmetry( img )
    #fog( img )
    
    # close the window when the user clicks on it
    waitForClick( win, "click to close" )
    win.close()

main()

</showafterdate>