2012-03-28 60 views
0

我正在尝试使用PIL和Tkinter来制作一些自定义图像处理软件。我想用鼠标在图像中选择一个感兴趣的区域,抓住这些像素值,并将它传递给scipy/numpy进行一些数字运算,并可能进行一些图像编辑。在PIL/TKinter中使用绘图

到目前为止,我有一个RegionOfInterest类:

class RegionOfInterest: 
    def __init__(self,image,boundingBox): 
     #take bounding box, draw an oval on the image, save boundingBox locally                                 
     self.box = boundingBox 
     self.avgInt = 0 
     self.draw = ImageDraw.Draw(image) 
     self.draw.rectangle(boundingBox,outline='white') 

    def capture(self): 
     region_to_capture = image.crop(box) 
     region_to_capture.save('output.jpg') 

,这需要PIL图像对象和boundingBox的(与裁剪并保存图像捕捉方法)。这获得由绘制函数调用:通过Tkinter的

def draw(event): 
    global image 
    global region 
    global listOfRegions 
    mouse_X = event.x 
    mouse_Y = event.y 
    region.append(mouse_X) 
    region.append(mouse_Y) 
    if len(region) == 4: 
     roi = RegionOfInterest(image,region) 
     listOfRegions.append(roi) 
     canvas.update() 
     roi.findPixels() 
     roi.calcIntensity() 
     region = [] 

后者又被称为控制单击

mouse_X = 0 
mouse_Y = 0 
region = [] 
listOfRegions = [] 

image = Image.open('test.jpg') 
image = image.convert('L') 
imPix = image.load() 
canvas = Tkinter.Canvas(window, width=image.size[0], height=image.size[1]) 
canvas.pack() 
image_tk = ImageTk.PhotoImage(image) 
canvas.create_image(image.size[0]//2, image.size[1]//2, image=image_tk) 

window.bind("<Control-Button-1>", draw) 
window.bind("<Control-space>", lambda e: nextFrame(sequence_object=sequence,event=e)) 
Tkinter.mainloop() 

此刻我最大的问题是,当我绘制矩形(归途in RegionOfIntereste。init()),矩形不显示!

有关如何使此工作的任何建议?也许有关于如何更好地连接tkinter/pil的资源建议?

回答

0

如果您的确在绘制您认为自己的矩形,那么最有可能发生的情况是它具有较低的堆叠级别,因此它位于图像下方。尝试lift ing或lower矩形或图像。

3

什么是这样的:

from Tkinter import * 
from PIL import Image, ImageTk 

class ScrolledCanvas(Frame): 
    def __init__(self, master, **kwargs): 
     Frame.__init__(self, master, **kwargs) 

     self.grid_rowconfigure(0, weight=1) 
     self.grid_columnconfigure(0, weight=1) 

     self.canv = Canvas(self, bd=0, highlightthickness=0) 
     self.hScroll = Scrollbar(self, orient='horizontal', 
           command=self.canv.xview) 
     self.hScroll.grid(row=1, column=0, sticky='we') 
     self.vScroll = Scrollbar(self, orient='vertical', 
           command=self.canv.yview) 
     self.vScroll.grid(row=0, column=1, sticky='ns') 
     self.canv.grid(row=0, column=0, sticky='nsew', padx=4, pady=4)   
     self.canv.configure(xscrollcommand=self.hScroll.set, 
          yscrollcommand=self.vScroll.set) 


class MyApp(Tk): 
    def __init__(self): 
     Tk.__init__(self) 
     self.grid_rowconfigure(0, weight=1) 
     self.grid_columnconfigure(0, weight=1) 

     self.main = ScrolledCanvas(self) 
     self.main.grid(row=0, column=0, sticky='nsew') 
     self.c = self.main.canv 

     self.currentImage = {} 
     self.load_imgfile('test.jpg') 

     self.c.bind('<ButtonPress-1>', self.on_mouse_down) 
     self.c.bind('<B1-Motion>', self.on_mouse_drag) 
     self.c.bind('<ButtonRelease-1>', self.on_mouse_up) 
     self.c.bind('<Button-3>', self.on_right_click) 

    def load_imgfile(self, filename):   
     img = Image.open(filename) 
     img = img.convert('L') 
     self.currentImage['data'] = img 

     photo = ImageTk.PhotoImage(img) 
     self.c.xview_moveto(0) 
     self.c.yview_moveto(0) 
     self.c.create_image(0, 0, image=photo, anchor='nw', tags='img') 
     self.c.config(scrollregion=self.c.bbox('all')) 
     self.currentImage['photo'] = photo 

    def on_mouse_down(self, event):   
     self.anchor = (event.widget.canvasx(event.x), 
         event.widget.canvasy(event.y)) 
     self.item = None 

    def on_mouse_drag(self, event):   
     bbox = self.anchor + (event.widget.canvasx(event.x), 
           event.widget.canvasy(event.y)) 
     if self.item is None: 
      self.item = event.widget.create_rectangle(bbox, outline="yellow") 
     else: 
      event.widget.coords(self.item, *bbox) 

    def on_mouse_up(self, event):   
     if self.item: 
      self.on_mouse_drag(event) 
      box = tuple((int(round(v)) for v in event.widget.coords(self.item))) 

      roi = self.currentImage['data'].crop(box) # region of interest 
      values = roi.getdata() # <----------------------- pixel values 
      print roi.size, len(values) 
      #print list(values) 

    def on_right_click(self, event):   
     found = event.widget.find_all() 
     for iid in found: 
      if event.widget.type(iid) == 'rectangle': 
       event.widget.delete(iid) 


app = MyApp() 
app.mainloop() 

在画布的图像就像是你的主要图像对象的“复制品”(这是在内存中)。

在画布上绘制一个矩形,然后将其转换(希望)到您主图像的相应区域,然后移开。