new_interface_demo_2.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. # https://github.com/Antoniii/Medicine-App/blob/master/README.md
  2. # conda create -n TEST python=3.5
  3. ### conda activate TEST
  4. # pip install Pillow
  5. # pip install cx-Freeze
  6. from pathlib import Path
  7. from tkinter import filedialog
  8. from tkinter import *
  9. from PIL import ImageTk, Image, ImageFont, ImageDraw
  10. from time import time
  11. root = Tk()
  12. current_dir = Path.cwd() # путь текущей директории
  13. filename = filedialog.askopenfilename(initialdir = current_dir, # initialdir = "/run/media/rick/DATA/Kazahi"
  14. title = "Select imagefile", filetypes = (("JPG files", "*.JPG"),("jpeg files", "*.jpeg"),
  15. ("jpg files", "*.jpg"),("png files", "*.png"),
  16. ("bmp files", "*.bmp"),("all files", "*.*")))
  17. N_size = 850
  18. size = (N_size, N_size)
  19. radius = 350 # диаметр маски
  20. p_x = 550
  21. p_y = 500
  22. antialias = 3
  23. # percent = 100
  24. # square = 555
  25. diameter = 15 # mm
  26. def prepare_mask(size, antialias = 2):
  27. mask = Image.new('L', (size[0] * antialias, size[1] * antialias), 0)
  28. #p = 390
  29. parametr = (mask.size[0] - p_x, mask.size[1] - p_y)
  30. ImageDraw.Draw(mask).ellipse((radius, radius) + parametr, fill=255)
  31. #print(p)
  32. # print((radius, radius) + parametr)
  33. return mask.resize(size, Image.ANTIALIAS)
  34. def crop(im, s):
  35. w, h = im.size
  36. k = w / s[0] - h / s[1]
  37. if k > 0: im = im.crop(((w - h) / 2, 0, (w + h) / 2, h))
  38. elif k < 0: im = im.crop((0, (h - w) / 2, w, (h + w) / 2))
  39. return im.resize(s, Image.ANTIALIAS)
  40. image = Image.open(filename).convert('L')
  41. k_size = 0.5 # коэффициент сжатия изображения
  42. #print(int(image.size[0]*k_size), int(image.size[1]*k_size))
  43. #image = image.resize((int(image.size[0]*k_size),int(image.size[1]*k_size)))
  44. image = image.resize((536,356))
  45. #print(image.size[0], image.size[1])
  46. root_y = 300
  47. #root.geometry('{}x{}'.format(image.size[0],int(image.size[1]+root_y)))
  48. root.geometry('{}x{}'.format(536,506))
  49. #print(image.size[0], int(image.size[1]+root_y))
  50. #canvas = Canvas(root,width=image.size[0],height=image.size[1])
  51. canvas = Canvas(root,width=536,height=356)
  52. #print(image.size[0], image.size[1])
  53. canvas.pack()
  54. # image = crop(image, size)
  55. # image.putalpha(prepare_mask(size, antialias))
  56. # image = image.convert('L')
  57. pilimage = ImageTk.PhotoImage(image)
  58. # kx_imagesprite = 0.5
  59. # ky_imagesprite = 0.5
  60. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*ky_imagesprite),image=pilimage)
  61. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  62. container = Frame() # создаём контейнер на главном окне для расположения кнопок и полей ввода
  63. container.pack(side='top', fill='both', expand=True)
  64. M = 255 # условие max
  65. L = 0 # min
  66. ########################################################################
  67. lbl1 = Label(container, text="Max = ")
  68. lbl1.grid(column=6, row=1)
  69. def get_val_motion(event):
  70. global M
  71. M = scal.get()
  72. scal = Scale(container, orient=HORIZONTAL, length=int(image.size[0]*0.6), from_=0, to=255,
  73. tickinterval=1, resolution=1)
  74. scal.bind("<B1-Motion>", get_val_motion)
  75. scal.grid(column=7, row=1)
  76. ########################################################################
  77. lbl2 = Label(container, text="Min = ")
  78. lbl2.grid(column=6, row=2)
  79. def get_val_motion_1(event_1):
  80. global L
  81. L = scal1.get()
  82. scal1 = Scale(container, orient=HORIZONTAL, length=int(image.size[0]*0.6), from_=0, to=255,
  83. tickinterval=1, resolution=1)
  84. scal1.bind("<B1-Motion>", get_val_motion_1)
  85. scal1.grid(column=7, row=2)
  86. ########################################################################
  87. def my_callback2(): # главная функция - для расчёта
  88. N = 0 # счётчик
  89. new_im = []
  90. start = time() # для тестирования скорости работы
  91. for i in range(image.size[0]):
  92. for j in range(image.size[1]):
  93. if (image.getpixel((i,j)) >= L) and (image.getpixel((i,j)) <= M):
  94. N += 1
  95. new_im.append((i,j,image.getpixel((i,j))))
  96. #global percent
  97. percent = N/(image.size[0]*image.size[1])*100
  98. global diameter
  99. square_global = 3.141593*(diameter**2)/4.0
  100. square_local = (square_global * percent) / 100.0
  101. #print(percent, square_global, square_local)
  102. print("Time {0:.3f} s".format(float(round((time()-start)*1e3)/1e3))) # для тестирования скорости работы
  103. global new_image # нужно для возможности сохранения в дальнейшем
  104. new_image = Image.new("L", (image.size[0], image.size[1]))
  105. for i in range(len(new_im)):
  106. new_image.putpixel((new_im[i][0], new_im[i][1]), new_im[i][2])
  107. #size = (700, 700)
  108. new_image = crop(new_image, size)
  109. new_image.putalpha(prepare_mask(size, antialias))
  110. draw = ImageDraw.Draw(new_image) # для отрисовки текста на изображении
  111. front_size = int(66*k_size**2)
  112. font = ImageFont.truetype("san-serif.ttf", front_size) # параметры текста
  113. k_x = 0.35
  114. k_y = 0.6
  115. draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)),"Result: {0:.1f}% = {1:.1f} mm^2".format(percent, square_local), 255,font=font) # наносим текст на изображение
  116. #draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)+front_size),"(L = {}, M = {}, N_size = {}, Radius_size = {})".format(L, M, N_size, radius), 255,font=font)
  117. draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)+front_size),"(L = {}, M = {})".format(L, M), 255,font=font)
  118. global pilimage
  119. pilimage = ImageTk.PhotoImage(new_image)
  120. global imagesprite
  121. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*kx_imagesprite), image=pilimage)
  122. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  123. button2 = Button(container , text="Result" , command=my_callback2)
  124. button2.grid(row=1 ,column=0)
  125. ########################################################################
  126. def my_callback3(): # показывает исходную фотографию
  127. #print('return button pushed')
  128. global pilimage
  129. pilimage = ImageTk.PhotoImage(image)
  130. global imagesprite
  131. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*kx_imagesprite),image=pilimage)
  132. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  133. button3 = Button(container , text="Source" , command=my_callback3)
  134. button3.grid(row=1 ,column=1)
  135. ########################################################################
  136. def my_callback4(): # сохраняет результат
  137. file_name = filedialog.asksaveasfilename(initialdir = current_dir,
  138. filetypes = (("png files", "*.png"),
  139. ("jpg files", "*.jpg"),
  140. ("bmp files", "*.bmp"),("all files", "*.*")), defaultextension="")
  141. global new_image
  142. new_image.save(file_name)
  143. button4 = Button(container , text="Save Result" , command=my_callback4)
  144. button4.grid(row=1 ,column=2)
  145. ########################################################################
  146. def my_callback5(): # открыть новое
  147. global filename
  148. filename = filedialog.askopenfilename(initialdir = current_dir, # initialdir = "/run/media/rick/DATA/Kazahi"
  149. title = "Select imagefile", filetypes = (("JPG files", "*.JPG"),("jpeg files", "*.jpeg"),
  150. ("jpg files", "*.jpg"),("png files", "*.png"),
  151. ("bmp files", "*.bmp"),("all files", "*.*")))
  152. global image
  153. image = Image.open(filename).convert('L')
  154. image = crop(image, size)
  155. image.putalpha(prepare_mask(size, antialias))
  156. image = image.convert('L')
  157. # global k_size
  158. # k_size = 0.6 # коэффициент сжатия изображения
  159. # image = image.resize((int(image.size[0]*k_size),int(image.size[1]*k_size)))
  160. # global root
  161. # root.geometry('{}x{}'.format(image.size[0],int(image.size[1]+root_y)))
  162. # global canvas
  163. # canvas = Canvas(root,width=image.size[0],height=image.size[1])
  164. # canvas.pack()
  165. global pilimage
  166. pilimage = ImageTk.PhotoImage(image)
  167. global imagesprite
  168. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*kx_imagesprite),image=pilimage)
  169. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  170. button5 = Button(container , text="Open New Image" , command=my_callback5)
  171. button5.grid(row=1 ,column=3)
  172. ########################################################################
  173. def my_callback6(): # открыть новое маленькое изображение
  174. global filename
  175. filename = filedialog.askopenfilename(initialdir = current_dir, # initialdir = "/run/media/rick/DATA/Kazahi"
  176. title = "Select imagefile", filetypes = (("JPG files", "*.JPG"),("jpeg files", "*.jpeg"),
  177. ("jpg files", "*.jpg"),("png files", "*.png"),
  178. ("bmp files", "*.bmp"),("all files", "*.*")))
  179. global image
  180. image = Image.open(filename).convert('L')
  181. # global k_size
  182. # k_size = 0.6 # коэффициент сжатия изображения
  183. image = image.resize((536,356))
  184. # global root
  185. # root.geometry('{}x{}'.format(800,800))
  186. # global canvas
  187. # canvas = Canvas(root,width=image.size[0],height=image.size[1])
  188. # canvas.pack()
  189. global pilimage
  190. pilimage = ImageTk.PhotoImage(image)
  191. global imagesprite
  192. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*kx_imagesprite),image=pilimage)
  193. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  194. button6 = Button(container , text="Open Small Image" , command=my_callback6)
  195. button6.grid(row=2 ,column=0)
  196. ########################################################################
  197. def my_callback7(): # главная функция - для расчёта маленького изображения
  198. N = 0 # счётчик
  199. new_im = []
  200. start = time() # для тестирования скорости работы
  201. for i in range(image.size[0]):
  202. for j in range(image.size[1]):
  203. if (image.getpixel((i,j)) >= L) and (image.getpixel((i,j)) <= M):
  204. N += 1
  205. new_im.append((i,j,image.getpixel((i,j))))
  206. #global percent
  207. percent = N/(image.size[0]*image.size[1])*100
  208. #global diameter
  209. #square_global = 3.141593*(diameter**2)/4.0
  210. #square_local = (square_global * percent) / 100.0
  211. #print(percent, square_global, square_local)
  212. print("Time {0:.3f} s".format(float(round((time()-start)*1e3)/1e3))) # для тестирования скорости работы
  213. global new_image # нужно для возможности сохранения в дальнейшем
  214. new_image = Image.new("L", (image.size[0], image.size[1]))
  215. for i in range(len(new_im)):
  216. new_image.putpixel((new_im[i][0], new_im[i][1]), new_im[i][2])
  217. #size = (700, 700)
  218. #new_image = crop(new_image, size)
  219. #new_image.putalpha(prepare_mask(size, antialias))
  220. draw = ImageDraw.Draw(new_image) # для отрисовки текста на изображении
  221. front_size = int(66*k_size**2)
  222. font = ImageFont.truetype("san-serif.ttf", front_size) # параметры текста
  223. k_x = 0.35
  224. k_y = 0.6
  225. draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)),"Result: {0:.1f}%".format(percent), 255,font=font) # наносим текст на изображение
  226. #draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)+front_size),"(L = {}, M = {}, N_size = {}, Radius_size = {})".format(L, M, N_size, radius), 255,font=font)
  227. draw.text((int(new_image.size[0]*k_x), int(new_image.size[1]*k_y)+front_size),"(L = {}, M = {})".format(L, M), 255,font=font)
  228. global pilimage
  229. pilimage = ImageTk.PhotoImage(new_image)
  230. global imagesprite
  231. #imagesprite = canvas.create_image(int(image.size[0]*kx_imagesprite),int(image.size[1]*kx_imagesprite), image=pilimage)
  232. imagesprite = canvas.create_image(0,0,image=pilimage, anchor=NW)
  233. button7 = Button(container , text="SmallResult" , command=my_callback7)
  234. button7.grid(row=2 ,column=1)
  235. ########################################################################
  236. lbl7 = Label(container, text="Calibration (current diameter = 15 mm):") # калибровка
  237. lbl7.grid(column=0, row=3)
  238. lbl8 = Label(container, text="Diameter = ")
  239. lbl8.grid(column=0, row=4)
  240. txt8 = Entry(container,width=5)
  241. txt8.grid(column=1, row=4)
  242. lbl8 = Label(container, text="mm")
  243. lbl8.grid(column=2, row=4)
  244. def clicked8():
  245. global diameter
  246. diameter = float(txt8.get())
  247. print(diameter)
  248. btn8 = Button(container, text="Input diameter", command=clicked8)
  249. btn8.grid(column=3, row=4)
  250. root.mainloop()