diff --git a/AscCam.py b/AscCam.py index 3e41b76..b231804 100755 --- a/AscCam.py +++ b/AscCam.py @@ -1,401 +1,403 @@ #!/usr/bin/python3 # Few required libraries import tkinter as tk import os import time import numpy as np import matplotlib from picamera import PiCamera from fractions import Fraction matplotlib.use('TkAgg') from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Main Tkinter class class GUI(tk.Frame): # Initialization of the class def __init__(self, master=None): super().__init__(master) self.master = master # Instantiate the camera self.camera = PiCamera(sensor_mode=3, resolution=PiCamera.MAX_RESOLUTION, framerate=10) self.data = np.empty((round(self.camera.resolution[1]/32)*32, round(self.camera.resolution[0]/32)*32, 3), dtype=np.uint8) # Camera warm-up time time.sleep(3) # Create the GUI self.create_widgets() # filepath for output: self.basePath = '/home/pi/Desktop/Imaging/{}'.format(time.strftime('%Y-%m-%d')) if not os.path.exists(self.basePath): os.mkdir(self.basePath) os.chown(self.basePath, 1000, 1000) # Parameter for the timelapse self.isTLOn = False - self.tlInterval = 60000 + self.tlInterval = 600000 self.dt = 0 self.prevTime = None self.timelapsePath = self.basePath self.job = None # Parameter for the WB self.isHistOn = False self.jobHist = None # Create the main GUI def create_widgets(self): # Create separate frames to group similar buttons frame1 = tk.Frame(master=self.master, bd=2, relief="ridge") frame1.grid(row=0, column=0, columnspan=1, rowspan=1, sticky="N") frame2 = tk.Frame(master=self.master, bd=2) frame2.grid(row=0, column=1, columnspan=1, rowspan=1, sticky="NW") frame3 = tk.Frame(master=self.master, bd=2, relief="ridge") frame3.grid(row=0, column=2, columnspan=1, rowspan=1, sticky="NW") # In Frame1 the general handling buttons # Place the first item (a label) in the first frame self.camLabel = tk.Label(master=frame1, text="CAMERA") self.camLabel.pack() # Then the preview buttons self.camOnButt = tk.Button(master=frame1, text="ON", fg="green", command=self.camOn) self.camOnButt.pack() self.camOffButt = tk.Button(master=frame1, text="OFF", fg="red", command=self.camOff) self.camOffButt.pack() # the acquisition section self.camResLabel = tk.Label(master=frame1, text=" Acquisition ") self.camResLabel.pack() self.camSnapButt = tk.Button(master=frame1, text="Snapshot", command=self.camSnap) self.camSnapButt.pack() self.camRecButt = tk.Button(master=frame1, text="Video", command=self.camRec) self.camRecButt.pack() # Time lapse with interval self.camTLButt = tk.Button(master=frame1, text="Time Lapse", command=self.camTL) self.camTLButt.pack() - self.intervalVar = tk.IntVar(value=1) + self.intervalVar = tk.IntVar(value=10) self.camInterval = tk.Scale(master=frame1, label="interval (min)", variable=self.intervalVar, from_=1, to=1000, resolution=1, orient="horizontal") - self.camInterval.set(1) + self.camInterval.set(10) self.camInterval.pack() # The Exit section self.camResLabel = tk.Label(master=frame1, text=" Exit ") self.camResLabel.pack(fill="x") self.quit= tk.Button(master=frame1, text="QUIT", fg="blue", command=self.master.destroy) self.quit.pack() # In Frame 2, the camera's options # Digital zoom self.zoomVar = tk.IntVar(value=1) self.camZoom = tk.Scale(master=frame2, label="Digi Zoom", variable=self.zoomVar, from_=1, to=10, resolution=1, orient="horizontal", command=self.setZoom) self.camZoom.set(1) self.camZoom.pack() # Image rotation - self.rotVar = tk.IntVar(value=90) + self.rotVar = tk.IntVar(value=180) self.camRot = tk.Scale(master=frame2, label="Rotation", variable=self.rotVar, from_=0, to=270, resolution=90, orient="horizontal", command=self.setRot) - self.camRot.set(90) + self.camRot.set(180) self.camRot.pack() + self.camera.rotation = 180 + # Brightness self.brightVar = tk.IntVar(value=50) self.camBright = tk.Scale(master=frame2, label="Brightness", variable=self.brightVar, from_=0, to=100, resolution=5, orient="horizontal", command=self.setBright) self.camBright.set(50) self.camBright.pack() # Contrast self.contrVar = tk.IntVar(value=0) self.camContrast = tk.Scale(master=frame2, label="Contrast", variable=self.contrVar, from_=-100, to=100, resolution=10, orient="horizontal", command=self.setContrast) self.camContrast.set(0) self.camContrast.pack() # Exposure mode and duration self.expLabel = tk.Label(master=frame2, text=" Exposure modes ") self.expLabel.pack(fill="x") exp_options = list(PiCamera.EXPOSURE_MODES.keys()) self.expVar = tk.StringVar() self.expVar.set("off") self.expMenu = tk.OptionMenu(frame2, self.expVar, *exp_options, command=self.setExpMode) self.expMenu.pack(fill="x") self.expVar = tk.IntVar(value=70) self.camExp = tk.Scale(master=frame2, label="exposure (ms)", variable=self.expVar, from_=1, to=200, resolution=1, orient="horizontal", command=self.setExp) self.camExp.set(70) self.camExp.pack() self.camera.exposure_mode = "off" self.camera.shutter_speed = 70000 # In frame 3 the white-balance # First the modes self.wbLabel = tk.Label(master=frame3, text=" White-balance modes ") self.wbLabel.pack(fill="x") wb_options = list(PiCamera.AWB_MODES.keys()) self.wbVar = tk.StringVar() self.wbVar.set("off") self.wbMenu = tk.OptionMenu(frame3, self.wbVar, *wb_options, command=self.setAWBMode) self.wbMenu.pack(fill="x") # Setup the camer AWB awb_red = float(self.camera.awb_gains[0]) awb_green = float(self.camera.awb_gains[1]) # And then the gains self.redVar = tk.DoubleVar(value=awb_red) self.wbRed = tk.Scale(master=frame3, label="red gain", variable=self.redVar, from_=0.0, to=8.0, resolution=0.1, orient="horizontal", command=self.setGain) self.wbRed.set(awb_red) self.wbRed.pack() self.greenVar = tk.DoubleVar(value=awb_green) self.wbGreen = tk.Scale(master=frame3, label="green gain", variable=self.greenVar, from_=0.0, to=8.0, resolution=0.1, orient="horizontal", command=self.setGain) self.wbGreen.set(awb_green) self.wbGreen.pack() # Then the preview buttons - self.camHistButt = tk.Button(master=frame3, text="Histogram", command=self.camHist, state=tk.DISABLED) + self.camHistButt = tk.Button(master=frame3, text="Histogram", command=self.camHist) self.camHistButt.pack() self.fig = Figure(figsize=(1.5,1.5), dpi=100, frameon=False) #self.axes = self.fig.add_subplot(111) self.axes = self.fig.add_axes([0, 0, 1, 1]) self.axes.axis('off') self.canevas = FigureCanvasTkAgg(self.fig, master=frame3) self.canevas.get_tk_widget().pack() self.canevas.show() def camOn(self): self.camera.start_preview(fullscreen=False, window=(0, 0, 640, 480)) return def camOff(self): self.camera.stop_preview() return def camSnap(self): photoPath = self.basePath + '/snaps/' #check to see if the snap output folder is present: if not os.path.exists(photoPath): #if not, create it: os.makedirs(photoPath) os.chown(photoPath, 1000, 1000) # Camera warm-up time time.sleep(1) self.camera.capture(photoPath + 'snap_' + time.strftime("%Y-%m-%d-%H-%M-%S") + '.png') return def camTL(self): if self.isTLOn: if self.job is not None: root.after_cancel(self.job) self.job = None self.prevTime = None self.dt = 0 self.camTLButt.configure(text="Time Lapse") self.camInterval.configure(state=tk.NORMAL) self.camRecButt.configure(state=tk.NORMAL) else: self.timelapsePath = (self.basePath + '/timelapse_' + time.strftime("%Y-%m-%d-%H-%M-%S")) #check to see if the snap output folder is present: if not os.path.exists(self.timelapsePath): #if not, create it: os.makedirs(self.timelapsePath) os.chown(self.timelapsePath, 1000, 1000) self.camRecButt.configure(state=tk.DISABLED) self.camInterval.configure(state=tk.DISABLED) self.tlInterval = int(self.camInterval.get())*60000; self.dt = 0 self.camTLButt.configure(text="STOP TL") self.isTLOn = not self.isTLOn if self.isTLOn: self.acquireTL() return def acquireTL(self): if self.isTLOn: self.camera.capture(self.timelapsePath + '/timelapse_' + time.strftime("%d-%H-%M-%S") + '.png') now = time.time() if self.prevTime is not None: self.dt = self.dt + self.tlInterval - round((now - self.prevTime)*1000) self.prevTime = now self.job = root.after(self.tlInterval + self.dt, self.acquireTL) return def camRec(self): return def camHist(self): if self.isHistOn: if self.jobHist is not None: root.after_cancel(self.jobHist) self.jobHist = None self.camHistButt.configure(text="Histogram") self.camOnButt.configure(state=tk.NORMAL) self.camSnapButt.configure(state=tk.NORMAL) self.camRecButt.configure(state=tk.NORMAL) self.camTLButt.configure(state=tk.NORMAL) self.isHistOn = False elif not self.isTLOn and not self.camera.previewing: self.camOnButt.configure(state=tk.DISABLED) self.camSnapButt.configure(state=tk.DISABLED) self.camRecButt.configure(state=tk.DISABLED) self.camTLButt.configure(state=tk.DISABLED) self.camHistButt.configure(text="STOP") self.isHistOn = True self.camDrawHist() return def camDrawHist(self): if self.isHistOn: self.camera.capture(self.data, 'rgb') color = ('r', 'g', 'b') self.axes.clear() for channel in range(3): hist,bins = np.histogram(self.data[:,:,channel], 256, [0, 256]) self.axes.plot(hist, color=color[channel]) self.canevas.draw() self.jobHist = root.after(200, self.camDrawHist) return def setZoom(self, zoom): zoomSide = 1 / float(zoom) edge = (1 - zoomSide)*0.5 self.camera.zoom = (edge, edge, zoomSide, zoomSide) return def setRot(self, rot): self.camera.rotation = int(rot) return def setAWBMode(self, awb): if self.camera.awb_mode == "off" and awb != "off": self.wbRed.configure(state=tk.DISABLED) self.wbGreen.configure(state=tk.DISABLED) self.camHistButt.configure(state=tk.DISABLED) if self.isHistOn: root.after_cancel(self.jobHist) self.jobHist = None self.isHistOn = False self.camera.awb_mode = awb if awb == "off": self.wbRed.configure(state=tk.NORMAL) self.wbGreen.configure(state=tk.NORMAL) self.camHistButt.configure(state=tk.NORMAL) self.setGain(0) return def setGain(self, gain): red = self.wbRed.get() green = self.wbGreen.get() self.camera.awb_gains = (Fraction(red), Fraction(green)) return def setBright(self, bright): self.camera.brightness = int(bright) return def setContrast(self, contr): self.camera.contrast = int(contr) return def setExpMode(self, exp): if self.camera.exposure_mode == "off" and exp != "off": self.setExp(0) self.camExp.configure(state=tk.DISABLED) self.camera.exposure_mode = exp if exp == "off": self.camExp.configure(state=tk.NORMAL) self.setExp(self.camExp.get()) return def setExp(self, exp): exp = int(exp)*1000 self.camera.shutter_speed = exp return root = tk.Tk() root.title("AscCam 0.01") root.resizable(width=False, height=False) -root.geometry("+15+400") +root.geometry("+15+450") app = GUI(master=root) app.mainloop()