简体   繁体   English

在PIL / TKinter中使用绘图

[英]Using Draw in PIL/TKinter

I'm trying to use PIL and Tkinter to make some custom image processing software. 我正在尝试使用PIL和Tkinter制作一些自定义图像处理软件。 I want to use the mouse to select a region of interest in the image, grab those pixel values, and pass it to scipy/numpy for some number crunching and possible PIL for some more image editing. 我想用鼠标在图像中选择一个感兴趣的区域,获取那些像素值,然后将其传递给scipy / numpy进行一些数字运算,并可能将PIL传递给其他图像编辑。

So far I have a RegionOfInterest class: 到目前为止,我有一个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')

which takes a PIL image object and a boundingBox (with a capture method for cropping and saving the image). 它接受一个PIL图像对象和一个boundingBox(带有用于裁剪和保存图像的捕获方法)。 This gets called by a draw function: 这被绘制函数调用:

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

Which is in turn called by a control-click through Tkinter 依次由Tkinter的Control-click调用

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

My biggest problem at the moment is that when I draw the rectangle (way back in RegionOfIntereste. init ()), the rectangles don't show up! 此刻我最大的问题是,当我绘制矩形(早在RegionOfIntereste。 的init()),矩形显示不出来!

Any advice on how to get this to work? 关于如何使它起作用的任何建议? Perhaps any suggestions for resources on learning how to interface tkinter/pil better? 也许对学习如何更好地连接tkinter / pil的资源有任何建议?

What about something like this: 像这样的事情呢:

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

The image in your canvas is like a 'replica' of your main Image object (which is in memory). 画布中的图像就像是主Image对象(位于内存中)的“副本”。

A rectangle drawn on the canvas then translates (hopefully) to the corresponding area of your main image, and away you go. 然后,在画布上绘制的矩形将(希望地)平移到主图像的相应区域,然后您便离开了。

If you are indeed drawing the rectangle where you think you are, most likely what is happening is that it has a lower stacking level so that it is below the image. 如果确实在您认为自己所在的位置绘制了矩形,则最有可能发生的情况是该矩形的堆叠级别较低,因此位于图像下方。 Try lift ing or lower ing either the rectangle or image. lift ING或lower ING无论是矩形或图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM