Advertisement
Guest User

Untitled

a guest
Dec 27th, 2017
845
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.07 KB | None | 0 0
  1. # Name ..
  2. # CSE 160
  3. # Homework 3: Image Blurring
  4.  
  5. # A Python program to blur an image.
  6.  
  7. from PIL import Image
  8. import itertools
  9. import sys
  10. import os
  11.  
  12. def read_image(file_path):
  13.     '''
  14.    Reads the image file at file_path into a rectangular grid of pixels,
  15.    represented as a list of list of integer. Each element of the outer list
  16.    is one row of pixels, where each pixel is an integer x such that
  17.    0 <= x < 256. Returns the grid of pixels.
  18.    '''
  19.     # YOU DO NOT NEED TO MODIFY THIS FUNCTION.
  20.     # Do not worry about understanding "How" this function works.
  21.     print "Reading image", file_path
  22.  
  23.     # Open a file in image format
  24.     try:
  25.         image = Image.open(file_path)
  26.     except IOError as e:
  27.         print e
  28.         return
  29.     except:
  30.         print "Unexpected error reading file", file_path
  31.         return
  32.    
  33.     width, height = image.size
  34.     data = list(image.getdata())
  35.    
  36.     # data is a single list. We break it into a nested list.
  37.     result = []
  38.     for r in range(height):
  39.         # Get the part of the list that corresponds to this row.
  40.         row_start = r * width
  41.         row = data[row_start:row_start + width]
  42.        
  43.         result.append(row)
  44.     return result
  45.  
  46. def write_image(file_name, pixel_grid):
  47.     '''
  48.    Given pixel_grid as an image in a list of lists of integers format,
  49.    write it to the filename file_name as an image.  
  50.    Requires that:
  51.    * Each row of pixel_grid is of the same length
  52.    * Each pixel value is an integer x such that 0 <= x < 256.
  53.    '''
  54.     # YOU DO NOT NEED TO MODIFY THIS FUNCTION.
  55.     # Do not worry about understanding "How" this function works.
  56.     size = len(pixel_grid[0]), len(pixel_grid)
  57.     image = Image.new("L", size)
  58.  
  59.     print "Writing", size[0], 'x', size[1], "image to file", file_name
  60.  
  61.     # Flatten the list by making an iterable sequence over the inner lists
  62.     # and then materializing the whole list.
  63.     data = list(itertools.chain.from_iterable(pixel_grid))
  64.     image.putdata(data)
  65.    
  66.     try:
  67.         # Write the image. File extension of file_name determines
  68.         # the encoding.
  69.         image.save(file_name)
  70.     except IOError as e:
  71.         print e
  72.     except:
  73.         print "Unexpected error writing file", file_name
  74.  
  75. def csv_line_to_list(line):
  76.     '''
  77.    Given a CSV-formatted row of integers, returns the integers
  78.    as a list. The argument line must be a string such as
  79.  
  80.        "255, 0,  27"
  81.  
  82.    Note that
  83.     * There are no extra spaces at the beginning or end of
  84.       the string, and
  85.     * Commas are only between elements (no comma before the
  86.       first element, and no comma after the last one).
  87.  
  88.    This method will present an error if either of these
  89.    constraints are violated.
  90.    '''
  91.     # YOU DO NOT NEED TO MODIFY THIS FUNCTION.
  92.     # Do not worry about understanding "How" this function works.
  93.     # Although it is not too tricky if you look up the string split
  94.     # function.
  95.     row = []
  96.     for pixel in line.split(','):
  97.         row.append(int(pixel))
  98.     return row
  99.  
  100. def read_grid(file_path):
  101.     '''
  102.    Reads the CSV file at file_path into rectangular grid of pixels,
  103.    represented as a list of lists of integers. This method should
  104.    read any file written by the write_grid function.  Returns the
  105.    grid of pixels.
  106.    '''
  107.  
  108.     # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  109.  
  110.  
  111.  
  112. def write_grid(file_name, pixel_grid):
  113.     '''
  114.    Writes the given pixel_grid to filename file_name as CSV.
  115.    '''
  116.     # YOU DO NOT NEED TO MODIFY THIS FUNCTION.
  117.     # Do not worry about understanding "How" this function works.
  118.     output_file = open(file_name, 'w')
  119.  
  120.     for row in pixel_grid:
  121.         output_file.write(str(row[0]))
  122.         for column in range(1, len(row)):
  123.             output_file.write(', ' + str(row[column]).rjust(3))
  124.         output_file.write('\n')
  125.  
  126.     output_file.close()
  127.  
  128. def get_pixel_at(pixel_grid, i, j):
  129.     '''
  130.    Returns the pixel in pixel_grid at row i and column j (zero-indexed).
  131.    Returns 0 if i or j is out of bounds for the given pixel_grid.
  132.    Returns 0 if i or j is a negative value.
  133.    '''
  134.  
  135.     # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  136.  
  137.  
  138.  
  139. def test_get_pixel_at():
  140.     ''' Basic, brief sanity checks for get_pixel_at. '''
  141.  
  142.     # If all of these tests return true, then your solution to
  143.     # get_pixel_at is probably mostly correct. However, passing
  144.     # these tests does not necessarily mean your solution is completely
  145.     # correct. There are many ways to implement get_pixel_at
  146.     # that pass these tests and are still wrong. No set of tests
  147.     # can check every possible grid or case.
  148.  
  149.     test_grid = [
  150.         [1, 2, 3, 4, 5, 6],
  151.         [0, 2, 4, 6, 8, 10],
  152.         [3, 4, 5, 6, 7, 8]
  153.     ]
  154.  
  155.     try:
  156.         assert get_pixel_at(test_grid, 0, 0) == 1,   \
  157.             "Call to get_pixel_at(0, 0) should have returned 1."
  158.         assert get_pixel_at(test_grid, -1, 0) == 0,  \
  159.             "Call to get_pixel_at(-1, 0) should have returned 0."
  160.         assert get_pixel_at(test_grid, 0, -1) == 0,  \
  161.             "Call to get_pixel_at(0, -1) should have returned 0."
  162.         assert get_pixel_at(test_grid, -1, -1) == 0, \
  163.             "Call to get_pixel_at(-1, -1) should have returned 0."
  164.  
  165.         assert get_pixel_at(test_grid, 2, 5) == 8,   \
  166.             "Call to get_pixel_at(2, 5) should have returned 8."
  167.         assert get_pixel_at(test_grid, 3, 5) == 0,   \
  168.             "Call to get_pixel_at(3, 5) should have returned 0."
  169.         assert get_pixel_at(test_grid, 2, 6) == 0,   \
  170.             "Call to get_pixel_at(2, 6) should have returned 0."
  171.         assert get_pixel_at(test_grid, 3, 6) == 0,   \
  172.             "Call to get_pixel_at(3, 6) should have returned 0."
  173.  
  174.         assert get_pixel_at(test_grid, 1, 3) == 6,   \
  175.             "Call to get_pixel_at(1, 3) should have returned 6."
  176.     except AssertionError as e:
  177.         # Print out a user-friendly error message
  178.         print e
  179.  
  180. # Run the tests. This method prints nothing if the tests
  181. # pass. This method prints an error message for the first
  182. # error it encounters.
  183. #test_get_pixel_at()
  184.  
  185.  
  186. def average_of_surrounding(pixel_grid, i, j):
  187.     '''
  188.    Returns the unweighted average of the values of the pixel at row i
  189.    and column j and the eight pixels surrounding it.
  190.    '''
  191.  
  192.     # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  193.  
  194.     # pixel_sum should be an integer. We intend for this to be
  195.     # truncating integer division.  
  196.     return pixel_sum / 9
  197.  
  198.  
  199. def test_average_of_surrounding():
  200.     ''' Basic, brief sanity checks for average_of_surrounding. '''
  201.  
  202.     # Similarly to test_get_pixel_at, passing all of these tests
  203.     # does not guarantee that your implementation of
  204.     # average_of_surrounding is correct.
  205.  
  206.     test_grid = [
  207.         [1, 2, 3, 4, 5, 6],
  208.         [0, 2, 4, 6, 8, 10],
  209.         [3, 4, 5, 6, 7, 8]
  210.     ]
  211.  
  212.     try:
  213.         assert average_of_surrounding(test_grid, 0, 0) == 0, \
  214.             "Call to average_of_surrounding(test_grid, 0, 0) should have returned 0."
  215.         assert average_of_surrounding(test_grid, 2, 5) == 3, \
  216.             "Call to average_of_surrounding(test_grid, 2, 5) should have returned 3."
  217.     except AssertionError as e:
  218.         print e
  219.  
  220. #test_average_of_surrounding()
  221.  
  222.  
  223. def blur(pixel_grid):
  224.     '''
  225.    Given pixel_grid (a grid of pixels), returns a new grid of pixels
  226.    that is the result of blurring pixel_grid. In the output grid,
  227.    each pixel is the average of that pixel and its eight neighbors in
  228.    the input grid.
  229.    '''
  230.  
  231.     # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  232.  
  233.  
  234. ################################################################
  235. # The main program begins here.
  236. #
  237. # Step A: Process command line arguments & get input_file name.
  238. #
  239. # sys.argv is a list of the arguments to the program, including
  240. # the name of the program being run. If you call:
  241. #
  242. #    python blur_image_solution.py my_image.png
  243. #
  244. # then sys.argv will be ['blur_image_solution.py', 'my_image.png']
  245. #
  246.  
  247. print "Welcome to the CSE 160 Image Blurring program!"
  248.  
  249. # Print how to use the program correctly if it appears that it has
  250. # been used incorrectly (with the wrong number of arguments).
  251. if len(sys.argv) != 2:
  252.     print "Usage:", sys.argv[0], "<input_file>"
  253.     print "  <input_file> should be either "
  254.     print "    (a) a CSV-formatted text file"
  255.     print "       (as generated by the write_grid function), or"
  256.     print "    (b) a black-and-white image file"
  257.     print "       (as generated by color_to_gray.py)."
  258.     print
  259.     print "  Blurs the given input file and outputs the result as:"
  260.     print "   <input_file>_blur.png (an image) and"
  261.     print "   <input_file>_blur_grid.txt (a CSV-formatted text file)."
  262.     sys.exit()
  263.  
  264. # Get the path to the file that the user wants to blur.
  265. input_file = sys.argv[1]
  266.  
  267. # Step B: Determine what type the input_file is, read the file
  268. # contents into a grid of pixels stored as a list of lists of integers
  269.  
  270. # Get the file extension and filename of the input file.
  271. # Don't worry about the details of how these two lines work.
  272. path_without_ext, ext = os.path.splitext(input_file)
  273. input_filename = os.path.basename(path_without_ext)
  274.  
  275. # Either read the file in as an image or as a grid based
  276. # on the file extension.
  277. if ext == ".txt":
  278.     input_grid = read_grid(input_file)
  279. else:
  280.     input_grid = read_image(input_file)
  281.  
  282.     # read_image returns None in case of error--if that
  283.     # happens, exit the program.
  284.     if input_grid == None:
  285.         exit()
  286.  
  287. # Step C: Generate the output file names
  288.  
  289. # Generate names for the output files based on the name of
  290. # the input file.
  291. out_image_filename = input_filename + '_blur.png'
  292. out_grid_filename = input_filename + '_blur_grid.txt'
  293.  
  294. # Step D: Apply the blur algorithm
  295.  
  296. # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  297.  
  298. # Step E: Write the result to both output files
  299.  
  300. # REMOVE THIS COMMENT AND REPLACE IT WITH YOUR CODE ...
  301.  
  302.  
  303. print "Program done"
  304.  
  305. ###
  306. ### Collaboration
  307. ###
  308.  
  309. # ... Write your answer here, as a comment (on lines starting with "#").
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement