Homework #8

Sean Lubner


In [16]:
from Tkinter import *
import matplotlib, sys, os, scipy.misc, urllib2, json
from matplotlib.image import imread
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from urllib import FancyURLopener
from skimage import filter
import numpy as np

# Make a root window
root = Tk()
root.title("Image Manipulator")
#root.minsize(120,50)
#root.maxsize(700,500)
root.columnconfigure(0, weight=1) # let this column expand in width when window is resized

# -------------------------------------- Search functions --------------------------------------
def googleSearch(searchTerm):
    """ Given searchTerm search query, performs a google image search and returns the first image (as an array)
        and the URL of the image.  Gracefully displays an error if unable to successfully import image. """
    # Replace spaces ' ' in search term for '%20' in order to comply with request
    imNames=searchTerm.replace(" ","")
    searchTerm = searchTerm.replace(' ','%20')

    # Start FancyURLopener with defined version 
    #class MyOpener(FancyURLopener): 
    #    version = ""#'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'
    myopener = FancyURLopener()
    # Notice that the start changes for each iteration in order to request a new set of images for each loop
    url = ('https://ajax.googleapis.com/ajax/services/search/images?' + 'v=1.0&q='+searchTerm+'&start=1&userip=MyIP')
    request = urllib2.Request(url, None, {'Referer': ''})
    response = urllib2.urlopen(request)
    
    # Get results using JSON
    results = json.load(response)
    dataInfo = results['responseData']['results']
    try:
        Url=dataInfo[0]["unescapedUrl"]
        extension=Url.split(".")[-1]
        (imName,header)=myopener.retrieve(Url,imNames+"."+extension)
        image = plt.imread("./"+imName)
        root.searched_image = image
        os.remove("./"+imName)
    except IOError:
        Url=dataInfo[-1]["unescapedUrl"]
        extension=Url.split(".")[-1]
        (imName,header)=myopener.retrieve(Url,imNames+"."+extension)
        image=plt.imread("./"+imName)
        root.searched_image = image
        os.remove("./"+imName)
    except:
        Url = "Sorry, the import failed, please try a different search  :("
        im_URL.set(Url)
    return Url, image, imName

def search_for_images(*args):
    """ Connect this function to the search button.  This function is separatd from the googleSearch function
        to allow for flexibility of different search engine protocols, if desired. """
    [search_URL, im_array, imName]=googleSearch(query.get())
    image_axes = plt.imshow(root.searched_image)
    canvas.show()
    im_URL.set(search_URL)

# -------------------------------------- Manipulation functions --------------------------------------
def color_complement_image(*args):
    """ Inverts the color channels in the image, it subtracts each element of each channel from 255.
        Call with the following parameters: color_complement(image)"""
    manipulated = 255-root.searched_image
    image_axes = plt.imshow(manipulated)
    canvas.show()
        
def original_image(*args):
    """ Restores the original image """
    image_axes = plt.imshow(root.searched_image)
    canvas.show()
    
def smooth_BW_image(*args):
    """ Convert to Black & White, and smooth """
    manipulated = scipy.ndimage.filters.gaussian_filter(root.searched_image,10)
    image_axes = plt.imshow(manipulated)
    canvas.show()
    
def edges_image(*args):
    """ Display the edges of the image """
    if len(root.searched_image.shape) == 2:
        manipulated = filter.canny(root.searched_image, sigma=10)
    elif len(root.searched_image.shape) in [3, 4]:
        manipulated = filter.canny(root.searched_image[:,:,0])
    else:
        im_URL.set('Could not find image edges.  Try a different image')
    image_axes = plt.imshow(manipulated)
    canvas.show()
    
# -------------------------------------- Layout --------------------------------------
# Input
input_label=Frame(root)
input_label.grid(row=0, column=0, sticky=(S,E,W))
Frame(input_label, height=20).grid(row=0, column=0) # spacer
#Label(input_label, text='text would show here', padx=10).grid(row=1, column=0, sticky=(S,W)) # Define "input" region

input_box = Frame(root) # container to hold input items
input_box.grid(row=1, column=0, padx=5, sticky=(N,S,W,E)) # Glue box to all four edges
query = StringVar() # String variable to hold the search query
Label(input_box, text='Query string:').grid(row=0, column=0, sticky=(E)) # within input_box, show label of entry region
Entry(input_box, textvariable=query).grid(row=0, column=1, sticky=(W,E)) # Entry widget for query, fills available space
input_box.columnconfigure(1, weight=1) # let the Entry field expand when window is resized
query_button = Button(input_box, text='Search Images', command=search_for_images).grid(row=0, column=2, sticky=(W), padx=20) # button


# Display URL
URL_label=Frame(root)
URL_label.grid(row=2, column=0, sticky=(S,E,W))
Frame(URL_label, height=20).grid(row=0, column=0) # spacer
Label(URL_label, text='Image URL:', padx=10).grid(row=1, column=0, sticky=(S,W))

URL_box = Frame(root, bd=2, relief=SUNKEN)
URL_box.grid(row=3, column=0, padx=5, sticky=(N,S,W,E)) # Glue box to all four edges
im_URL = StringVar()
im_URL.set('Enter a search description into the "Query string" field above, and click "Search Images"')
Label(URL_box, textvariable=im_URL, padx=5).grid(row = 1, column = 0, sticky=(W))


# Display Image
display_label=Frame(root)
display_label.grid(row=4, column=0, sticky=(S,E,W))
Frame(display_label, height=20).grid(row=0, column=0) # spacer
Label(display_label, text='Image Display:', padx=10).grid(row=1, column=0, sticky=(S,W))

image_box = Frame(root)
image_box.grid(row=5, column=0, padx=5, sticky=(N,S,W,E)) # Glue box to all four edges
root.rowconfigure(5, weight=1)
image_box.columnconfigure(0, weight=1)


# Image Manipulations
manipulations_label=Frame(root)
manipulations_label.grid(row=6, column=0, sticky=(S,E,W))
Frame(manipulations_label, height=20).grid(row=0, column=0) # spacer
Label(manipulations_label, text='Image Manipulations Options:', padx=10).grid(row=1, column=0, sticky=(S,W))

manipulations_box = Frame(root, bd=2, relief=SUNKEN) 
manipulations_box.grid(row=7, column=0, padx=5, sticky=(N,S,W,E)) # Glue box to all four edges
smooth_button = Button(manipulations_box, text='Smooth + B&W', command=smooth_BW_image).grid(row=1, column=0, pady=10, sticky=(N))
invert_button = Button(manipulations_box, text='Invert Colors', command=color_complement_image).grid(row=1, column=1, pady=10, sticky=(N))
edges_button = Button(manipulations_box, text='Show Edges', command=edges_image).grid(row=1, column=2, pady=10, sticky=(N))
original_button = Button(manipulations_box, text='Original', command=original_image).grid(row=1, column=3, pady=10, sticky=(N))
for c in range(manipulations_box.grid_size()[0]): # keep buttons evenly spaced out
    manipulations_box.columnconfigure(c, weight=1)

fig = plt.figure() # Placeholder for image
image_axes = fig.add_subplot(111)
canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(fig, master=image_box)
canvas.show()
canvas.get_tk_widget().grid(row=0, column=0)
    
Frame(root, height=10).grid(row=8, column=0) # spacer at bottom

root.mainloop()