Использование Draw в PIL / TKinter - PullRequest
0 голосов
/ 29 марта 2012

Я пытаюсь использовать 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 (с методом захвата для обрезки и сохранения изображения).Это вызывается функцией рисования:

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 ]

3 голосов
/ 31 марта 2012

Что-то вроде этого:

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

Изображение на вашем холсте похоже на «копию» вашего основного объекта изображения (который находится в памяти).затем на холсте переводится (надеюсь) в соответствующую область вашего основного изображения, и вы уходите.

0 голосов
/ 29 марта 2012

Если вы действительно рисуете прямоугольник там, где вы думаете, то, скорее всего, происходит то, что он имеет более низкий уровень стека, так что он находится ниже изображения.Попробуйте lift или lower либо прямоугольник, либо изображение.

...