image_selection_frame.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 import Tkinter
00003 import roslib
00004 roslib.load_manifest('face_contour_detector')
00005 import rospy
00006 import cv
00007 import cv_bridge
00008 import Image
00009 import ImageTk
00010 import image_settings_frame
00011 from face_contour_detector.srv import *
00012 from face_contour_detector.msg import *
00013 
00014 ## @package face_contour_detector.gui.image_selection_frame
00015 #
00016 #  This package contains only the class ImageSelectionFrame. See class documentation for details.
00017 #  @author Fabian Wenzelmann
00018 
00019 ## @brief constant defining the maximum width an displayed image is allowed to have
00020 MAX_WIDTH = 250
00021 ## @brief constant defining the maximum width an displayed image is allowed to have
00022 MAX_HEIGHT = 500
00023 
00024 ## @brief This class is used to display proposals to the user.
00025 #  @author Fabian Wenzelmann
00026 #
00027 #  This class displays up to four proposals images. The images can be clicked which means that the users selects the filter settings of that image.
00028 #  The images are scaled to a max size so that the four images fit in a single row.
00029 #  Here's an example instance of this frame:
00030 #  @image html image_selection_frame.png
00031 class ImageSelectionFrame(Tkinter.Frame):
00032         ## @brief Constructor method
00033         #  @param self the object pointer
00034         #  @param master The Tkinter master widget of this frame
00035         #  @param proposals a list of type autoselect_result. Each proposal consists of the original image and the initial filter settings.
00036         #
00037         #  This frame contains only for simple labels which display the result of applying the filters of that proposal to the original image.
00038         #  Each label is clickable. When clicked the settings of this proposal are used to create a ImageSettingsFrame.
00039     def __init__(self, master, proposals):
00040         image_settings_frame.current_image = None
00041         Tkinter.Frame.__init__(self, master)
00042         self.master.title("Select Edge Image")
00043         bridge = cv_bridge.CvBridge()
00044         images = []
00045         self.proposals = proposals = proposals[:4]
00046         f = rospy.ServiceProxy("apply_filters", ApplyFilters)
00047         for proposal in proposals:
00048             resp = f(proposal.image, proposal.areas)
00049             cv_img = bridge.imgmsg_to_cv(resp.result_image, "mono8")
00050             py_img = Image.fromstring("L", cv.GetSize(cv_img), cv_img.tostring())
00051             scaled = scale_image(py_img, MAX_WIDTH, MAX_HEIGHT)
00052             images.append(scaled)
00053         information_label = Tkinter.Label(self, text="Choose one of the following proposals")
00054         information_label.grid(row=0, column=0)
00055         button_mode = lambda n: lambda *args: self.select(n)
00056         # keep references so that there is still the reference (strange tkinter behavior...)
00057         self.image_buffer = image_buffer = []
00058         for i, image in enumerate(images):
00059             photo_image = ImageTk.PhotoImage(image)
00060             image_buffer.append(photo_image)
00061             image_label = Tkinter.Label(self, image=photo_image)
00062             image_label.bind("<1>", button_mode(i))
00063             image_label.grid(row=1, column=i)
00064             
00065         # member documentation
00066         
00067         ## @var proposals
00068         #  a list of type autoselect_result. Each proposal consists of the original image and the initial filter settings.
00069         
00070         ## @var image_buffer
00071         #  a list of the ImateTk.PhotoImages that are displayed (or python will destroy them even if they're displayed...)
00072     
00073     ## @brief Callback method for image label clicks.
00074     #  @param self the object pointer
00075     #  @param n The number of the proposal that is choose. For example if the list contained for proposals and the second is choosen by the user n is 1
00076     #
00077     #  This method creates a new ImageSettingsFrame with the selected initial settings. A new Tkinter.Toplevel widget is created as master of that frame.
00078     #  The new frame gets displayed and this method waits for this window. After that the master of this object (which is usually a Tkinter.Tk widget) gets destroyed.
00079     def select(self, n):
00080         top = Tkinter.Toplevel()
00081         settings = image_settings_frame.ImageSettingsFrame(top, self.proposals[n])
00082         settings.pack()
00083         self.master.withdraw()
00084         top.wait_window()
00085         self.master.destroy()
00086         
00087 ## @brief This method is used to scale an image to a maximum size.
00088 #  @param img The image to scale (PIL Image)
00089 #  @param max_width The maximum width that the scaled version of this image is allowed to have
00090 #  @param max_height The maximum height that the scaled version of this image is allowed to have
00091 #
00092 #  This function returns a scaled version of the image. The image has a width <= max_width and a height <= max_height. The scaled version preserve the proportions of the original image.
00093 def scale_image(img, max_width, max_height):
00094     width, height = img.size
00095     w_factor, h_factor = max_width / float(width), max_height / float(height)
00096     factor = min(w_factor, h_factor)
00097     if factor >= 1:
00098         return img
00099     else:
00100         return img.resize(( int(factor * width), int(factor * height) ), Image.ANTIALIAS)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends


face_contour_detector
Author(s): Fabian Wenzelmann and Julian Schmid
autogenerated on Wed Dec 26 2012 16:18:17