2012-03-28 62 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() 

在畫布的圖像就像是你的主要圖像對象的「複製品」(這是在內存中)。

在畫布上繪製一個矩形,然後將其轉換(希望)到您主圖像的相應區域,然後移開。