2017-07-27 5 views
1

私はPython GUI w/Tkinterで作業しています。私は、BMP画像から4つの指定されたポイントの場所を変数に保存し、保存されたポイントを多かれ少なかれ通過する最適な楕円を作成しようとしています。私はまだTkinterとGUIの作業初心者ですので、私を負担してください!Python Tkinter。データポイントからのベストフィット楕円

これまでのところ、コードはポイントをマークし、その位置/座標をプリントアウトすることができます。私はこのような状況のためにmatplotlibを使うべきですか?そのw/tkinterも使えますか?ここで

from tkinter import * 
from PIL import Image, ImageTk 

class Window(Frame): 

    def __init__(self, master=None): 
     Frame.__init__(self, master) 

     self.master = master 
     self.pos = [] 
     self.master.title("GUI") 
     self.pack(fill=BOTH, expand=1) 

     self.counter = 0 

     menu = Menu(self.master) 
     self.master.config(menu=menu) 

     file = Menu(menu) 
     file.add_command(label="Exit", command=self.client_exit) 
     menu.add_cascade(label="File", menu=file) 
     analyze = Menu(menu) 

     analyze.add_command(label="Region of 
     Interest",command=self.regionOfInterest) 
     analyze.add_command(label="Erase", command=self.erasePoints) 

     menu.add_cascade(label="Analyze", menu=analyze) 
     load = Image.open("ap41.ddr.brf.sdat.bmp") 
     render = ImageTk.PhotoImage(load) 

     img = Label(self, image=render) 
     img.image = render 
     img.place(x=0, y=0) 

    def regionOfInterest(self): 
     root.config(cursor="plus") 
     canvas.bind("<Button-1>", self.imgClick) 

    def erasePoints(self): 
     self.pos = [] 

    def client_exit(self): 
     exit() 

    def imgClick(self, event): 

     if self.counter < 4: 
      x = canvas.canvasx(event.x) 
      y = canvas.canvasy(event.y) 
      self.pos.append((x, y)) 
      print(self.pos) 
      canvas.create_line(x - 5, y, x + 5, y, fill="red", 
tags="crosshair") 
      canvas.create_line(x, y - 5, x, y + 5, fill="red", 
tags="crosshair") 
      self.counter += 1 
     else: 
      canvas.unbind("<Button 1>") 
      root.config(cursor="arrow") 
      self.counter = 0 


root = Tk() 
imgSize = Image.open("ap41.ddr.brf.sdat.bmp") 
tkimage = ImageTk.PhotoImage(imgSize) 
w, h = imgSize.size 

canvas = Canvas(root, width=w, height=h) 
canvas.create_image((w/2,h/2),image=tkimage) 
canvas.pack() 

root.geometry("%dx%d"%(w,h)) 
app = Window(root) 
root.mainloop() 
+0

こんにちはFLCL。あなたは 'create_oval() 'でデータを使ってみましたか? –

+0

私はちょうど私の答えを更新しました。私は修正が必要な間違いがあった。 –

+0

ユニークな楕円を定義するには4ポイントでは不十分ですが、5は最小です – f5r5e5d

答えて

1

は、あなたとし、微調整遊ぶことができるものですが、私は、これはあなたがやろうとしているものに近いものになると思う。

は、ここに私のコードです。

最初に左上のコードと右下のコードを処理する方法にリンクしてcreate_ovel()コマンドで楕円を作成する方法にリンクするCreate Ellipseというラベルのメニュー項目を作成しました。これがあなたがしたいことに近いかどうかを教えてください。

以下の新しいメソッドは、各タプルの値を基本タプルと比較し、数値が低い場合は左上のコードを変更し、数値が高い場合は右下のコードを変更します。これらの2組のコードが分かれば、選択したものにおおよそ一致する楕円が作成されます。ここで

from tkinter import * 
from PIL import Image, ImageTk 

class Window(Frame): 

    def __init__(self, master=None): 
     Frame.__init__(self, master) 

     self.master = master 
     self.pos = [] 
     self.master.title("GUI") 
     self.pack(fill=BOTH, expand=1) 

     self.counter = 0 

     menu = Menu(self.master) 
     self.master.config(menu=menu) 

     file = Menu(menu) 
     file.add_command(label="Exit", command=self.client_exit) 
     menu.add_cascade(label="File", menu=file) 
     analyze = Menu(menu) 

     analyze.add_command(label="Region of Interest",command=self.regionOfInterest) 
     analyze.add_command(label="Erase", command=self.erasePoints) 
     analyze.add_command(label="Create Ellipse", command=self.createEllipse) 

     menu.add_cascade(label="Analyze", menu=analyze) 
     load = Image.open("./Colors/1.png") 
     render = ImageTk.PhotoImage(load) 


     img = Label(self, image=render) 
     img.image = render 
     img.place(x=0, y=0) 

    def createEllipse(self): 

     top_left_cords = self.pos[0] 
     bottom_right_cords = self.pos[0] 
     for pos in self.pos: 
      if pos[0] < top_left_cords[0]: 
       top_left_cords = (pos[0], top_left_cords[1]) 

      if pos[1] < top_left_cords[1]: 
       top_left_cords = (top_left_cords[0], pos[1]) 

      if pos[0] > bottom_right_cords[0]: 
       bottom_right_cords = (pos[0], bottom_right_cords[1]) 

      if pos[1] > bottom_right_cords[1]: 
       bottom_right_cords = (bottom_right_cords[0], pos[1]) 

     print(top_left_cords, bottom_right_cords) 

     canvas.create_oval(top_left_cords, bottom_right_cords) 

    def regionOfInterest(self): 
     root.config(cursor="plus") 
     canvas.bind("<Button-1>", self.imgClick) 

    def erasePoints(self): 
     self.pos = [] 

    def client_exit(self): 
     exit() 

    def imgClick(self, event): 

     if self.counter < 4: 
      x = canvas.canvasx(event.x) 
      y = canvas.canvasy(event.y) 
      self.pos.append((x, y)) 
      print(self.pos) 
      canvas.create_line(x - 5, y, x + 5, y, fill="red", 
tags="crosshair") 
      canvas.create_line(x, y - 5, x, y + 5, fill="red", 
tags="crosshair") 
      self.counter += 1 
     else: 
      canvas.unbind("<Button 1>") 
      root.config(cursor="arrow") 
      self.counter = 0 


root = Tk() 
imgSize = Image.open("./Colors/1.png") 
tkimage = ImageTk.PhotoImage(imgSize) 
w, h = imgSize.size 

canvas = Canvas(root, width=w, height=h) 
canvas.create_image((w/2,h/2),image=tkimage) 
canvas.pack() 

root.geometry("%dx%d"%(w,h)) 
app = Window(root) 
root.mainloop() 

は前と後、私はテストのために持っているサンプル画像からである:

def createEllipse(self): 

    top_left_cords = self.pos[0] 
    bottom_right_cords = self.pos[0] 
    for pos in self.pos: 
     if pos[0] < top_left_cords[0]: 
      top_left_cords = (pos[0], top_left_cords[1]) 

     if pos[1] < top_left_cords[1]: 
      top_left_cords = (top_left_cords[0], pos[1]) 

     if pos[0] > bottom_right_cords[0]: 
      bottom_right_cords = (pos[0], bottom_right_cords[1]) 

     if pos[1] > bottom_right_cords[1]: 
      bottom_right_cords = (bottom_right_cords[0], pos[1]) 

以下は完全なコードです。

前:

enter image description here

後:再び

enter image description here

+0

もう一度!遅れて返事をおかけして申し訳ありません。あなたのコードの詳細な実行をありがとう!残念ながら、私はそれを実行しようとすると、bmp画像上のマークされた点に残念ながら表示されませんが、それでもtop_left_cords&bottom_right_cordsの値を出力しますので、動作すると思います!多分私はキャンバスを使わなければならないと感じています。 – FLCL

+0

@FLCLハム。まあそれは私のために働く。私はちょうど私がテストできるものにイメージを変更しました。私はテストの私の側から前と後のイメージを追加しました。 –

+0

@FLCL楕円を作成するために新しいメニューボタンを使いましたか? –