在PIL / TKinter中使用Draw

时间:2012-03-28 23:47:42

标签: python image-processing tkinter python-imaging-library

我正在尝试使用PIL和Tkinter制作一些自定义图像处理软件。我想使用鼠标选择图像中感兴趣的区域,抓取那些像素值,并将其传递给scipy / numpy以进行一些数字处理和可能的PIL以进行更多图像编辑。

到目前为止,我有一个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(使用捕获方法进行裁剪和保存图像)。这由draw函数调用:

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 = []

然后通过控件点击Tkinter来调用

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()

目前我最大的问题是当我绘制矩形(回到RegionOfIntereste。 init ())时,矩形不显示!

有关如何使其发挥作用的任何建议?也许有关于学习如何更好地连接tkinter / pil的资源的任何建议?

2 个答案:

答案 0 :(得分: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()

画布中的图像就像是主Image对象(位于内存中)的“副本”。

在画布上绘制的矩形然后(希望)翻译到你的相应区域 主要形象,然后离开。

答案 1 :(得分:0)

如果您确实正在绘制您认为自己所在的矩形,那么最有可能的是它具有较低的堆叠级别,因此它位于图像下方。尝试liftlower矩形或图像。