forked from MicronOxford/microscope.tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
select_circle.py
118 lines (106 loc) · 4.7 KB
/
select_circle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/python
# -*- coding: utf-8
#
# Copyright 2017 Mick Phillips ([email protected])
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Display a window that allows the user to select a circular area."""
import Tkinter as tk
from PIL import Image
import numpy as np
from resizeimage import resizeimage
import sys
class App(tk.Frame):
def __init__(self, filename, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.filename = str(filename)
self.ratio = 4
self.offset = [45, 50]
self.create_widgets()
def create_widgets(self):
self.canvas = Canvas(self, width=600, height=600)
temp = Image.open(self.filename)
if len(np.shape(temp)) == 2:
temp = resizeimage.resize_cover(temp, [(np.shape(temp)[0]/self.ratio),(np.shape(temp)[1]/self.ratio)])
temp = temp.save("photo.ppm", "ppm")
elif len(np.shape(temp)) == 3:
temp = resizeimage.resize_cover(temp[0,:,:], ([np.shape(temp)[1],np.shape(temp)[2]]/self.ratio))
temp = temp.save("photo.ppm", "ppm")
self.image = tk.PhotoImage(file = "photo.ppm")
self.canvas.create_image(self.offset[0], self.offset[1], anchor = tk.NW, image = self.image)
self.canvas.pack()
self.btn_quit = tk.Button(self, text="Quit", command=self.quit)
self.btn_quit.pack()
class Canvas(tk.Canvas):
def __init__(self, *args, **kwargs):
tk.Canvas.__init__(self, *args, **kwargs)
self.bind("<Button-1>", self.on_click)
self.bind("<Button-3>", self.on_click)
self.bind("<B1-Motion>", self.circle_resize)
self.bind("<B3-Motion>", self.circle_drag)
self.bind("<ButtonRelease>", self.on_release)
self.circle = None
self.p_click = None
self.bbox_click = None
self.centre = [0,0]
self.diameter = 0
self.ratio = 4
self.offset = [45, 50]
def on_release(self, event):
self.p_click = None
self.bbox_click = None
def on_click(self, event):
if self.circle == None:
self.circle = self .create_oval((event.x-1, event.y-1, event.x+1, event.y+1))
self.centre[0] = (event.x - self.offset[0]) * self.ratio
self.centre[1] = (event.y - self.offset[1]) * self.ratio
self.diameter = (event.x+1 - event.x+1 + 1) * self.ratio
np.savetxt('circleParameters.txt', (self.centre[0], self.centre[1], self.diameter))
def circle_resize(self, event):
if self.circle is None:
return
if self.p_click is None:
self.p_click = (event.x, event.y)
self.bbox_click = self.bbox(self.circle)
return
bbox = self.bbox(self.circle)
unscaledCentre = ((bbox[2] + bbox[0])/2, (bbox[3] + bbox[1])/2)
r0 = ((self.p_click[0] - unscaledCentre[0])**2 + (self.p_click[1] - unscaledCentre[1])**2)**0.5
r1 = ((event.x - unscaledCentre[0])**2 + (event.y - unscaledCentre[1])**2)**0.5
scale = r1 / r0
self.scale(self.circle, unscaledCentre[0], unscaledCentre[1], scale, scale)
self.p_click= (event.x, event.y)
self.diameter = (self.bbox(self.circle)[2] - self.bbox(self.circle)[0]) * self.ratio
np.savetxt('circleParameters.txt', (self.centre[0], self.centre[1], self.diameter))
def circle_drag(self, event):
if self.circle is None:
return
if self.p_click is None:
self.p_click = (event.x, event.y)
return
self.move(self.circle,
event.x - self.p_click[0],
event.y - self.p_click[1])
self.p_click = (event.x, event.y)
bbox = self.bbox(self.circle)
unscaledCentre = ((bbox[2] + bbox[0]) / 2, (bbox[3] + bbox[1]) / 2)
self.centre[0] = (unscaledCentre[0] - self.offset[0]) * self.ratio
self.centre[1] = (unscaledCentre[1] - self.offset[1]) * self.ratio
np.savetxt('circleParameters.txt', (self.centre[0], self.centre[1], self.diameter))
self.update()
if __name__ == '__main__':
app = App('%s' %sys.argv[1])
app.master.title('Select a circle.')
app.mainloop()