Page MenuHomec4science

AscCam.py
No OneTemporary

File Metadata

Created
Sun, Apr 28, 14:23

AscCam.py

#!/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 = 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=10)
self.camInterval = tk.Scale(master=frame1, label="interval (min)",
variable=self.intervalVar, from_=1,
to=1000, resolution=1, orient="horizontal")
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()
# X and Y position of the zoomed area
self.xVar = tk.IntVar(value=50)
self.camX = tk.Scale(master=frame2, label="X position",
variable=self.xVar, from_=0,
to=100, resolution=10, orient="horizontal",
command=self.setZoom)
self.camX.set(50)
self.camX.pack()
self.yVar = tk.IntVar(value=50)
self.camY = tk.Scale(master=frame2, label="Y position",
variable=self.yVar, from_=0,
to=100, resolution=10, orient="horizontal",
command=self.setZoom)
self.camY.set(50)
self.camY.pack()
# Image rotation
self.rotVar = tk.IntVar(value=270)
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(270)
self.camRot.pack()
# Implemented but removed from the GUI
# for space issues
#
# 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)
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, 480, 360))
self.camera.start_preview(fullscreen=False, window=(0, 0, 360, 480))
self.camera.preview.rotation = int(self.camRot.get())
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, value):
zoom = self.camZoom.get()
xfrac = float(self.camX.get())/100
yfrac = 1-float(self.camY.get())/100
zoomSide = 1 / float(zoom)
edgeX = (1 - zoomSide)*xfrac
edgeY = (1 - zoomSide)*yfrac
self.camera.zoom = (edgeX, edgeY, zoomSide, zoomSide)
return
def setRot(self, rot):
if self.camera.preview is not None:
self.camera.preview.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+450")
app = GUI(master=root)
app.mainloop()

Event Timeline