Mikroskop mit Tkinter-GUi

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
kaytec
User
Beiträge: 541
Registriert: Dienstag 13. Februar 2007, 21:57

Re: Mikroskop mit Tkinter-GUi

Beitragvon kaytec » Sonntag 15. April 2018, 20:47

Hallo,

mit der Maus kann das Bild verschoben werden.

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8
  3. from __future__ import division
  4.  
  5. import tkinter as tk
  6. import os
  7. import datetime
  8. import cv2
  9. from PIL import Image, ImageTk
  10. from functools import partial
  11. from itertools import cycle
  12. import numpy as np
  13.  
  14. WIDTH = 640
  15. HEIGHT = 480
  16. VIDEO_CODEC = "XVID"
  17. DEFAULT_CAM_ID = 0
  18.  
  19.  
  20. class Microscope(object):
  21.  
  22.     PROPID_WIDTH = 3
  23.     PROPID_HEIGHT = 4
  24.     INTERPOLATION_METHODS= {"NEAREST" : cv2.INTER_NEAREST,
  25.                             "LINEAR" : cv2.INTER_LINEAR,
  26.                             "AREA" : cv2.INTER_AREA,
  27.                             "CUBIC" : cv2.INTER_CUBIC,
  28.                             "LANCZOS4" : cv2.INTER_LANCZOS4}
  29.  
  30.     def __init__(self, cam_id=DEFAULT_CAM_ID, number_of_imgs=10,
  31.         series_time_interval=1, image_path=".", video_path=".",
  32.         series_img_path=".", img_format=".tiff"):
  33.         self.cam = cv2.VideoCapture(cam_id)
  34.         if not self.cam.isOpened():
  35.             raise RuntimeError("can not open camera {0!r}".format(
  36.                 cam_id))
  37.         self.img_format = img_format
  38.         self.inter_frame = None
  39.         self.last_frame = None
  40.         self.take_series = False
  41.         self.recording = False
  42.         self.number_of_imgs = number_of_imgs
  43.         self.series_counter = None
  44.         self.series_time_counter = None
  45.         self.series_time_interval = series_time_interval
  46.         self.image_path = image_path
  47.         self.video_path = video_path
  48.         self.series_img_path = series_img_path
  49.         self.series_dir = None
  50.         self.interpolation_methods_keys = cycle(
  51.             self.INTERPOLATION_METHODS.keys())
  52.         self.interpolation_method = self.interpolation_methods_keys.next()
  53.         self.cam_width = self.zoom_width = int(self.cam.get(self.PROPID_WIDTH))
  54.         self.cam_height = self.zoom_height = int(self.cam.get(self.PROPID_HEIGHT))
  55.        
  56.     def __enter__(self):
  57.         return self
  58.  
  59.     def __exit__(self, *args):
  60.         self.release()
  61.  
  62.     @property
  63.     def size(self):
  64.         return self.cam_width, self.cam_height
  65.        
  66.     @property
  67.     def zoom_size(self):
  68.         return self.zoom_width, self.zoom_height
  69.        
  70.     @property
  71.     def interpolation(self):
  72.         return self.interpolation_method
  73.  
  74.     def get_image(self):
  75.         state, frame = self.cam.read()
  76.        
  77.         if state and np.array_equal(self.last_frame, frame):
  78.             self.release()
  79.             state = False
  80.         if not state:
  81.             raise RuntimeError("could not read image")
  82.  
  83.         self.last_frame = frame
  84.         self.inter_frame = cv2.resize(frame, self.zoom_size,
  85.         interpolation = self.INTERPOLATION_METHODS[
  86.             self.interpolation_method])
  87.            
  88.         if self.take_series:
  89.             self.series_time_counter += 1
  90.             if self.series_time_counter > self.series_time_interval:
  91.                 self.series_counter += 1
  92.                 self.series_time_counter = 0
  93.                 if self.series_counter <= self.number_of_imgs:
  94.                     img_name = "{0}{1}".format(self.series_counter,
  95.                         self.img_format)
  96.                     cv2.imwrite(os.path.join(self.series_img_path,
  97.                         self.series_dir, img_name), self.inter_frame)
  98.                 else:
  99.                     self.take_series = False
  100.         if self.recording:
  101.             self.video_writer.write(self.inter_frame)
  102.         return self.inter_frame
  103.  
  104.     def recording_start_stop(self, name = None):
  105.         if self.recording:
  106.             self.recording = False
  107.         else:
  108.             self.recording = True
  109.             self.video_writer = cv2.VideoWriter(os.path.join(
  110.                 self.video_path, name if name else
  111.                 "{0:%d%b%Y_%H_%M_%S.%f}.avi".format(datetime.datetime.utcnow()
  112.                 )), cv2.cv.CV_FOURCC(* VIDEO_CODEC), 24, self.zoom_size)
  113.                
  114.     def take_series_picture(self):
  115.         if not self.take_series:        
  116.             self.series_dir = "{0:%d%b%Y_%H_%M_%S.%f}".format(
  117.                 datetime.datetime.utcnow())
  118.             os.makedirs(self.series_dir)
  119.             self.series_time_counter = 0
  120.             self.series_counter = 0
  121.             self.take_series = True
  122.  
  123.     def take_picture(self, name = None):
  124.         if not name:
  125.             name = "{0:%d%b%Y_%H_%M_%S.%f}{1}".format(
  126.                 datetime.datetime.utcnow(), self.img_format)
  127.         cv2.imwrite(os.path.join(self.image_path, name), self.inter_frame)
  128.        
  129.     def series_up_down(self, step):
  130.         if not self.take_series:
  131.             if self.number_of_imgs > -step:
  132.                 self.number_of_imgs += step
  133.        
  134.     def set_time_interval(self, step):
  135.         if not self.take_series:
  136.             if self.series_time_interval > -step:
  137.                 self.series_time_interval += step
  138.        
  139.     def zoom_image(self, step):
  140.         height = int(self.zoom_height + step)
  141.         width = int(height * self.cam_width / self.cam_height)
  142.         if width > 0 and height > 0:
  143.             self.zoom_width = width
  144.             self.zoom_height = height
  145.  
  146.     def reset_zoom(self):
  147.         self.zoom_width, self.zoom_height = self.size
  148.        
  149.     def next_interpolation_method(self):
  150.         self.interpolation_method = self.interpolation_methods_keys.next()
  151.        
  152.     def release(self):
  153.         self.cam.release()
  154.  
  155. class MicroscopeUI(tk.Frame):
  156.  
  157.     UPDATE_INTERVAL = 10
  158.     REC_ON = 5
  159.    
  160.     def __init__(self, parent, microscope, width, height, zoom_step=10):
  161.         tk.Frame.__init__(self, parent)
  162.         self.parent = parent
  163.         self.width = width
  164.         self.height = height
  165.         self.tk_image = None
  166.         self.rec_on = cycle(x for x in xrange(self.REC_ON))
  167.         self.text_on = False
  168.         self.microscope = microscope
  169.         self.text_colour_index = cycle(["white", "green", "black", "red",
  170.             "magenta", "green", "brown", "yellow", "blue", "orange", "gray"])
  171.         self.text_colour = self.text_colour_index.next()
  172.         self.canvas = tk.Canvas(self, width=width, height=height)
  173.         self.canvas.grid(column=0, row=0)
  174.         self.canvas.bind("<ButtonPress-1>", self.start_slide)
  175.         self.canvas.bind("<B1-Motion>", self.slide_image)
  176.         self.vscrollbar = tk.Scrollbar(self)
  177.         self.vscrollbar.grid(column=1, row=0, sticky=tk.N+tk.S)
  178.         self.canvas.config(yscrollcommand=self.vscrollbar.set)
  179.         self.vscrollbar.config(command=self.canvas.yview)
  180.         self.hscrollbar = tk.Scrollbar(self, orient=tk.HORIZONTAL)
  181.         self.hscrollbar.grid(column=0, row=1, columnspan=5, sticky=tk.E+tk.W)
  182.         self.canvas.config(xscrollcommand=self.hscrollbar.set)
  183.         self.hscrollbar.config(command=self.canvas.xview)
  184.         button_frame = tk.Frame(self)
  185.         button_frame.grid(column=0, row=3, columnspan=2)
  186.         self.buttons = list()
  187.         for column, (text, width, command, var)in enumerate(
  188.             (("||", 2, self.capture_start_stop, ()),
  189.              ("Z+", 2, self.microscope.zoom_image, (zoom_step,)),
  190.              ("Z-", 2, self.microscope.zoom_image, (-zoom_step,)),
  191.              ("Z+/-", 2, self.microscope.reset_zoom, ()),
  192.              ("[1]", 2, self.microscope.take_picture, ()),
  193.              ("REC", 2, self.recording_start_stop, ()),
  194.              ("[S]]]", 2, self.microscope.take_series_picture, ()),
  195.              ("INTPOL", 5, self.next_interpolation_method, ()),
  196.              ("S+", 2, self.series_up_down, (1,)),
  197.              ("S-", 2, self.series_up_down, (-1,)),
  198.              ("T+", 2, self.time_interval_up_down, (
  199.               self.microscope.series_time_interval,)),
  200.              ("T-", 2, self.time_interval_up_down, (
  201.               -self.microscope.series_time_interval,)),
  202.              ("ON", 2, self.set_text_on_off, ()),
  203.              ("C", 2, self.change_text_colour, ()))):
  204.             button = tk.Button(button_frame, text=text, width=width,
  205.                 relief="raised", font="Arial 10 bold",
  206.                 command=partial(command, *var))
  207.             button.grid(column=column, row=0)
  208.             self.buttons.append(button)
  209.  
  210.     def slide_image(self, event):
  211.         self.canvas.scan_dragto(event.x, event.y, gain=-1)
  212.        
  213.     def start_slide(self, event):
  214.         self.canvas.scan_mark(event.x, event.y)
  215.        
  216.     def capture_start_stop(self):
  217.         if self.after_id is None:
  218.             self.buttons[0].config(text = "||")
  219.             self.run()
  220.         else:
  221.             self.buttons[0].config(text = ">")
  222.             self.after_cancel(self.after_id)
  223.             self.after_id = None
  224.  
  225.     def run(self):
  226.         try:
  227.             tk_image = Image.frombytes("RGB",  self.microscope.zoom_size,
  228.                 self.microscope.get_image(), "raw", "BGR")
  229.         except RuntimeError:
  230.             self.raise_cam_id_error()
  231.             return
  232.  
  233.         self.canvas.delete("img", "rec", "txt")
  234.         self.tk_image = ImageTk.PhotoImage(tk_image)
  235.         self.canvas.create_image((0,0), anchor=tk.NW,
  236.             image=self.tk_image, tag="img")
  237.         width, height = self.microscope.zoom_size
  238.         if self.text_on:        
  239.             rec_text = " "
  240.             if self.microscope.recording and not self.rec_on.next():
  241.                 rec_text = "O"
  242.             self.canvas.create_text(width / 2, height / 2,
  243.                 text="+", font="Courier 30", fill=self.text_colour,
  244.                 tag="txt")
  245.             self.canvas.create_text(width / 2,
  246.                 10 + height/2 - self.height / 2,
  247.                 font="Courier 13 bold",
  248.                 text = "REC:{0}  FILTER:{1}  SERIES:{2}  TIME:{3}  RES:{4}:{5}"
  249.                 .format(rec_text,
  250.                     self.microscope.interpolation,
  251.                     self.microscope.number_of_imgs,                            
  252.                     self.microscope.series_time_interval,
  253.                     width, height),
  254.                 anchor="center",
  255.                 fill = self.text_colour,
  256.                 tag = "txt")
  257.  
  258.         state = tk.DISABLED if self.microscope.take_series else tk.NORMAL
  259.         for button in (1, 2, 3, 7, 8, 9, 10, 11):
  260.             self.buttons[button].config(state=state)
  261.                
  262.         width, height = self.microscope.zoom_size
  263.         self.canvas.config(scrollregion = (0, 0, width, height))
  264.         self.after_id = self.after(self.UPDATE_INTERVAL, self.run)
  265.            
  266.     def change_text_colour(self):      
  267.         self.set_text_on_off(True)
  268.         self.text_colour = self.text_colour_index.next()
  269.        
  270.     def set_text_on_off(self, force_on=False):
  271.         self.text_on = force_on or not self.text_on
  272.         self.buttons[12].config(text="OFF" if self.text_on else "ON")
  273.        
  274.     def raise_cam_id_error(self):
  275.         self.canvas.delete("img", "rec", "txt")
  276.         self.canvas.create_text((self.width / 2, self.height / 2),
  277.             text='NO CAM', font='Arial 40')
  278.         for button in self.buttons:
  279.             button.config(state="disabled")
  280.            
  281.     def recording_start_stop(self):
  282.         self.set_text_on_off(True)
  283.         self.microscope.recording_start_stop()
  284.        
  285.     def series_up_down(self, step):
  286.         self.set_text_on_off(True)
  287.         self.microscope.series_up_down(step)
  288.        
  289.     def time_interval_up_down(self, step):
  290.         self.set_text_on_off(True)
  291.         self.microscope.set_time_interval(step)
  292.        
  293.     def next_interpolation_method(self):
  294.         self.set_text_on_off(True)
  295.         self.microscope.next_interpolation_method()
  296.  
  297.     def release(self):
  298.         self.parent.destroy()
  299.  
  300. def main():
  301.     root = tk.Tk()
  302.     root.title('MICROSCOPE')
  303.    
  304.     try:
  305.         with Microscope(series_time_interval=1) as microscope:
  306.             def take_picture(e):
  307.                 microscope_ui.take_picture()
  308.             microscope_ui = MicroscopeUI(
  309.                 root, microscope, WIDTH, HEIGHT)
  310.             microscope_ui.pack(expand=tk.YES)
  311.             microscope_ui.run()
  312.             root.protocol("WM_DELETE_WINDOW", microscope_ui.release)
  313.             #root.bind("<Key" + chr(10) + ">", take_picture)
  314.             root.mainloop()
  315.            
  316.     except RuntimeError:
  317.         tk.Label(root, text = 'can not open camera {0!r}'.format(
  318.                 DEFAULT_CAM_ID), font = "Arial 20", height = 10).pack()
  319.         root.mainloop()
  320.    
  321. if __name__ == '__main__':
  322.     main()


Gruß
Benutzeravatar
kaytec
User
Beiträge: 541
Registriert: Dienstag 13. Februar 2007, 21:57

Re: Mikroskop mit Tkinter-GUi

Beitragvon kaytec » Montag 23. April 2018, 19:39

Hallo,

es kann jetzt mit dem Button "AR" das Seitenverhältnis geändert werden und diese Funktion ist für Mikroskopaufnahmen völlig unnötig. Da auch alle anderen USB-Kameras erkannt werden ist es evt. doch brauchbar. Ich habe ein China Cinch/USB-Konverter verwendet und eine alte Videokamera ausgelesen.

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8
  3. from __future__ import division
  4.  
  5. import tkinter as tk
  6. import os
  7. import datetime
  8. import cv2
  9. from PIL import Image, ImageTk
  10. from functools import partial
  11. from itertools import cycle
  12. import numpy as np
  13.  
  14. WIDTH = 640
  15. HEIGHT = 480
  16. VIDEO_CODEC = "XVID"
  17. DEFAULT_CAM_ID = 0
  18.  
  19.  
  20. class Microscope(object):
  21.  
  22.     PROPID_WIDTH = 3
  23.     PROPID_HEIGHT = 4
  24.     INTERPOLATION_METHODS = {"NEAREST" : cv2.INTER_NEAREST,
  25.                              "LINEAR" : cv2.INTER_LINEAR,
  26.                              "AREA" : cv2.INTER_AREA,
  27.                              "CUBIC" : cv2.INTER_CUBIC,
  28.                              "LANCZOS4" : cv2.INTER_LANCZOS4}
  29.                            
  30.     ASPECT_RATIO = {"16/9" : 9/16,
  31.                     "4/3" : 3/4,
  32.                     "3/2" : 2/3,
  33.                     "21/9" : 9/21,
  34.                     "8/3" : 3/8,
  35.                     "9/5" : 9/5,
  36.                     "3/1" : 1/3,
  37.                     "25/12" : 12/25,
  38.                     "25/16" : 16/25}
  39.    
  40.  
  41.     def __init__(self, cam_id=DEFAULT_CAM_ID, number_of_imgs=10,
  42.         series_time_interval=1, image_path=".", video_path=".",
  43.         series_img_path=".", img_format=".tiff"):
  44.         self.cam = cv2.VideoCapture(cam_id)
  45.         if not self.cam.isOpened():
  46.             raise RuntimeError("can not open camera {0!r}".format(
  47.                 cam_id))
  48.         self.img_format = img_format
  49.         self.inter_frame = None
  50.         self.last_frame = None
  51.         self.take_series = False
  52.         self.recording = False
  53.         self.number_of_imgs = number_of_imgs
  54.         self.series_counter = None
  55.         self.series_time_counter = None
  56.         self.series_time_interval = series_time_interval
  57.         self.image_path = image_path
  58.         self.video_path = video_path
  59.         self.series_img_path = series_img_path
  60.         self.series_dir = None
  61.         self.interpolation_methods_keys = cycle(
  62.             self.INTERPOLATION_METHODS.keys())
  63.         self.interpolation_method = self.interpolation_methods_keys.next()
  64.         self.cam_width = self.zoom_width = self.width = \
  65.             int(self.cam.get(self.PROPID_WIDTH))
  66.         self.cam_height = self.zoom_height = self.height = \
  67.             int(self.cam.get(self.PROPID_HEIGHT))
  68.         aspect_ratio = self.cam_height / self.cam_width
  69.         if aspect_ratio not  in self.ASPECT_RATIO.values():
  70.             self.ASPECT_RATIO["CAM"] = aspect_ratio
  71.         self.aspect_ratio_keys = cycle(self.ASPECT_RATIO.keys())
  72.         for i in xrange(len(self.ASPECT_RATIO)):
  73.             self.aspect_ratio = self.aspect_ratio_keys.next()
  74.             if self.ASPECT_RATIO[self.aspect_ratio] == aspect_ratio:
  75.                 break
  76.        
  77.     def __enter__(self):
  78.         return self
  79.  
  80.     def __exit__(self, *args):
  81.         self.release()
  82.    
  83.     @property
  84.     def cam_size(self):
  85.         return self.cam_width, self.cam_height
  86.        
  87.     @property
  88.     def size(self):
  89.         return self.width, self.height
  90.        
  91.     @property
  92.     def zoom_size(self):
  93.         return self.zoom_width, self.zoom_height
  94.        
  95.     @property
  96.     def interpolation(self):
  97.         return self.interpolation_method
  98.  
  99.     def get_image(self):
  100.         state, frame = self.cam.read()
  101.        
  102.         if state and np.array_equal(self.last_frame, frame):
  103.             self.release()
  104.             state = False
  105.         if not state:
  106.             raise RuntimeError("could not read image")
  107.        
  108.         self.crop_frame = cv2.resize(frame, self.zoom_size,
  109.             interpolation = self.INTERPOLATION_METHODS[
  110.             self.interpolation_method])[int(self.zoom_height / 2
  111.             - self.zoom_width*self.ASPECT_RATIO[self.aspect_ratio] / 2)
  112.             : int(self.zoom_width * self.ASPECT_RATIO[self.aspect_ratio]
  113.             + self.zoom_height / 2 - int(self.zoom_width*self.ASPECT_RATIO[
  114.             self.aspect_ratio]) / 2), 0 : self.zoom_width]
  115.         self.height, self.width = self.crop_frame.shape[0], \
  116.             self.crop_frame.shape[1]
  117.            
  118.         if self.take_series:
  119.             self.series_time_counter += 1
  120.             if self.series_time_counter > self.series_time_interval:
  121.                 self.series_counter += 1
  122.                 self.series_time_counter = 0
  123.                 if self.series_counter <= self.number_of_imgs:
  124.                     img_name = "{0}{1}".format(self.series_counter,
  125.                         self.img_format)
  126.                     cv2.imwrite(os.path.join(self.series_img_path,
  127.                         self.series_dir, img_name), self.get_image)
  128.                 else:
  129.                     self.take_series = False
  130.         if self.recording:                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
  131.             self.video_writer.write(self.crop_frame)
  132.            
  133.         return self.crop_frame
  134.  
  135.     def recording_start_stop(self, name = None):
  136.         if self.recording:
  137.             self.recording = False
  138.         else:
  139.             self.recording = True
  140.             self.video_writer = cv2.VideoWriter(os.path.join(
  141.                 self.video_path, name if name else
  142.                 "{0:%d%b%Y_%H_%M_%S.%f}.avi".format(datetime.datetime.utcnow()
  143.                 )), cv2.cv.CV_FOURCC(* VIDEO_CODEC), 24, self.size)
  144.                
  145.     def take_series_picture(self):
  146.         if not self.take_series:        
  147.             self.series_dir = "{0:%d%b%Y_%H_%M_%S.%f}".format(
  148.                 datetime.datetime.utcnow())
  149.             os.makedirs(self.series_dir)
  150.             self.series_time_counter = 0
  151.             self.series_counter = 0
  152.             self.take_series = True
  153.  
  154.     def take_picture(self, name = None):
  155.         if not name:
  156.             name = "{0:%d%b%Y_%H_%M_%S.%f}{1}".format(
  157.                 datetime.datetime.utcnow(), self.img_format)
  158.         cv2.imwrite(os.path.join(self.image_path, name), self.crop_frame)
  159.        
  160.     def series_up_down(self, step):
  161.         if not self.take_series:
  162.             if self.number_of_imgs > -step:
  163.                 self.number_of_imgs += step
  164.        
  165.     def set_time_interval(self, step):
  166.         if not self.take_series:
  167.             if self.series_time_interval > -step:
  168.                 self.series_time_interval += step
  169.        
  170.     def zoom_image(self, step):
  171.         height = int(self.zoom_height + step)
  172.         width = int(height * self.cam_width / self.cam_height)
  173.         if width > 0 and height > 0:
  174.             self.zoom_width = width
  175.             self.zoom_height = height
  176.  
  177.     def reset_zoom(self):
  178.         self.zoom_width, self.zoom_height = self.cam_size
  179.        
  180.     def next_interpolation_method(self):
  181.         self.interpolation_method = self.interpolation_methods_keys.next()
  182.        
  183.     def next_aspect_ratio(self):
  184.         self.aspect_ratio = self.aspect_ratio_keys.next()
  185.        
  186.     def release(self):
  187.         self.cam.release()
  188.  
  189. class MicroscopeUI(tk.Frame):
  190.  
  191.     UPDATE_INTERVAL = 10
  192.     REC_ON = 5
  193.    
  194.     def __init__(self, parent, microscope, width, height, zoom_step=10):
  195.         tk.Frame.__init__(self, parent)
  196.         self.parent = parent
  197.         self.width = width
  198.         self.height = height
  199.         self.tk_image = None
  200.         self.rec_on = cycle(x for x in xrange(self.REC_ON))
  201.         self.text_on = False
  202.         self.microscope = microscope
  203.         self.text_colour_index = cycle(["white", "green", "black", "red",
  204.             "magenta", "green", "brown", "yellow", "blue", "orange", "gray"])
  205.         self.text_colour = self.text_colour_index.next()
  206.         self.canvas = tk.Canvas(self, width=width, height=height)
  207.         self.canvas.grid(column=0, row=0)
  208.         self.canvas.bind("<ButtonPress-1>", self.start_slide)
  209.         self.canvas.bind("<B1-Motion>", self.slide_image)
  210.         vscrollbar = tk.Scrollbar(self)
  211.         vscrollbar.grid(column=1, row=0, sticky=tk.N+tk.S)
  212.         self.canvas.config(yscrollcommand=vscrollbar.set)
  213.         vscrollbar.config(command=self.canvas.yview)
  214.         hscrollbar = tk.Scrollbar(self, orient=tk.HORIZONTAL)
  215.         hscrollbar.grid(column=0, row=1, columnspan=5, sticky=tk.E+tk.W)
  216.         self.canvas.config(xscrollcommand=hscrollbar.set)
  217.         hscrollbar.config(command=self.canvas.xview)
  218.         button_frame = tk.Frame(self)
  219.         button_frame.grid(column=0, row=3, columnspan=2)
  220.         self.buttons = list()
  221.         for column, (text, width, command, var)in enumerate(
  222.             (("||", 2, self.capture_start_stop, ()),
  223.              ("Z+", 2, self.microscope.zoom_image, (zoom_step,)),
  224.              ("Z-", 2, self.microscope.zoom_image, (-zoom_step,)),
  225.              ("Z+/-", 2, self.microscope.reset_zoom, ()),
  226.              ("[1]", 2, self.microscope.take_picture, ()),
  227.              ("REC", 2, self.recording_start_stop, ()),
  228.              ("INTPOL", 5, self.next_interpolation_method, ()),
  229.              ("[S]]]", 2, self.microscope.take_series_picture, ()),
  230.              ("S+", 2, self.series_up_down, (1,)),
  231.              ("S-", 2, self.series_up_down, (-1,)),
  232.              ("T+", 2, self.time_interval_up_down, (
  233.               self.microscope.series_time_interval,)),
  234.              ("T-", 2, self.time_interval_up_down, (
  235.               -self.microscope.series_time_interval,)),
  236.              ("ON", 2, self.set_text_on_off, ()),
  237.              ("C", 2, self.change_text_colour, ()),
  238.              ("AR", 2, self.microscope.next_aspect_ratio, ()))):
  239.             button = tk.Button(button_frame, text=text, width=width,
  240.                 relief="raised", font="Arial 10 bold",
  241.                 command=partial(command, *var))
  242.             button.grid(column=column, row=0)
  243.             self.buttons.append(button)
  244.  
  245.     def slide_image(self, event):
  246.         self.canvas.scan_dragto(event.x, event.y, gain=-1)
  247.        
  248.     def start_slide(self, event):
  249.         self.canvas.scan_mark(event.x, event.y)
  250.        
  251.     def capture_start_stop(self):
  252.         if self.after_id is None:
  253.             self.buttons[0].config(text = "||")
  254.             self.run()
  255.         else:
  256.             self.buttons[0].config(text = ">")
  257.             self.after_cancel(self.after_id)
  258.             self.after_id = None
  259.  
  260.     def run(self):
  261.         try:
  262.             image = self.microscope.get_image()
  263.             width, height = self.microscope.size
  264.             tk_image = Image.frombytes("RGB",  (width, height),
  265.                 image, "raw", "BGR")
  266.         except RuntimeError:
  267.             self.raise_cam_id_error()
  268.             return
  269.            
  270.         self.canvas.delete("img", "rec", "txt")
  271.         self.tk_image = ImageTk.PhotoImage(tk_image)
  272.         self.canvas.create_image((0,0), anchor=tk.NW,
  273.             image=self.tk_image, tag="img")
  274.         if self.text_on:        
  275.             rec_text = " "
  276.             if self.microscope.recording and not self.rec_on.next():
  277.                 rec_text = "*"
  278.             self.canvas.create_text(width / 2, height / 2,
  279.                 text="+", font="Courier 30", fill=self.text_colour,
  280.                 tag="txt")
  281.             self.canvas.create_text(width / 2,10 + height / 2
  282.                 - height / 2,
  283.                 font="Courier 13 bold",
  284.                 text = "REC:{0}  FILTER:{1}  SERIES:{2}  TIME:{3}  RES:{4}:{5} > {6}"
  285.                 .format(rec_text,
  286.                     self.microscope.interpolation,
  287.                     self.microscope.number_of_imgs,                            
  288.                     self.microscope.series_time_interval,
  289.                     width, height,
  290.                     self.microscope.aspect_ratio),
  291.                 anchor="center",
  292.                 fill = self.text_colour,
  293.                 tag = "txt")
  294.  
  295.         state = tk.DISABLED if self.microscope.take_series else tk.NORMAL
  296.         for button in (1, 2, 3, 7, 8, 9, 10, 11, 14):
  297.             self.buttons[button].config(state=state)
  298.                
  299.         width, height = self.microscope.zoom_size
  300.         self.canvas.config(scrollregion = (0, 0, width, height))
  301.         self.after_id = self.after(self.UPDATE_INTERVAL, self.run)
  302.            
  303.     def change_text_colour(self):      
  304.         self.set_text_on_off(True)
  305.         self.text_colour = self.text_colour_index.next()
  306.        
  307.     def set_text_on_off(self, force_on=False):
  308.         self.text_on = force_on or not self.text_on
  309.         self.buttons[12].config(text="OFF" if self.text_on else "ON")
  310.        
  311.     def raise_cam_id_error(self):
  312.         self.canvas.delete("img", "rec", "txt")
  313.         self.canvas.create_text((self.width / 2, self.height / 2),
  314.             text='NO CAM', font='Arial 40')
  315.         for button in self.buttons:
  316.             button.config(state="disabled")
  317.            
  318.     def recording_start_stop(self):
  319.         self.set_text_on_off(True)
  320.         self.microscope.recording_start_stop()
  321.        
  322.     def series_up_down(self, step):
  323.         self.set_text_on_off(True)
  324.         self.microscope.series_up_down(step)
  325.        
  326.     def time_interval_up_down(self, step):
  327.         self.set_text_on_off(True)
  328.         self.microscope.set_time_interval(step)
  329.        
  330.     def next_interpolation_method(self):
  331.         self.set_text_on_off(True)
  332.         self.microscope.next_interpolation_method()
  333.  
  334.     def release(self):
  335.         self.parent.destroy()
  336.  
  337. def main():
  338.     root = tk.Tk()
  339.     root.title('MICROSCOPE')
  340.    
  341.     try:
  342.         with Microscope(series_time_interval=1) as microscope:
  343.             def take_picture(e):
  344.                 microscope_ui.take_picture()
  345.             microscope_ui = MicroscopeUI(
  346.                 root, microscope, WIDTH, HEIGHT)
  347.             microscope_ui.pack(expand=tk.YES)
  348.             microscope_ui.run()
  349.             root.protocol("WM_DELETE_WINDOW", microscope_ui.release)
  350.             #root.bind("<Key" + chr(10) + ">", take_picture)
  351.             root.mainloop()
  352.            
  353.     except RuntimeError:
  354.         tk.Label(root, text = 'can not open camera {0!r}'.format(
  355.                 DEFAULT_CAM_ID), font = "Arial 20", height = 10).pack()
  356.         root.mainloop()
  357.    
  358. if __name__ == '__main__':
  359.     main()


Gruß Frank

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder