Wednesday 2 November 2016

Tkinter and Picamera in Python on RPi.

                                        (this is not my jewellery CNC blog, that's here : http://digital-jeweller.blogspot.com/)



              RPi Tkinter and Picamera

Having exhausted my attempts at getting results from my UP board which has no real working API and not much developer representation on its forum, other than to post the new products for sale, I have moved my efforts back to the RPi. 

Running IoT it has a reasonably fast result once setting the board to turbo, but its still pulling video over USB, which still sucks it dry and it has no drivers to utilise the RPi PiCamera which is lightning fast running on the GPU. 

SO: Something I have been trying to avoid.. Linux.. domain of pimpled skinny guys in server rooms with leaking pens in their pockets , and halitosis.... 

The API for Picamera is stunningly easy to use, best api I have seen to date, its biggest drawback however is the way it previews the camera, which cannot be locked to a window unless you do some opencv trickery which really drains the cpu.. you can trick the Tkinter window into a locked state (it cannot be moved or sized) with a single command though, and then overlay the preview, which gives a similar effect. Not yet decided how that plays out for me... 

My first crack at this was to familiarize myself with Tkinter and the Picamera copmands, so the obvious choice was to develop an interface to play with all the commands:

Create a Window
Create Sliders
Create DropDown boxes
and get them all talking to Picamera. 

Surprisingly small amount of code to be honest..

#!/usr/bin/python
import Tkinter as tk
import RPi.GPIO as GPIO
import picamera
from time import sleep

camera = picamera.PiCamera()
choices = ['off', 'auto', 'sunlight','cloudy','shade','tungsten','fluorescent','incandescent','flash','horizon']
effects = ['none','negative','solarize','sketch','denoise','emboss','oilpaint','hatch','gpen','pastel','watercolor','film','blur','saturation','colorswap','washedout','posterise','colorpoint','colorbalance','cartoon','deinterlace1','deinterlace2']

def CameraON():
    camera.preview_fullscreen=False
    camera.preview_window=(90,100, 320, 240)
    camera.resolution=(640,480)
    camera.start_preview()
    
def CameraOFF():
    camera.stop_preview()
    
def EXIT():
    root.destroy
    camera.stop_preview()
    camera.close()
    quit()

def UpdateBrightness(value):
    camera.brightness = int(value)
    
def UpdateContrast(value):
    camera.contrast = int(value)
    
def UpdateSharpness(value):
    camera.sharpness = int(value)
    
def UpdateSaturation(value):
    camera.saturation = int(value)

def SetAWB(var):
    camera.awb_mode = var

def SetEFFECTS(var):
    camera.image_effect = var

def Zoom(var):
    x = float("0."+var)
    camera.zoom = (0.5,0.5,x,x)
    
root = tk.Tk()
root.resizable(width=False, height=False)
root.geometry("320x300+89+50")
root.title("Camera Button Test")

root.buttonframe = tk.Frame(root)
root.buttonframe.grid(row=5, column=3, columnspan=2)

tk.Button(root.buttonframe, text='Start Camera', command=CameraON).grid(row=1, column = 1)
tk.Button(root.buttonframe, text='Kill Camera', command=CameraOFF).grid(row=1, column = 2)
tk.Button(root.buttonframe, text='Exit Program', command=EXIT).grid(row=1, column = 3)

tk.Scale(root.buttonframe, from_=30, to=100, orient=tk.HORIZONTAL, label = "Brightness", command=UpdateBrightness).grid(row=2,column=1)
tk.Scale(root.buttonframe, from_=-100, to=100, orient=tk.HORIZONTAL, label = "Contrast", command=UpdateContrast).grid(row=2,column=2)
tk.Scale(root.buttonframe, from_=-100, to=100, orient=tk.HORIZONTAL, label = "Sharpness", command=UpdateSharpness).grid(row=2,column=3)
tk.Scale(root.buttonframe, from_=-100, to=100, orient=tk.HORIZONTAL, label = "Saturation", command=UpdateSaturation).grid(row=3,column=1)
tk.Scale(root.buttonframe, from_=10, to=99, orient=tk.HORIZONTAL, label = "Zoom", command=Zoom).grid(row=4,column=1)

AWB_Var = tk.StringVar(root)
AWB_Var.set(choices[0]) 
AWB_Option = tk.OptionMenu(root.buttonframe, AWB_Var, *choices, command=SetAWB).grid(row=3,column=2)

EFFECT_Var = tk.StringVar(root)
EFFECT_Var.set(effects[0]) 
EFFECT_Option = tk.OptionMenu(root.buttonframe, EFFECT_Var, *effects, command=SetEFFECTS).grid(row=3,column=3)

#enable next line to lock window in place                     
#root.overrideredirect(True)

root.mainloop()

and the output while not exactly professional looking was quite a good result for a new language (for me anyhow)

time to start adding the GPIO to run the camera table now.




3 comments: