Showing posts with label picamera. Show all posts
Showing posts with label picamera. Show all posts

Monday, March 22, 2021

min. version of RPi/Python Code to control Camera Module with preview on local HDMI

It's a minimum version of my another exercise "RPi/Python Code to control Camera Module with preview on local HDMI"; with minimum functions preview and capture only, using PyQt5 GUI, fixed resolution 240x240, and display the captured image on GUI. You can also choice save file name; image.jpg or img_<timestamp>.jpg, under Desktop folder. It's used to prepare images for my coming exercise "Raspberry Pi/Python send image to ESP32/MicroPython via WiFi TCP socket".

In my usage scenario: The Raspberry Pi 4B/8G is installed with HQ Camera Module (mount with manual focus lens) and a 4 inch HDMI IPS Touch Display. Remote control with Android with xrdp/Microsoft Remote Desktop. Such that I can control camera on remote Android device, adjust focus/aperture on the lens, and check the effect on local HDMI preview at real-time.


Python3 code, qCam240_20210323.py
import sys
import picamera
from pkg_resources import require
import time
import picamera

from PyQt5.QtWidgets import (QApplication, QWidget,
                             QPushButton, QLabel, QRadioButton,
                             QMessageBox, QHBoxLayout, QVBoxLayout)
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.Qt import qRed, qGreen, qBlue
from signal import signal, SIGINT

print(sys.version)
print(require('picamera'))

rpi_icon = 'rpi_icon_240.png'

class AppWindow(QWidget):
    
    camPreviewState = False  #not in Preview
    
    def __init__(self):
        super().__init__()

        self.camera = picamera.PiCamera()
        self.camera.resolution = (240, 240)
        
        lbSysInfo = QLabel('Python:\n' + sys.version)
        lbPicameraInfo = QLabel(str(require('picamera')))
        vboxInfo = QVBoxLayout()
        vboxInfo.addWidget(lbSysInfo)
        vboxInfo.addWidget(lbPicameraInfo)
        
        #setup UI
        btnPreview = QPushButton("Start Preview", self)
        btnPreview.clicked.connect(self.evBtnPreviewClicked)
        btnCapture = QPushButton("Capture", self)
        btnCapture.clicked.connect(self.evBtnCaptureClicked)
        
        lbFileName = QLabel('save as (Desktop/):')
        self.rbtnImage = QRadioButton('image.jpg')
        self.rbtnImage.setChecked(True)
        self.rbtnStamp = QRadioButton('img_<timestamp>.jpg')
        
        vboxCamControl = QVBoxLayout()
        vboxCamControl.addWidget(btnPreview)
        vboxCamControl.addWidget(btnCapture)
        vboxCamControl.addWidget(lbFileName)
        vboxCamControl.addWidget(self.rbtnImage)
        vboxCamControl.addWidget(self.rbtnStamp)
        vboxCamControl.addStretch()
        
        self.lbImg = QLabel(self)
        self.lbImg.resize(240, 240)
        self.lbImg.setStyleSheet("border: 1px solid black;")
        
        try:
            with open(rpi_icon):
                pixmap = QPixmap(rpi_icon)
                self.lbImg.setPixmap(pixmap)
        except FileNotFoundError:
            print('File Not Found Error')
        
        hboxCam = QHBoxLayout()
        hboxCam.addWidget(self.lbImg)
        hboxCam.addLayout(vboxCamControl)

        self.lbPath = QLabel(self)

        vboxMain = QVBoxLayout()
        vboxMain.addLayout(vboxInfo)
        vboxMain.addLayout(hboxCam)
        vboxMain.addWidget(self.lbPath)
        vboxMain.addStretch()
        self.setLayout(vboxMain)
        
        self.setGeometry(100, 100, 500,400)
        self.show()

    def evBtnPreviewClicked(self):
        if self.camPreviewState:
            print('Stop Preview')
            self.camera.stop_preview()
            self.sender().setText('Start Preview')
            self.camPreviewState = False
        else:
            print('Start Preview')
            self.camera.start_preview()
            self.sender().setText('Stop Preview')
            self.camPreviewState = True
        
    def evBtnCaptureClicked(self):
        print('evBtnCaptureClicked()')
        print("Capture")
        
        if self.rbtnImage.isChecked():
            targetPath="/home/pi/Desktop/image.jpg" 
        else:
            timeStamp = time.strftime("%Y%m%d-%H%M%S")
            targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
        
        print(targetPath)
        
        self.camera.capture(targetPath)
        self.lbPath.setText(targetPath)
        
        try:
            with open(targetPath):
                pixmap = QPixmap(targetPath)
                self.lbImg.setPixmap(pixmap)
                
                #as a exercise, get some info from pixmap
                print('\npixmap:')
                print(pixmap)
                print(type(pixmap))
                print(str(pixmap.width()) + " : " + str(pixmap.height()))
                print()
                
                print('convert to Image')
                qim = pixmap.toImage()
                print(qim)
                print(type(qim))
                print()
                
                print('read a pixel from image')
                qrgb = qim.pixel(0, 0)
                print(hex(qrgb))
                print(type(qrgb))
                
                r, g, b = qRed(qrgb), qGreen(qrgb), qBlue(qrgb) 
                print([hex(r), hex(g), hex(b)])
                print()

        except FileNotFoundError:
            print('File Not Found Error')
        
    def closeEvent(self, event):
        confirmClose = QMessageBox.question(self,
                                            "Quit App?",
                                            "Confirm to Quit?",
                                            QMessageBox.No | QMessageBox.Yes,
                                            QMessageBox.Yes)
        if confirmClose == QMessageBox.Yes:
            print('Confirmed Close')
            self.camera.close()
            event.accept()
        else:
            event.ignore()
        
if __name__ == '__main__':
    print('run __main__')
    app = QApplication(sys.argv)
    window = AppWindow()
    sys.exit(app.exec_())

print("- bye -")

Download the thumbnail image, save as "rpi_icon_240.png" in the same folder. Used as a default image only.



Tuesday, March 9, 2021

RPi/Python Code to control Camera Module with preview on local HDMI

It's a Python3 code run on Raspberry Pi to control Camera Module with various setting. The preview display on local HDMI. 


In my usage scenario: The Raspberry Pi 4B/8G is installed with HQ Camera Module (mount with manual focus lens) and a 4 inch HDMI IPS Touch Display. Remote control with Android with xrdp/Microsoft Remote Desktop. Such that I can control and change setting on remote Android device, adjust focus/aperture on the lens, and check the effect on local HDMI preview at real-time.

It's a long time ago, I make a similar code with preview stream video, both control and preview on remote desktop, Python to capture image from Pi Camera Module, with image effects. But I'm not satisfied by the delay of stream video, that's why I re-develop this code again.


The lens shown on the video is a Nikkor ais 28mm f2.8 manual focus lens, connected to HQ Camera Module via a Nikon F to C mount adapter.

rpiCam_20210309a.py
import sys
import picamera
from pkg_resources import require
import time

"""
ref: Picamera
https://picamera.readthedocs.io/en/release-1.13/
"""

#from tkinter import *
#tkinter for Python 3
import tkinter as tk
from tkinter import ttk

def close_window():
    #close tasks
    camera.close()
    print("Camera closed")
    
    print("close_window()")
    print("Window closed")
    root.destroy()

#event callback functions
def evStartPreviewBtnPressed():
    print("Start Preview")
    camera.start_preview()

def evStopPreviewBtnPressed():
    print("Stop Preview")
    camera.stop_preview()

def evCaptureBtnPressed():
    print("Capture")
    timeStamp = time.strftime("%Y%m%d-%H%M%S")
    targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
    print(targetPath)
    camera.capture(targetPath)
    
def cmdScaleSharpness(new_value):
    camera.sharpness = scaleSharpness.get()
    print("sharpness: " + str(camera.sharpness))
    
def cmdScaleContrast(new_value):
    camera.contrast = scaleContrast.get()
    print("contrast: " + str(camera.contrast))
    
def cmdScaleBrightness(new_value):
    camera.brightness = scaleBrightness.get()
    print("brightness: " + str(camera.brightness))
    
def cmdScaleSaturation(new_value):
    camera.saturation = scaleSaturation.get()
    print("saturation: " + str(camera.saturation))
    
def cmdScaleExpCompensation(NEW_VALUE):
    camera.exposure_compensation = scaleExpCompensation.get()
    print("exposure_compensation: " + str(camera.exposure_compensation))
    
def cmdRB_Iso():
    camera.iso = varIso.get()
    print("iso: " + str(camera.iso))

print(sys.version)
print(require('picamera'))
strInfo = str(sys.version) + str(require('picamera'))
type(sys.version)
type(require('picamera'))

#Prepare camera
camera = picamera.PiCamera()
#set default
camera.sharpness = +5
camera.contrast = 0
camera.brightness = 50
camera.saturation = 0
camera.iso = 100
camera.video_stabilization = False
camera.exposure_compensation = 0
camera.exposure_mode = 'auto'
camera.meter_mode = 'average'
camera.awb_mode = 'auto'
camera.image_effect = 'none'
camera.color_effects = None
camera.rotation = 0
camera.hflip = False
camera.vflip = False
camera.crop = (0.0, 0.0, 1.0, 1.0)
  
# not work for HQ
#camera.resolution = (4056, 3040)  # HQ
#camera.resolution = (2592, 1944)  # V1
camera.resolution = (3280, 2464)  # V2
#end of set default

SCALE_WIDTH = 940;

#Prepare GUI
root = tk.Tk()
#root.geometry("650x550")
root.geometry("960x800")
root.wm_title("doCamII")
root.protocol("WM_DELETE_WINDOW", close_window)

labelInfo = tk.Label(root,
                  text=strInfo, fg="gray",
                  font=("Helvetica", 14))
labelInfo.pack()

#Main control
frameMain = tk.Frame(root, bg="lightgray")

btnStartPreview = tk.Button(frameMain, text="Start Preview",
                    command=evStartPreviewBtnPressed)
btnStopPreview = tk.Button(frameMain, text="Stop Preview",
                    command=evStopPreviewBtnPressed)
btnStartPreview.grid(row=2, column=0, sticky=tk.W+tk.E)
btnStopPreview.grid(row=2, column=1, sticky=tk.W+tk.E)

btnCapture = tk.Button(frameMain, text="Capture",
                    command=evCaptureBtnPressed)
btnCapture.grid(row=3, columnspan=2, sticky=tk.W+tk.E)
frameMain.pack(padx=10,pady=10)

#Setting
notebook = ttk.Notebook(root)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
frame3 = ttk.Frame(notebook)
notebook.add(frame1, text='Setting 1')
notebook.add(frame2, text='Setting 2')
notebook.add(frame3, text='Setting 3')
notebook.pack()

lfSharpness = ttk.LabelFrame(frame1, text="sharpness")
lfSharpness.pack(fill="x", expand="no", anchor=tk.N)
scaleSharpness = tk.Scale(
    lfSharpness,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    command=cmdScaleSharpness)
scaleSharpness.set(camera.sharpness)
scaleSharpness.pack()

lfContrast = ttk.LabelFrame(frame1, text="contrast")
lfContrast.pack(fill="x", expand="no", anchor=tk.N)
scaleContrast = tk.Scale(
    lfContrast,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    command=cmdScaleContrast)
scaleContrast.set(camera.contrast)
scaleContrast.pack()

lfBrightness = ttk.LabelFrame(frame1, text="brightness")
lfBrightness.pack(fill="x", expand="no", anchor=tk.N)
scaleBrightness = tk.Scale(
    lfBrightness,
    from_=0, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    command=cmdScaleBrightness)
scaleBrightness.set(camera.brightness)
scaleBrightness.pack()

lfSaturation = ttk.LabelFrame(frame1, text="saturation")
lfSaturation.pack(fill="x", expand="no", anchor=tk.N)
scaleSaturation = tk.Scale(
    lfSaturation,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    command=cmdScaleSaturation)
scaleSaturation.set(camera.saturation)
scaleSaturation.pack()

lfExpCompensation = ttk.LabelFrame(frame1, text="exposure_compensation")
lfExpCompensation.pack(fill="x", expand="no", anchor=tk.N)
scaleExpCompensation = tk.Scale(
    lfExpCompensation,
    from_=-25, to=25,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    command=cmdScaleExpCompensation)
scaleExpCompensation.set(camera.exposure_compensation)
scaleExpCompensation.pack()

#==========================================================
varIso = tk.IntVar()
varIso.set(camera.iso)
lfIso = ttk.LabelFrame(frame2, text="iso")
lfIso.pack(fill="x", expand="no", anchor=tk.N)
tk.Radiobutton(lfIso, variable=varIso,
        text='0 (auto)',value=0,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfIso, variable=varIso,
        text='100',value=100,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfIso, variable=varIso,
        text='200',value=200,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfIso, variable=varIso,
        text='400',value=400,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfIso, variable=varIso,
        text='800',value=800,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfIso, variable=varIso,
        text='1600',value=1600,command=cmdRB_Iso).pack(
            anchor=tk.W, side=tk.LEFT)
#==========================================================
#-- meter_mode command
def cmdMeterMode():
    camera.meter_mode = varMeterMode.get()
    print("meter_mode: " + str(camera.meter_mode))
#-- exposure_mode
lfMeterMode = ttk.LabelFrame(frame2, text="meter_mode")
lfMeterMode.pack(fill="x", expand="no", anchor=tk.N)
varMeterMode = tk.StringVar()
varMeterMode.set(camera.meter_mode)

tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='average',value='average',command=cmdMeterMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='spot',value='spot',command=cmdMeterMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='backlit',value='backlit',command=cmdMeterMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='matrix',value='matrix',command=cmdMeterMode).pack(
            anchor=tk.W, side=tk.LEFT)


#==========================================================
#-- exposure_mode command
def cmdEposureMode():
    camera.exposure_mode = varExposureMode.get()
    print("exposure_mode: " + str(camera.exposure_mode))
#-- exposure_mode
lfExpMode = ttk.LabelFrame(frame2, text="exposure_mode")
lfExpMode.pack(fill="x", expand="no", anchor=tk.N)
varExposureMode = tk.StringVar()
varExposureMode.set(camera.exposure_mode)
lfExposure_mode1 = ttk.Frame(lfExpMode)
lfExposure_mode1.pack(fill="x", expand="no", anchor=tk.N)
lfExposure_mode2 = ttk.Frame(lfExpMode)
lfExposure_mode2.pack(fill="x", expand="no", anchor=tk.N)

tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='off',value='off',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='auto',value='auto',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='night',value='night',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)

tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='nightpreview',value='nightpreview',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='backlight',value='backlight',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='spotlight',value='spotlight',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='sports',value='sports',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode1, variable=varExposureMode,
        text='snow',value='snow',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)

tk.Radiobutton(lfExposure_mode2, variable=varExposureMode,
        text='beach',value='beach',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode2, variable=varExposureMode,
        text='verylong',value='verylong',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode2, variable=varExposureMode,
        text='fixedfps',value='fixedfps',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode2, variable=varExposureMode,
        text='antishake',value='antishake',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExposure_mode2, variable=varExposureMode,
        text='fireworks',value='fireworks',command=cmdEposureMode).pack(
            anchor=tk.W, side=tk.LEFT)
#==========================================================
#common button handler for ImageEffect without parameter setting,
#simple set camera.image_effect
def butComImageEffect():
    camera.image_effect=varImageEffect.get()
    labelImageEffectVar.set(camera.image_effect)

#----- ImageEffect 'solarise' ui event
def butImageEffect_solarize():
    camera.image_effect=varImageEffect.get()
    if cbSolarize_yuv_Var.get():
        yuv = 1
    else:
        yuv = 0
    solarize_para = (yuv,
                     scSolarize_x0_Var.get(),
                     scSolarize_y0_Var.get(),
                     scSolarize_y1_Var.get(),
                     scSolarize_y2_Var.get())
    camera.image_effect_params = solarize_para
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_solarizePara(new_value=None):
    varImageEffect.set("solarize")
    butImageEffect_solarize()

#----- ImageEffect 'watercolor' ui event ---
def butImageEffect_watercolor():
    camera.image_effect=varImageEffect.get()
    
    if cbWatercolor_uv_Var.get():
        watercolor_para = (scWatercolor_u_Var.get(),
                           scWatercolor_v_Var.get())
        camera.image_effect_params = watercolor_para
    else:
        watercolor_para = ()
        camera.image_effect_params = watercolor_para
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_watercolorPara(new_value=None):
    varImageEffect.set("watercolor")
    butImageEffect_watercolor()
    
#----- ImageEffect 'film' ui event ---
def butImageEffect_film():
    camera.image_effect=varImageEffect.get()
    
    film_para = (scFilm_strength_Var.get(),
                 scFilm_u_Var.get(),
                 scFilm_v_Var.get())
    camera.image_effect_params = film_para
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_filmPara(new_value=None):
    varImageEffect.set("film")
    butImageEffect_film()
    
#----- ImageEffect 'blur' ui event ---
def butImageEffect_blur():
    camera.image_effect=varImageEffect.get()
    
    camera.image_effect_params = scBlur_size_Var.get()
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_blurPara(new_value=None):
    varImageEffect.set("blur")
    butImageEffect_blur()
    
#----- ImageEffect 'colorswap' ui event ---
def butImageEffect_colorswap():
    camera.image_effect=varImageEffect.get()
    
    camera.image_effect_params = cbColorswap_dir_Var.get()
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_colorswapPara(new_value=None):
    varImageEffect.set("colorswap")
    butImageEffect_colorswap()

#----- ImageEffect 'posterise' ui event ---
def butImageEffect_posterise():
    camera.image_effect=varImageEffect.get()

    camera.image_effect_params = scPosterise_steps_Var.get()

    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_posterisePara(new_value=None):
    varImageEffect.set("posterise")
    butImageEffect_posterise()

#----- ImageEffect 'colorpoint' ui event ---
def butImageEffect_colorpoint():
    camera.image_effect=varImageEffect.get()

    camera.image_effect_params = quadrantVar.get()
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_colorpointPara(new_value=None):
    varImageEffect.set("colorpoint")
    butImageEffect_colorpoint()

#----- ImageEffect 'colorbalance' ui event ---
def butImageEffect_colorbalance():
    camera.image_effect=varImageEffect.get()

    colorbalance_para = (scColorbalance_lens_Var.get(),
                         scColorbalance_r_Var.get(),
                         scColorbalance_g_Var.get(),
                         scColorbalance_b_Var.get(),
                         scColorbalance_u_Var.get(),
                         scColorbalance_v_Var.get())
    camera.image_effect_params = colorbalance_para
    
    labelImageEffectVar.set(camera.image_effect +
                            " " + str(camera.image_effect_params))
    
def ev_colorbalancePara(new_value=None):
    varImageEffect.set("colorbalance")
    butImageEffect_colorbalance()
#-----------------------------------------------------
#-----------------------------------------------------
    
# Tab Image Effect
varImageEffect = tk.StringVar()
labelImageEffectVar = tk.StringVar()
image_effect_setting = camera.image_effect
varImageEffect.set(image_effect_setting)
labelImageEffectVar.set(image_effect_setting)
tk.Label(frame3, textvariable=labelImageEffectVar).pack(anchor=tk.N)

#-- image_effect

lfNoParaOpts1 = ttk.Frame(frame3)
lfNoParaOpts1.pack(fill="x", expand="yes", anchor=tk.N)

tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='none',value='none',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='negative',value='negative',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='sketch',value='sketch',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='denoise',value='denoise',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='emboss',value='emboss',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='oilpaint',value='oilpaint',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='hatch',value='hatch',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='gpen',value='gpen',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)

lfNoParaOpts2 = ttk.Frame(frame3)
lfNoParaOpts2.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='pastel',value='pastel',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='saturation',value='saturation',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='washedout',value='washedout',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='cartoon',value='cartoon',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace1',value='deinterlace1',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace2',value='deinterlace2',command=butComImageEffect).pack(
            anchor=tk.W, side=tk.LEFT)

lfSolarize = ttk.LabelFrame(frame3, text="solarize")
lfSolarize.pack(fill="x", expand="yes", anchor=tk.N)

tk.Radiobutton(lfSolarize, variable=varImageEffect,
        text='solarize',value='solarize',command=butImageEffect_solarize).pack(
            anchor=tk.W, side=tk.LEFT)

cbSolarize_yuv_Var = tk.BooleanVar()
tk.Checkbutton(lfSolarize, text="yuv",
    variable=cbSolarize_yuv_Var, command=ev_solarizePara).pack(
        anchor=tk.W, side=tk.LEFT)

scSolarize_x0_Var = tk.IntVar()
scSolarize_x0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="x0",
    variable=scSolarize_x0_Var, command=ev_solarizePara).pack(
        anchor=tk.W, side=tk.LEFT)

scSolarize_y0_Var = tk.IntVar()
scSolarize_y0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y0",
    variable=scSolarize_y0_Var, command=ev_solarizePara).pack(
        anchor=tk.W, side=tk.LEFT)

scSolarize_y1_Var = tk.IntVar()
scSolarize_y1_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y1",
    variable=scSolarize_y1_Var, command=ev_solarizePara).pack(
        anchor=tk.W, side=tk.LEFT)

scSolarize_y2_Var = tk.IntVar()
scSolarize_y2_Var.set(0)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y2",
    variable=scSolarize_y2_Var, command=ev_solarizePara).pack(
        anchor=tk.W, side=tk.LEFT)

lfwatercolor = ttk.LabelFrame(frame3, text="watercolor")
lfwatercolor.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfwatercolor, variable=varImageEffect,
        text='watercolor',value='watercolor',command=butImageEffect_watercolor
               ).pack(anchor=tk.W, side=tk.LEFT)

cbWatercolor_uv_Var = tk.BooleanVar()
cbWatercolor_uv_Var.set(False)
tk.Checkbutton(lfwatercolor, text="uv",
    variable=cbWatercolor_uv_Var, command=ev_watercolorPara).pack(
        anchor=tk.W, side=tk.LEFT)

scWatercolor_u_Var = tk.IntVar()
scWatercolor_u_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scWatercolor_u_Var, command=ev_watercolorPara).pack(
        anchor=tk.W, side=tk.LEFT)
scWatercolor_v_Var = tk.IntVar()
scWatercolor_v_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scWatercolor_v_Var, command=ev_watercolorPara).pack(
        anchor=tk.W, side=tk.LEFT)

lffilm = ttk.LabelFrame(frame3, text="film")
lffilm.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lffilm, variable=varImageEffect,
        text='film',value='film',command=butImageEffect_film).pack(
            anchor=tk.W, side=tk.LEFT)

scFilm_strength_Var = tk.IntVar()
scFilm_strength_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="strength",
    variable=scFilm_strength_Var, command=ev_filmPara).pack(
        anchor=tk.W, side=tk.LEFT)
scFilm_u_Var = tk.IntVar()
scFilm_u_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scFilm_u_Var, command=ev_filmPara).pack(anchor=tk.W, side=tk.LEFT)
scFilm_v_Var = tk.IntVar()
scFilm_v_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scFilm_v_Var, command=ev_filmPara).pack(anchor=tk.W, side=tk.LEFT)

lfblur = ttk.LabelFrame(frame3, text="blur")
lfblur.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfblur, variable=varImageEffect,
        text='blur',value='blur',command=butImageEffect_blur).pack(
            anchor=tk.W, side=tk.LEFT)
scBlur_size_Var = tk.IntVar()
scBlur_size_Var.set(1)
tk.Scale(lfblur, from_=1, to=2,
    orient=tk.HORIZONTAL, length=100, label="size",
    variable=scBlur_size_Var, command=ev_blurPara).pack(anchor=tk.W, side=tk.LEFT)

lfcolorswap = ttk.LabelFrame(frame3, text="colorswap")
lfcolorswap.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfcolorswap, variable=varImageEffect,
        text='colorswap',value='colorswap',command=butImageEffect_colorswap).pack(
            anchor=tk.W, side=tk.LEFT)
cbColorswap_dir_Var = tk.BooleanVar()
cbColorswap_dir_Var.set(False)
tk.Checkbutton(lfcolorswap, text="dir - 0:RGB to BGR/1:RGB to BRG",
    variable=cbColorswap_dir_Var, command=ev_colorswapPara).pack(
        anchor=tk.W, side=tk.LEFT)

lfposterise = ttk.LabelFrame(frame3, text="posterise")
lfposterise.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfposterise, variable=varImageEffect,
        text='posterise',value='posterise',command=butImageEffect_posterise).pack(
            anchor=tk.W, side=tk.LEFT)
scPosterise_steps_Var = tk.IntVar()
scPosterise_steps_Var.set(4)
tk.Scale(lfposterise, from_=2, to=32,
    orient=tk.HORIZONTAL, length=200, label="steps",
    variable=scPosterise_steps_Var, command=ev_posterisePara).pack(
        anchor=tk.W, side=tk.LEFT)

lfcolorpoint = ttk.LabelFrame(frame3, text="colorpoint")
lfcolorpoint.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfcolorpoint, variable=varImageEffect,
        text='colorpoint',value='colorpoint',command=butImageEffect_colorpoint).pack(
            anchor=tk.W, side=tk.LEFT)
quadrantVar = tk.IntVar()
quadrantVar.set(0)
tk.Radiobutton(lfcolorpoint, text="green",
    variable=quadrantVar, value=0, command=ev_colorpointPara).pack(
        anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="red/yellow",
    variable=quadrantVar, value=1, command=ev_colorpointPara).pack(
        anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="blue",
    variable=quadrantVar, value=2, command=ev_colorpointPara).pack(
        anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="purple",
    variable=quadrantVar, value=3, command=ev_colorpointPara).pack(
        anchor=tk.W, side=tk.LEFT)

lfcolorbalance = ttk.LabelFrame(frame3, text="colorbalance: I can't see any effect!")
lfcolorbalance.pack(fill="x", expand="yes", anchor=tk.N)
tk.Radiobutton(lfcolorbalance, variable=varImageEffect,
        text='colorbalance',value='colorbalance',command=butImageEffect_colorbalance).pack(
            anchor=tk.W, side=tk.LEFT)

scColorbalance_lens_Var = tk.DoubleVar()
scColorbalance_lens_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="lens",
    variable=scColorbalance_lens_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

scColorbalance_r_Var = tk.DoubleVar()
scColorbalance_r_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="r",
    variable=scColorbalance_r_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

scColorbalance_g_Var = tk.DoubleVar()
scColorbalance_g_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="g",
    variable=scColorbalance_g_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

scColorbalance_b_Var = tk.DoubleVar()
scColorbalance_b_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="b",
    variable=scColorbalance_b_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

scColorbalance_u_Var = tk.IntVar()
scColorbalance_u_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="u",
    variable=scColorbalance_u_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

scColorbalance_v_Var = tk.IntVar()
scColorbalance_v_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="v",
    variable=scColorbalance_v_Var, command=ev_colorbalancePara).pack(
        anchor=tk.W, side=tk.LEFT)

#==========================================================
root.mainloop()

print("- bye -")


Remark:
As this is writing, picamera is still 1.13, so the maximum resolution is 3280x2464 for V2, not HQ. 



~ Another minimum version:  with minimum functions preview and capture only, using PyQt5 GUI, fixed resolution 240x240, and display the captured image on GUI. You can also choice save file name; image.jpg or img_<timestamp>.jpg, under Desktop folder.

Related:

Saturday, May 23, 2020

Python to control Raspberry Pi Camera

It's a simple Python script run on Raspberry Pi/Raspbian to perform simple control of camera, start preview, stop preview, and capture photo.

It run with Python3.

import sys
from tkinter import *
import picamera
from pkg_resources import require
import time

#event callback functions
def evStartPreviewBtnPressed():
    print("Start Preview")
    camera.start_preview()

def evStopPreviewBtnPressed():
    print("Stop Preview")
    camera.stop_preview()

def evCaptureBtnPressed():
    print("Capture")
    timeStamp = time.strftime("%Y%m%d-%H%M%S")
    targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
    print(targetPath)
    camera.capture(targetPath)

print(sys.version)
print(require('picamera'))


#Prepare camera
camera = picamera.PiCamera()


root = Tk()
root.geometry("600x360")
root.wm_title("Hello")
#root.configure(bg = "#909090")

labelSys = Label(root, text=sys.version, justify=LEFT)
labelSys.grid(row=0, columnspan=2, sticky=W)
labelPiCameraVer = Label(root, text=require('picamera'), justify=LEFT)
labelPiCameraVer.grid(row=1, columnspan=2, sticky=W)
                         

btnStartPreview = Button(root, text="Start Preview",
                         command=evStartPreviewBtnPressed)
btnStopPreview = Button(root, text="Stop Preview",
                        command=evStopPreviewBtnPressed)
btnStartPreview.grid(row=2, column=0, sticky=W+E)
btnStopPreview.grid(row=2, column=1, sticky=W+E)

btnCapture = Button(root, text="Capture",
                    command=evCaptureBtnPressed)
btnCapture.grid(row=3, columnspan=2, sticky=W+E)


root.mainloop()

#close tasks
camera.close()

With Microsoft's Remote Desktop on Android device, it can be run remotely. The camera preview will be displayed on local screen.


xredp have to be installed in Raspberry Pi, with command:
$ sudo apt-get install xrdp

This video show how it run on Raspberry Pi 3 with Waveshare 4" HDMI LCD, run it on Android phone with Remote Desktop app. The local mounted display (4" HDMI LCD) is used as viewfinder.


Remark:
If you run the script locally, the preview will cover the GUI, but you can still click on it. Click the original position of the Stop Preview button to close the preview.


NOT WORK on High Quality Camera

Once I received High Quality Camera and tested on it, the script fail when capture continuously. Then I make a simple script to take photos using RPi Camera Module, work on v2.1, but also faile on High Quality Camera with "picamera.exc.PiCameraRuntimeError: No data received from sensor."


What's wrong on the script? or my Raspberry Pi High Quality Camera defected?

Tested on:
- Raspberry Pi 3B+
- Update Raspberry Pi OS
- Python 3.7.3
- picamera 1.13

doCappp.py
import picamera
import time

with picamera.PiCamera() as camera:
    camera.start_preview()
    for i in range(5):
        camera.resolution = (1280, 720)
        time.sleep(1)
        filename = 'imageA%02d.jpg' % i
        camera.capture(filename)
        print('Captured %s' % filename)
    time.sleep(7)
    
    print("End")
    camera.stop_preview()
    time.sleep(1)
    print("End End")
    camera.close()
    print("End End End")


Monday, June 27, 2016

picamera updated 1.11


Picamera updated 1.11, now support Camera V2. If you not yet updated, run the command to update:
$ sudo apt-get update
$ sudo apt-get upgrade

Suggested to update firmware also:
$ sudo rpi-update


Release 1.11 (2016-06-19) Change log (https://picamera.readthedocs.io/en/release-1.11/changelog.html):

1.11 on the surface consists mostly of enhancements, but underneath includes a major re-write of picamera’s core:

  • Direct capture to buffer-protocol objects, such as numpy arrays (#241)
  • Add request_key_frame() method to permit manual request of an I-frame during H264 recording; this is now used implicitly by split_recording() (#257)
  • Added timestamp attribute to query camera’s clock (#212)
  • Added framerate_delta to permit small adjustments to the camera’s framerate to be performed “live” (#279)
  • Added clear() and copy_to() methods to PiCameraCircularIO (#216)
  • Prevent setting attributes on the main PiCamera class to ease debugging in educational settings (#240)
  • Due to the core re-writes in this version, you may require cutting edge firmware (sudo rpi-update) if you are performing unencoded captures, unencoded video recording, motion estimation vector sampling, or manual sensor mode setting.
  • Added property to control preview’s resolution separately from the camera’s resolution (required for maximum resolution previews on the V2 module - #296).

There are also several bug fixes:

  • Fixed basic stereoscopic operation on compute module (#218)
  • Fixed accessing framerate as a tuple (#228)
  • Fixed hang when invalid file format is specified (#236)
  • Fixed multiple bayer captures with capture_sequence() and capture_continuous() (#264)
  • Fixed usage of “falsy” custom outputs with motion_output (#281)
Many thanks to the community, and especially thanks to 6by9 (one of the firmware developers) who’s fielded seemingly endless questions and requests from me in the last couple of months!


Hardware Limits (http://picamera.readthedocs.io/en/release-1.11/fov.html#hardware-limits):

The are additional limits imposed by the GPU hardware that performs all image and video processing:

  • The maximum resolution for MJPEG recording depends partially on GPU memory. If you get “Out of resource” errors with MJPEG recording at high resolutions, try increasing gpu_mem in /boot/config.txt.
  • The maximum horizontal resolution for default H264 recording is 1920. Any attempt to recording H264 video at higher horizontal resolutions will fail.
  • However, H264 high profile level 4.2 has slightly higher limits and may succeed with higher resolutions.
  • The maximum resolution of the V2 camera can cause issues with previews. Currently, picamera runs previews at the same resolution as captures (equivalent to -fp in raspistill). You may need to increase gpu_mem in /boot/config.txt to achieve full resolution operation with the V2 camera module.
  • The maximum framerate of the camera depends on several factors. With overclocking, 120fps has been achieved on a V2 module but 90fps is the maximum supported framerate.
  • The maximum exposure time is currently 6 seconds on the V1 camera module, and 10 seconds on the V2 camera module. Remember that exposure time is limited by framerate, so you need to set an extremely slow framerate before setting shutter_speed.



Sunday, April 24, 2016

Python script to take timelapse photos


It's my exercise of Python 2 to take timelapse photos, modified from the Python script in "Test Pi NoIR Camera Module with Infrared filter, 680nm vs 720nm".

myPiLapse.py
import picamera
import Tkinter as tk
import ttk
import time
from PIL import ImageTk, Image
from threading import Thread
import io
import sys
from pkg_resources import require
from fractions import Fraction
from time import sleep
import tkFont

#reference:
# http://picamera.readthedocs.org/en/latest/api_camera.html

RQS_0=0
RQS_QUIT=1
RQS_CAPTURE=2
RQS_STARTLAPSE = 3
RQS_STOPLAPSE = 4
RQS_LAPSEEND = 5
rqs=RQS_0
rqsUpdateSetting=True

LAPSE_RQS_0 = 0
LAPSE_RQS_STOP = 1
lapse_rqs = LAPSE_RQS_0

PREFIX_IMAGE = "img_"
PREFIX_LAPSE = "lapse_"
prefix = PREFIX_IMAGE



def camHandler():
    global rqs
    rqs = RQS_0

    timelapsing = False
    
    camera = picamera.PiCamera()
    #stream = io.BytesIO()

    #set default
    camera.sharpness = 0
    camera.contrast = 0
    camera.brightness = 50
    camera.saturation = 0
    camera.ISO = 0
    camera.video_stabilization = False
    camera.exposure_compensation = 0
    camera.exposure_mode = 'auto'
    camera.meter_mode = 'average'
    camera.awb_mode = 'auto'
    camera.image_effect = 'none'
    camera.color_effects = None
    #camera.rotation = 0
    camera.rotation = 270
    camera.hflip = False
    camera.vflip = False
    camera.crop = (0.0, 0.0, 1.0, 1.0)
    #camera.resolution = (1024, 768)
    camera.resolution = (400, 300)
    #end of set default
    #camera.start_preview()

    while rqs != RQS_QUIT:
        #check if need update setting
        global rqsUpdateSetting
        if ((rqsUpdateSetting == True) and (timelapsing == False)):
            rqsUpdateSetting = False
            camera.sharpness = scaleSharpness.get()
            camera.contrast = scaleContrast.get()
            camera.brightness = scaleBrightness.get()
            camera.saturation = scaleSaturation.get()
            camera.exposure_compensation = scaleExpCompensation.get()
            camera.iso = varIso.get()
            camera.drc_strength = varDrc.get()
            camera.exposure_mode = varExpMode.get()
            camera.meter_mode = varMeterMode.get()
            camera.rotation = varRotation.get()
            camera.vflip = varVFlip.get()
            camera.hflip = varHFlip.get()
            camera.image_denoise = varDenoise.get()

            awb_mode_setting = varAwbMode.get()
            labelAwbVar.set(awb_mode_setting)
            camera.awb_mode = awb_mode_setting

            if awb_mode_setting == "off":
                gr = scaleGainRed.get()
                gb = scaleGainBlue.get()
                gAwb = (gr, gb)
                camera.awb_gains = gAwb
                labelAwbVar.set(awb_mode_setting + " : "
                    + str(gAwb))

            image_effect_setting = varImageEffect.get()
            labelImageEffectVar.set(image_effect_setting)
            camera.image_effect = image_effect_setting

            if image_effect_setting == 'solarize':
                if cbSolarize_yuv_Var.get():
                    yuv = 1
                else:
                    yuv = 0
                solarize_para = (
                    yuv,
                    scSolarize_x0_Var.get(),
                    scSolarize_y0_Var.get(),
                    scSolarize_y1_Var.get(),
                    scSolarize_y2_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(solarize_para))
                camera.image_effect_params = solarize_para
            elif image_effect_setting == 'colorpoint':
                camera.image_effect_params = quadrantVar.get()
                labelImageEffectVar.set(image_effect_setting + " " + str(quadrantVar.get()))
            elif image_effect_setting == 'colorbalance':
                colorbalance_para = (
                    scColorbalance_lens_Var.get(),
                    scColorbalance_r_Var.get(),
                    scColorbalance_g_Var.get(),
                    scColorbalance_b_Var.get(),
                    scColorbalance_u_Var.get(),
                    scColorbalance_v_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(colorbalance_para))
                camera.image_effect_params = colorbalance_para
            elif image_effect_setting == 'colorswap':
                labelImageEffectVar.set(image_effect_setting + " " + str(cbColorswap_dir_Var.get()))
                camera.image_effect_params = cbColorswap_dir_Var.get()
            elif image_effect_setting == 'posterise':
                labelImageEffectVar.set(image_effect_setting + " " + str(scPosterise_steps_Var.get()))
                camera.image_effect_params = scPosterise_steps_Var.get()
            elif image_effect_setting == 'blur':
                labelImageEffectVar.set(image_effect_setting + " " + str(scBlur_size_Var.get()))
                camera.image_effect_params = scBlur_size_Var.get()
            elif image_effect_setting == 'film':
                film_para = (
                    scFilm_strength_Var.get(),
                    scFilm_u_Var.get(),
                    scFilm_v_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(film_para))
                camera.image_effect_params = film_para
            elif image_effect_setting == 'watercolor':
                if cbWatercolor_uv_Var.get():
                    watercolor_para = (
                        scWatercolor_u_Var.get(),
                        scWatercolor_v_Var.get())
                    labelImageEffectVar.set(image_effect_setting + " " + str(watercolor_para))
                    camera.image_effect_params = watercolor_para
                else:
                    watercolor_para = ()
                    labelImageEffectVar.set(image_effect_setting + " " + str(watercolor_para))
                    camera.image_effect_params = watercolor_para

        if rqs == RQS_CAPTURE:
            global prefix
            print("Capture")
            rqs=RQS_0
            timeStamp = time.strftime("%Y%m%d-%H%M%S")
            jpgFile=prefix+timeStamp+'.jpg'
            
            #camera.resolution = (2592, 1944)    #set photo size

            varRes = varResolution.get()
            if varRes == '640x480':
                settingResolution = (640, 480)
            elif varRes == '800x600':
                settingResolution = (800, 600)
            elif varRes == '1280x720':
                settingResolution = (1280, 720)
            elif varRes == '1296x730':
                settingResolution = (1296, 730)
            elif varRes == '1296x972':
                settingResolution = (1296, 972)
            elif varRes == '1600x1200':
                settingResolution = (1600, 1200)
            elif varRes == '1920x1080':
                settingResolution = (1920, 1080)
            else:
                settingResolution = (2592, 1944)

            camera.resolution = settingResolution

            shutterSpeedSetting = varShutterSpeed.get()
            settingQuality = varQuality.get()
            
            if shutterSpeedSetting == 'normal':
                camera.capture(jpgFile, quality=settingQuality)
            else:
                orgFrameRate = camera.framerate

                if shutterSpeedSetting == '6 sec':
                    camera.framerate = Fraction(1, 6)
                    camera.shutter_speed = 6000000
                elif shutterSpeedSetting == '5 sec':
                    camera.framerate = Fraction(1, 5)
                    camera.shutter_speed = 5000000
                elif shutterSpeedSetting == '4 sec':
                    camera.framerate = Fraction(1, 4)
                    camera.shutter_speed = 4000000
                elif shutterSpeedSetting == '3 sec':
                    camera.framerate = Fraction(1, 3)
                    camera.shutter_speed = 3000000
                elif shutterSpeedSetting == '2 sec':
                    camera.framerate = Fraction(1, 2)
                    camera.shutter_speed = 2000000
                elif shutterSpeedSetting == '1 sec':
                    camera.framerate = Fraction(1, 1)
                    camera.shutter_speed = 1000000
                elif shutterSpeedSetting == '1/2 sec':
                    camera.framerate = Fraction(1, 1)
                    camera.shutter_speed = 500000
                elif shutterSpeedSetting == '1/4 sec':
                    camera.framerate = Fraction(1, 1)
                    camera.shutter_speed = 250000
                #sleep(1)
                camera.capture(jpgFile, quality=settingQuality)
                camera.framerate = orgFrameRate
                camera.shutter_speed = 0

            camera.resolution = (400, 300)      #resume preview size
            
            labelCapVal.set(jpgFile)
        elif rqs == RQS_STARTLAPSE:
            rqs=RQS_0
            labelLapseText.set("Timelapse started.")
            btnStartLapse.config(state=tk.DISABLED)
            btnStopLapse.config(state=tk.NORMAL)

            timelapsing = True
            prefix = PREFIX_LAPSE

            camera.shutter_speed = camera.exposure_speed
            camera.exposure_mode = 'off'
            g = camera.awb_gains
            camera.awb_mode = 'off'
            camera.awb_gains = g
            
            startTimelapseHandle()
        elif rqs == RQS_STOPLAPSE:
            rqs=RQS_0
            global lapse_rqs
            lapse_rqs = LAPSE_RQS_STOP

            labelLapseText.set("Timelapse stopped.")
            btnStartLapse.config(state=tk.NORMAL)
            btnStopLapse.config(state=tk.DISABLED)

            prefix = PREFIX_IMAGE
            timelapsing = False
            rqsUpdateSetting = True
        elif rqs == RQS_LAPSEEND:
            rqs=RQS_0
            labelLapseText.set("Timelapse ended.")
            btnStartLapse.config(state=tk.NORMAL)
            btnStopLapse.config(state=tk.DISABLED)
            prefix = PREFIX_IMAGE
            timelapsing = False
            rqsUpdateSetting = True
        else:
            stream = io.BytesIO()
            camera.capture(stream, format='jpeg', quality=40)
            stream.seek(0)
            tmpImage = Image.open(stream)
            tmpImg = ImageTk.PhotoImage(tmpImage)
            previewPanel.configure(image = tmpImg)
            #sleep(0.5)
                
    print("Quit")        
    #camera.stop_preview()

def startCamHandler():
    camThread = Thread(target=camHandler)
    camThread.start()

def TimelapseHandle():
    global lapse_rqs
    global rqs
    global prefix

    print("TimelapseHandle started")

    numberOfShot = scaleNumOfShot.get()
    interval = scaleIntervalSec.get()
    
    while True:
        
        if lapse_rqs == LAPSE_RQS_STOP:
            lapse_rqs = LAPSE_RQS_0
            print('LAPSE_RQS_STOP')
            break
        print(numberOfShot)

        rqs = RQS_CAPTURE

        if numberOfShot != 0:
            numberOfShot = numberOfShot-1
            labelLapseText.set(str(numberOfShot))
            if numberOfShot == 0:
                break;
        
        sleep(interval)
        
    rqs = RQS_LAPSEEND
    print("TimelapseHandle ended")
    
def startTimelapseHandle():
    print("TimelapseHandle starting...")
    global lapse_rqs
    lapse_rqs = LAPSE_RQS_0
    timelapseThread = Thread(target=TimelapseHandle)
    timelapseThread.start()

def quit():
    print("quit()")
    global rqs
    global lapse_rqs
    rqs=RQS_QUIT
    lapse_rqs=LAPSE_RQS_STOP

    global tkTop
    tkTop.destroy()

def capture():
    global rqs
    rqs = RQS_CAPTURE
    labelCapVal.set("capturing")

def cbScaleSetting(new_value):
    global rqsUpdateSetting
    rqsUpdateSetting = True

def cbButtons():
    global rqsUpdateSetting
    rqsUpdateSetting = True
    
def lapseScaleSetting(new_value):
    #do nothing
    pass

def cmdStartLapse():
    global rqs
    labelLapseText.set("Timelapse starting...")
    rqs = RQS_STARTLAPSE

def cmdStopLapse():
    global rqs
    labelLapseText.set("Timelapse stopping...")
    rqs = RQS_STOPLAPSE

tkTop = tk.Tk()
tkTop.wm_title("helloraspberrypi.blogspot.com")
tkTop.geometry('1000x650')

myFont = tkFont.Font(size=16)

previewWin = tk.Toplevel(tkTop)
previewWin.title('Preview')
previewWin.geometry('400x300')
previewPanel = tk.Label(previewWin)
previewPanel.pack(side = "bottom", fill = "both", expand = "yes")

#tkButtonQuit = tk.Button(tkTop, text="Quit", command=quit).pack()

tkButtonCapture = tk.Button(
    tkTop, text="Capture", command=capture)
tkButtonCapture.pack()

SCALE_WIDTH = 980;

labelCapVal = tk.StringVar()
tk.Label(tkTop, textvariable=labelCapVal).pack()

notebook = ttk.Notebook(tkTop)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
frame3 = ttk.Frame(notebook)
frame4 = ttk.Frame(notebook)
frame5 = ttk.Frame(notebook)
notebook.add(frame1, text='Setting')
notebook.add(frame2, text='White Balance')
notebook.add(frame3, text='Image Effect')
notebook.add(frame4, text='Control')
notebook.add(frame5, text='Timelapse')
notebook.pack()

# Tab Setting
tk.Label(frame1, text=require('picamera')).pack()

scaleSharpness = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="sharpness",
    command=cbScaleSetting)
scaleSharpness.set(0)
scaleSharpness.pack(anchor=tk.CENTER)

scaleContrast = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="contrast",
    command=cbScaleSetting)
scaleContrast.set(0)
scaleContrast.pack(anchor=tk.CENTER)

scaleBrightness = tk.Scale(
    frame1,
    from_=0, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="brightness",
    command=cbScaleSetting)
scaleBrightness.set(50)
scaleBrightness.pack(anchor=tk.CENTER)

scaleSaturation = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="saturation",
    command=cbScaleSetting)
scaleSaturation.set(0)
scaleSaturation.pack(anchor=tk.CENTER)

scaleExpCompensation = tk.Scale(
    frame1,
    from_=-25, to=25,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="exposure_compensation",
    command=cbScaleSetting)
scaleExpCompensation.set(0)
scaleExpCompensation.pack(anchor=tk.CENTER)

lfExpMode = ttk.LabelFrame(frame1, text="Exposure Mode")
lfExpMode.pack(fill="x")
varExpMode = tk.StringVar()
varExpMode.set('auto')
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='off',value='off',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='auto',value='auto',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='night',value='night',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='nightpreview',value='nightpreview',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='backlight',value='backlight',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='spotlight',value='spotlight',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='sports',value='sports',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='snow',value='snow',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='beach',value='beach',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='verylong',value='verylong',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='fixedfps',value='fixedfps',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='antishake',value='antishake',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfExpMode, variable=varExpMode,
        text='fireworks',value='fireworks',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfMeterMode = ttk.LabelFrame(frame1, text="Meter Mode")
lfMeterMode.pack(fill="x")
varMeterMode = tk.StringVar()
varMeterMode.set('average')
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='average',value='average',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='spot',value='spot',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='backlit',value='backlit',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfMeterMode, variable=varMeterMode,
        text='matrix',value='matrix',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

# Tab White Balance

lfAwbMode = ttk.LabelFrame(frame2, text="awb_mode")
lfAwbMode.pack(fill="x")
lfAwbGains = ttk.LabelFrame(frame2, text="awb_gains")
lfAwbGains.pack(fill="x")

labelAwbVar = tk.StringVar()
tk.Label(lfAwbMode, textvariable=labelAwbVar).pack()

#--
AWB_MODES = [
    ("off (set by awb_gains)", "off"),
    ("auto", "auto"),
    ("sunlight", "sunlight"),
    ("cloudy", "cloudy"),
    ("shade", "shade"),
    ("tungsten", "tungsten"),
    ("fluorescent", "fluorescent"),
    ("incandescent", "incandescent"),
    ("flash", "flash"),
    ("horizon", "horizon"),
    ]

varAwbMode = tk.StringVar()
varAwbMode.set("auto")
for text, awbmode in AWB_MODES:
    awbModeBtns = tk.Radiobutton(
        lfAwbMode,
        text=text,
        variable=varAwbMode,
        value=awbmode,
        command=cbButtons)
    awbModeBtns.pack(anchor=tk.W)
#--
scaleGainRed = tk.Scale(
    lfAwbGains,
    from_=0.0, to=8.0,
    resolution=0.1,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="Red",
    command=cbScaleSetting)
scaleGainRed.set(0.0)
scaleGainRed.pack(anchor=tk.CENTER)

scaleGainBlue = tk.Scale(
    lfAwbGains,
    from_=0.0, to=8.0,
    resolution=0.1,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="Blue",
    command=cbScaleSetting)
scaleGainBlue.set(0.0)
scaleGainBlue.pack(anchor=tk.CENTER)

# Tab Image Effect
#For Image effects, ref:
#http://picamera.readthedocs.org/en/latest/api_camera.html?highlight=effect#picamera.camera.PiCamera.image_effect
labelImageEffectVar = tk.StringVar()
tk.Label(frame3, textvariable=labelImageEffectVar).pack()
#-- image_effect

varImageEffect = tk.StringVar()
varImageEffect.set('none')

lfNoParaOpts1 = ttk.Frame(frame3)
lfNoParaOpts1.pack(fill="x")

tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='none',value='none',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='negative',value='negative',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='sketch',value='sketch',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='denoise',value='denoise',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='emboss',value='emboss',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='oilpaint',value='oilpaint',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='hatch',value='hatch',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='gpen',value='gpen',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfNoParaOpts2 = ttk.Frame(frame3)
lfNoParaOpts2.pack(fill="x")
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='pastel',value='pastel',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='saturation',value='saturation',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='washedout',value='washedout',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='cartoon',value='cartoon',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace1',value='deinterlace1',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace2',value='deinterlace2',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfSolarize = ttk.LabelFrame(frame3, text="solarize")
lfSolarize.pack(fill="x")

tk.Radiobutton(lfSolarize, variable=varImageEffect,
        text='solarize',value='solarize',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

cbSolarize_yuv_Var = tk.BooleanVar()
tk.Checkbutton(lfSolarize, text="yuv",
    variable=cbSolarize_yuv_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_x0_Var = tk.IntVar()
scSolarize_x0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="x0",
    variable=scSolarize_x0_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y0_Var = tk.IntVar()
scSolarize_y0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y0",
    variable=scSolarize_y0_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y1_Var = tk.IntVar()
scSolarize_y1_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y1",
    variable=scSolarize_y1_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y2_Var = tk.IntVar()
scSolarize_y2_Var.set(0)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y2",
    variable=scSolarize_y2_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfwatercolor = ttk.LabelFrame(frame3, text="watercolor")
lfwatercolor.pack(fill="x")
tk.Radiobutton(lfwatercolor, variable=varImageEffect,
        text='watercolor',value='watercolor',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

cbWatercolor_uv_Var = tk.BooleanVar()
cbWatercolor_uv_Var.set(False)
tk.Checkbutton(lfwatercolor, text="uv",
    variable=cbWatercolor_uv_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scWatercolor_u_Var = tk.IntVar()
scWatercolor_u_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scWatercolor_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scWatercolor_v_Var = tk.IntVar()
scWatercolor_v_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scWatercolor_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lffilm = ttk.LabelFrame(frame3, text="film")
lffilm.pack(fill="x")
tk.Radiobutton(lffilm, variable=varImageEffect,
        text='film',value='film',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scFilm_strength_Var = tk.IntVar()
scFilm_strength_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="strength",
    variable=scFilm_strength_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scFilm_u_Var = tk.IntVar()
scFilm_u_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scFilm_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scFilm_v_Var = tk.IntVar()
scFilm_v_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scFilm_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfblur = ttk.LabelFrame(frame3, text="blur")
lfblur.pack(fill="x")
tk.Radiobutton(lfblur, variable=varImageEffect,
        text='blur',value='blur',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
scBlur_size_Var = tk.IntVar()
scBlur_size_Var.set(1)
tk.Scale(lfblur, from_=1, to=2,
    orient=tk.HORIZONTAL, length=100, label="size",
    variable=scBlur_size_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfcolorswap = ttk.LabelFrame(frame3, text="colorswap")
lfcolorswap.pack(fill="x")
tk.Radiobutton(lfcolorswap, variable=varImageEffect,
        text='colorswap',value='colorswap',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
cbColorswap_dir_Var = tk.BooleanVar()
cbColorswap_dir_Var.set(False)
tk.Checkbutton(lfcolorswap, text="dir - 0:RGB to BGR/1:RGB to BRG",
    variable=cbColorswap_dir_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfposterise = ttk.LabelFrame(frame3, text="posterise")
lfposterise.pack(fill="x")
tk.Radiobutton(lfposterise, variable=varImageEffect,
        text='posterise',value='posterise',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
scPosterise_steps_Var = tk.IntVar()
scPosterise_steps_Var.set(4)
tk.Scale(lfposterise, from_=2, to=32,
    orient=tk.HORIZONTAL, length=200, label="steps",
    variable=scPosterise_steps_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfcolorpoint = ttk.LabelFrame(frame3, text="colorpoint")
lfcolorpoint.pack(fill="x")
tk.Radiobutton(lfcolorpoint, variable=varImageEffect,
        text='colorpoint',value='colorpoint',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
quadrantVar = tk.IntVar()
quadrantVar.set(0)
tk.Radiobutton(lfcolorpoint, text="green",
    variable=quadrantVar, value=0, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="red/yellow",
    variable=quadrantVar, value=1, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="blue",
    variable=quadrantVar, value=2, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="purple",
    variable=quadrantVar, value=3, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfcolorbalance = ttk.LabelFrame(frame3, text="colorbalance: I can't see the effect!")
lfcolorbalance.pack(fill="x")
tk.Radiobutton(lfcolorbalance, variable=varImageEffect,
        text='colorbalance',value='colorbalance',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_lens_Var = tk.DoubleVar()
scColorbalance_lens_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="lens",
    variable=scColorbalance_lens_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_r_Var = tk.DoubleVar()
scColorbalance_r_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="r",
    variable=scColorbalance_r_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_g_Var = tk.DoubleVar()
scColorbalance_g_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="g",
    variable=scColorbalance_g_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_b_Var = tk.DoubleVar()
scColorbalance_b_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="b",
    variable=scColorbalance_b_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_u_Var = tk.IntVar()
scColorbalance_u_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="u",
    variable=scColorbalance_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_v_Var = tk.IntVar()
scColorbalance_v_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="v",
    variable=scColorbalance_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
# Tab Control

lfISO = ttk.LabelFrame(frame4, text="ISO")
lfISO.pack(fill="x")
varIso = tk.IntVar()
tk.Radiobutton(lfISO, variable=varIso,
        text='auto',value='0',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='100',value='100',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='200',value='200',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='320',value='320',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='400',value='400',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='500',value='500',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='640',value='640',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfISO, variable=varIso,
        text='800',value='800',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfDRC = ttk.LabelFrame(frame4, text="Dynamic Range Compression")
lfDRC.pack(fill="x")
varDrc = tk.StringVar()
varDrc.set('off')
tk.Radiobutton(lfDRC, variable=varDrc,
        text='off',value='off',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfDRC, variable=varDrc,
        text='low',value='low',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfDRC, variable=varDrc,
        text='medium',value='medium',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfDRC, variable=varDrc,
        text='high',value='high',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfRotation = ttk.LabelFrame(frame4, text="Rotation")
lfRotation.pack(fill="x")
varRotation = tk.IntVar()
varRotation.set(270)
tk.Radiobutton(lfRotation, variable=varRotation,
        text='0',value='0',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfRotation, variable=varRotation,
        text='90',value='90',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfRotation, variable=varRotation,
        text='180',value='180',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfRotation, variable=varRotation,
        text='270',value='270',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)


lfFlip = ttk.LabelFrame(frame4, text="Flip")
lfFlip.pack(fill="x")
varHFlip = tk.BooleanVar()
varHFlip.set(False)
tk.Checkbutton(lfFlip, text="hflip",
    variable=varHFlip, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
varVFlip = tk.BooleanVar()
varVFlip.set(False)
tk.Checkbutton(lfFlip, text="vflip",
    variable=varVFlip, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
# Resolution
lfResolution = ttk.LabelFrame(frame4, text="Resolution")
lfResolution.pack(fill="x")
varResolution = tk.StringVar()
varResolution.set('1280x720')
tk.Radiobutton(lfResolution, variable=varResolution,
        text='640x480',value='640x480').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='800x400',value='800x600').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='1280x720',value='1280x720').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='1296x730',value='1296x730').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='1296x972',value='1296x972').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='1600x1200',value='1600x1200').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='1920x1080',value='1920x1080').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfResolution, variable=varResolution,
        text='2592x1944',value='2592x1944').pack(anchor=tk.W, side=tk.LEFT)

# Quality
lfQuality = ttk.LabelFrame(frame4, text="Quality")
lfQuality.pack(fill="x")
varQuality = tk.IntVar()
varQuality.set(85)
tk.Scale(lfQuality, from_=10, to=100,
    orient=tk.HORIZONTAL, length=600, label="%",
    variable=varQuality).pack(anchor=tk.W, side=tk.LEFT)

lfDenoise = ttk.LabelFrame(frame4, text="image_denoise")
lfDenoise.pack(fill="x")
varDenoise = tk.BooleanVar()
varDenoise.set(True)
tk.Checkbutton(lfDenoise, text="image_denoise",
    variable=varDenoise, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

# Shutter Speed
lfShuuterSpeed = ttk.LabelFrame(frame4, text="Slow Shutter (caution: NOT work as expected)")
lfShuuterSpeed.pack(fill="x")
frameShuuterSpeed1 = tk.Frame(lfShuuterSpeed)
frameShuuterSpeed1.pack(fill="x")
frameShuuterSpeed2 = tk.Frame(lfShuuterSpeed)
frameShuuterSpeed2.pack(fill="x")

varShutterSpeed = tk.StringVar()
varShutterSpeed.set('normal')
tk.Radiobutton(frameShuuterSpeed1, variable=varShutterSpeed,
        text='normal',value='normal').pack(anchor=tk.W, side=tk.LEFT)

tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='1/4 sec',value='1/4 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='1/2 sec',value='1/2 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='1 sec',value='1 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='2 sec',value='2 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='3 sec',value='3 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='4 sec',value='4 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='5 sec',value='5 sec').pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(frameShuuterSpeed2, variable=varShutterSpeed,
        text='6 sec',value='6 sec').pack(anchor=tk.W, side=tk.LEFT)

#---------------------------------------
#TimeLapse

lfTimelapse = ttk.LabelFrame(frame5, text="Timelapse")
lfTimelapse.pack(fill="x")

btnStartLapse = tk.Button(
    lfTimelapse, text="Start TimeLapse", state=tk.NORMAL,
    font=myFont, command=cmdStartLapse)
btnStartLapse.pack(anchor=tk.W, side=tk.LEFT)

btnStopLapse = tk.Button(
    lfTimelapse, text="Stop TimeLapse", state=tk.DISABLED,
    font=myFont, command=cmdStopLapse)
btnStopLapse.pack(anchor=tk.W, side=tk.LEFT)

labelLapseText = tk.StringVar()
tk.Label(lfTimelapse, textvariable=labelLapseText).pack(anchor=tk.W, side=tk.LEFT)

lfInterval = ttk.LabelFrame(frame5, text="interval")
lfInterval.pack(fill="x")

scaleIntervalSec = tk.Scale(
    lfInterval,
    from_=5, to=60,
    resolution=5,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="second",
    font=myFont,
    command=lapseScaleSetting)
scaleIntervalSec.set(5)
scaleIntervalSec.pack(anchor=tk.CENTER)

lfNumOfShot = ttk.LabelFrame(frame5, text="Number of shot")
lfNumOfShot.pack(fill="x")

scaleNumOfShot= tk.Scale(
    lfNumOfShot,
    from_=0, to=300,
    resolution=1,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="# (0 = continue until 'Stop Timelapse' button pressed)",
    font=myFont,
    command=lapseScaleSetting)
scaleNumOfShot.set(0)
scaleNumOfShot.pack(anchor=tk.CENTER)

labelLockedSetting = tk.StringVar()
tk.Label(frame5, textvariable=labelLockedSetting).pack()
#=======================================
print("start")
startCamHandler()

tk.mainloop()




Here is a video show how it run remote run on Raspberry Pi 3 with Camera Module, from Android phone. Where the phone act as WiFi hotspot, and remote login Raspberry Pi with aRDP app to run the script.

The Raspberry Pi 3 (with Camera Module) powered with portable battery, such that I can bring it outside. It installed with RDP and config to connect to my WiFi hotspot automatically.



Saturday, December 19, 2015

Python to capture image from Pi Camera Module, with image effects


picamera.camera Module provide function to apply various image effect. This example modified from previous post "Python to capture image from Pi Camera Module, with White Balance setting", to add feature to apply image effect.

reference: API - picamera.camera Module - image_effect


myPiCam.py
import picamera
import Tkinter as tk
import ttk
import time
from PIL import ImageTk, Image
from threading import Thread
import io
import sys
from pkg_resources import require

RQS_0=0
RQS_QUIT=1
RQS_CAPTURE=2
rqs=RQS_0
rqsUpdateSetting=True

def camHandler():
    global rqs
    rqs = RQS_0
    
    camera = picamera.PiCamera()
    #stream = io.BytesIO()

    #set default
    camera.sharpness = 0
    camera.contrast = 0
    camera.brightness = 50
    camera.saturation = 0
    camera.ISO = 0
    camera.video_stabilization = False
    camera.exposure_compensation = 0
    camera.exposure_mode = 'auto'
    camera.meter_mode = 'average'
    camera.awb_mode = 'auto'
    camera.image_effect = 'none'
    camera.color_effects = None
    #camera.rotation = 0
    camera.rotation = 270
    camera.hflip = False
    camera.vflip = False
    camera.crop = (0.0, 0.0, 1.0, 1.0)
    #camera.resolution = (1024, 768)
    camera.resolution = (400, 300)
    #end of set default
    #camera.start_preview()

    while rqs != RQS_QUIT:
        #check if need update setting
        global rqsUpdateSetting
        if rqsUpdateSetting == True:
            rqsUpdateSetting = False
            camera.sharpness = scaleSharpness.get()
            camera.contrast = scaleContrast.get()
            camera.brightness = scaleBrightness.get()
            camera.saturation = scaleSaturation.get()
            camera.exposure_compensation = scaleExpCompensation.get()

            awb_mode_setting = varAwbMode.get()
            labelAwbVar.set(awb_mode_setting)
            camera.awb_mode = awb_mode_setting

            if awb_mode_setting == "off":
                gr = scaleGainRed.get()
                gb = scaleGainBlue.get()
                gAwb = (gr, gb)
                camera.awb_gains = gAwb
                labelAwbVar.set(awb_mode_setting + " : "
                    + str(gAwb))

            image_effect_setting = varImageEffect.get()
            labelImageEffectVar.set(image_effect_setting)
            camera.image_effect = image_effect_setting

            if image_effect_setting == 'solarize':
                if cbSolarize_yuv_Var.get():
                    yuv = 1
                else:
                    yuv = 0
                solarize_para = (
                    yuv,
                    scSolarize_x0_Var.get(),
                    scSolarize_y0_Var.get(),
                    scSolarize_y1_Var.get(),
                    scSolarize_y2_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(solarize_para))
                camera.image_effect_params = solarize_para
            elif image_effect_setting == 'colorpoint':
                camera.image_effect_params = quadrantVar.get()
                labelImageEffectVar.set(image_effect_setting + " " + str(quadrantVar.get()))
            elif image_effect_setting == 'colorbalance':
                colorbalance_para = (
                    scColorbalance_lens_Var.get(),
                    scColorbalance_r_Var.get(),
                    scColorbalance_g_Var.get(),
                    scColorbalance_b_Var.get(),
                    scColorbalance_u_Var.get(),
                    scColorbalance_v_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(colorbalance_para))
                camera.image_effect_params = colorbalance_para
            elif image_effect_setting == 'colorswap':
                labelImageEffectVar.set(image_effect_setting + " " + str(cbColorswap_dir_Var.get()))
                camera.image_effect_params = cbColorswap_dir_Var.get()
            elif image_effect_setting == 'posterise':
                labelImageEffectVar.set(image_effect_setting + " " + str(scPosterise_steps_Var.get()))
                camera.image_effect_params = scPosterise_steps_Var.get()
            elif image_effect_setting == 'blur':
                labelImageEffectVar.set(image_effect_setting + " " + str(scBlur_size_Var.get()))
                camera.image_effect_params = scBlur_size_Var.get()
            elif image_effect_setting == 'film':
                film_para = (
                    scFilm_strength_Var.get(),
                    scFilm_u_Var.get(),
                    scFilm_v_Var.get())
                labelImageEffectVar.set(image_effect_setting + " " + str(film_para))
                camera.image_effect_params = film_para
            elif image_effect_setting == 'watercolor':
                if cbWatercolor_uv_Var.get():
                    watercolor_para = (
                        scWatercolor_u_Var.get(),
                        scWatercolor_v_Var.get())
                    labelImageEffectVar.set(image_effect_setting + " " + str(watercolor_para))
                    camera.image_effect_params = watercolor_para
                else:
                    watercolor_para = ()
                    labelImageEffectVar.set(image_effect_setting + " " + str(watercolor_para))
                    camera.image_effect_params = watercolor_para

        if rqs == RQS_CAPTURE:
            print("Capture")
            rqs=RQS_0
            timeStamp = time.strftime("%Y%m%d-%H%M%S")
            jpgFile='img_'+timeStamp+'.jpg'
            camera.resolution = (2592, 1944)    #set photo size
            camera.capture(jpgFile)
            camera.resolution = (400, 300)      #resume preview size
            labelCapVal.set(jpgFile)
        else:
            stream = io.BytesIO()
            camera.capture(stream, format='jpeg')
            stream.seek(0)
            tmpImage = Image.open(stream)
            tmpImg = ImageTk.PhotoImage(tmpImage)
            previewPanel.configure(image = tmpImg)
            #sleep(0.5)
                
    print("Quit")        
    #camera.stop_preview()
    
def startCamHandler():
    camThread = Thread(target=camHandler)
    camThread.start()

def quit():
    global rqs
    rqs=RQS_QUIT

    global tkTop
    tkTop.destroy()

def capture():
    global rqs
    rqs = RQS_CAPTURE
    labelCapVal.set("capturing")

def cbScaleSetting(new_value):
    global rqsUpdateSetting
    rqsUpdateSetting = True

def cbButtons():
    global rqsUpdateSetting
    rqsUpdateSetting = True

tkTop = tk.Tk()
tkTop.wm_title("helloraspberrypi.blogspot.com")
tkTop.geometry('1000x650')

previewWin = tk.Toplevel(tkTop)
previewWin.title('Preview')
previewWin.geometry('400x300')
previewPanel = tk.Label(previewWin)
previewPanel.pack(side = "bottom", fill = "both", expand = "yes")

#tkButtonQuit = tk.Button(tkTop, text="Quit", command=quit).pack()

tkButtonCapture = tk.Button(
    tkTop, text="Capture", command=capture)
tkButtonCapture.pack()

SCALE_WIDTH = 980;

labelCapVal = tk.StringVar()
tk.Label(tkTop, textvariable=labelCapVal).pack()

notebook = ttk.Notebook(tkTop)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
frame3 = ttk.Frame(notebook)
notebook.add(frame1, text='Setting')
notebook.add(frame2, text='White Balance')
notebook.add(frame3, text='Image Effect')
notebook.pack()

# Tab Setting
scaleSharpness = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="sharpness",
    command=cbScaleSetting)
scaleSharpness.set(0)
scaleSharpness.pack(anchor=tk.CENTER)

scaleContrast = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="contrast",
    command=cbScaleSetting)
scaleContrast.set(0)
scaleContrast.pack(anchor=tk.CENTER)

scaleBrightness = tk.Scale(
    frame1,
    from_=0, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="brightness",
    command=cbScaleSetting)
scaleBrightness.set(50)
scaleBrightness.pack(anchor=tk.CENTER)

scaleSaturation = tk.Scale(
    frame1,
    from_=-100, to=100,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="saturation",
    command=cbScaleSetting)
scaleSaturation.set(0)
scaleSaturation.pack(anchor=tk.CENTER)

scaleExpCompensation = tk.Scale(
    frame1,
    from_=-25, to=25,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="exposure_compensation",
    command=cbScaleSetting)
scaleExpCompensation.set(0)
scaleExpCompensation.pack(anchor=tk.CENTER)

# Tab White Balance

lfAwbMode = ttk.LabelFrame(frame2, text="awb_mode")
lfAwbMode.pack(fill="x")
lfAwbGains = ttk.LabelFrame(frame2, text="awb_gains")
lfAwbGains.pack(fill="x")

labelAwbVar = tk.StringVar()
tk.Label(lfAwbMode, textvariable=labelAwbVar).pack()

#--
AWB_MODES = [
    ("off", "off"),
    ("auto", "auto"),
    ("sunlight", "sunlight"),
    ("cloudy", "cloudy"),
    ("shade", "shade"),
    ("tungsten", "tungsten"),
    ("fluorescent", "fluorescent"),
    ("incandescent", "incandescent"),
    ("flash", "flash"),
    ("horizon", "horizon"),
    ]

varAwbMode = tk.StringVar()
varAwbMode.set("auto")
for text, awbmode in AWB_MODES:
    awbModeBtns = tk.Radiobutton(
        lfAwbMode,
        text=text,
        variable=varAwbMode,
        value=awbmode,
        command=cbButtons)
    awbModeBtns.pack(anchor=tk.W)
#--
scaleGainRed = tk.Scale(
    lfAwbGains,
    from_=0.0, to=8.0,
    resolution=0.1,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="Red",
    command=cbScaleSetting)
scaleGainRed.set(0.0)
scaleGainRed.pack(anchor=tk.CENTER)

scaleGainBlue = tk.Scale(
    lfAwbGains,
    from_=0.0, to=8.0,
    resolution=0.1,
    length=SCALE_WIDTH,
    orient=tk.HORIZONTAL,
    label="Blue",
    command=cbScaleSetting)
scaleGainBlue.set(0.0)
scaleGainBlue.pack(anchor=tk.CENTER)

# Tab Image Effect
#For Image effects, ref:
#http://picamera.readthedocs.org/en/latest/api_camera.html?highlight=effect#picamera.camera.PiCamera.image_effect
labelImageEffectVar = tk.StringVar()
tk.Label(frame3, textvariable=labelImageEffectVar).pack()
#-- image_effect

varImageEffect = tk.StringVar()
varImageEffect.set('none')

lfNoParaOpts1 = ttk.Frame(frame3)
lfNoParaOpts1.pack(fill="x", expand="yes")

tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='none',value='none',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='negative',value='negative',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='sketch',value='sketch',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='denoise',value='denoise',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='emboss',value='emboss',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='oilpaint',value='oilpaint',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='hatch',value='hatch',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts1, variable=varImageEffect,
        text='gpen',value='gpen',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfNoParaOpts2 = ttk.Frame(frame3)
lfNoParaOpts2.pack(fill="x", expand="yes")
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='pastel',value='pastel',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='saturation',value='saturation',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='washedout',value='washedout',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='cartoon',value='cartoon',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace1',value='deinterlace1',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfNoParaOpts2, variable=varImageEffect,
        text='deinterlace2',value='deinterlace2',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfSolarize = ttk.LabelFrame(frame3, text="solarize")
lfSolarize.pack(fill="x", expand="yes")

tk.Radiobutton(lfSolarize, variable=varImageEffect,
        text='solarize',value='solarize',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

cbSolarize_yuv_Var = tk.BooleanVar()
tk.Checkbutton(lfSolarize, text="yuv",
    variable=cbSolarize_yuv_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_x0_Var = tk.IntVar()
scSolarize_x0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="x0",
    variable=scSolarize_x0_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y0_Var = tk.IntVar()
scSolarize_y0_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y0",
    variable=scSolarize_y0_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y1_Var = tk.IntVar()
scSolarize_y1_Var.set(128)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y1",
    variable=scSolarize_y1_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scSolarize_y2_Var = tk.IntVar()
scSolarize_y2_Var.set(0)
tk.Scale(lfSolarize, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="y2",
    variable=scSolarize_y2_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfwatercolor = ttk.LabelFrame(frame3, text="watercolor")
lfwatercolor.pack(fill="x", expand="yes")
tk.Radiobutton(lfwatercolor, variable=varImageEffect,
        text='watercolor',value='watercolor',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

cbWatercolor_uv_Var = tk.BooleanVar()
cbWatercolor_uv_Var.set(False)
tk.Checkbutton(lfwatercolor, text="uv",
    variable=cbWatercolor_uv_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scWatercolor_u_Var = tk.IntVar()
scWatercolor_u_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scWatercolor_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scWatercolor_v_Var = tk.IntVar()
scWatercolor_v_Var.set(0)
tk.Scale(lfwatercolor, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scWatercolor_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lffilm = ttk.LabelFrame(frame3, text="film")
lffilm.pack(fill="x", expand="yes")
tk.Radiobutton(lffilm, variable=varImageEffect,
        text='film',value='film',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scFilm_strength_Var = tk.IntVar()
scFilm_strength_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="strength",
    variable=scFilm_strength_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scFilm_u_Var = tk.IntVar()
scFilm_u_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="u",
    variable=scFilm_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)
scFilm_v_Var = tk.IntVar()
scFilm_v_Var.set(0)
tk.Scale(lffilm, from_=0, to=255,
    orient=tk.HORIZONTAL, length=200, label="v",
    variable=scFilm_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfblur = ttk.LabelFrame(frame3, text="blur")
lfblur.pack(fill="x", expand="yes")
tk.Radiobutton(lfblur, variable=varImageEffect,
        text='blur',value='blur',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
scBlur_size_Var = tk.IntVar()
scBlur_size_Var.set(1)
tk.Scale(lfblur, from_=1, to=2,
    orient=tk.HORIZONTAL, length=100, label="size",
    variable=scBlur_size_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfcolorswap = ttk.LabelFrame(frame3, text="colorswap")
lfcolorswap.pack(fill="x", expand="yes")
tk.Radiobutton(lfcolorswap, variable=varImageEffect,
        text='colorswap',value='colorswap',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
cbColorswap_dir_Var = tk.BooleanVar()
cbColorswap_dir_Var.set(False)
tk.Checkbutton(lfcolorswap, text="dir - 0:RGB to BGR/1:RGB to BRG",
    variable=cbColorswap_dir_Var, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfposterise = ttk.LabelFrame(frame3, text="posterise")
lfposterise.pack(fill="x", expand="yes")
tk.Radiobutton(lfposterise, variable=varImageEffect,
        text='posterise',value='posterise',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
scPosterise_steps_Var = tk.IntVar()
scPosterise_steps_Var.set(4)
tk.Scale(lfposterise, from_=2, to=32,
    orient=tk.HORIZONTAL, length=200, label="steps",
    variable=scPosterise_steps_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

lfcolorpoint = ttk.LabelFrame(frame3, text="colorpoint")
lfcolorpoint.pack(fill="x", expand="yes")
tk.Radiobutton(lfcolorpoint, variable=varImageEffect,
        text='colorpoint',value='colorpoint',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
quadrantVar = tk.IntVar()
quadrantVar.set(0)
tk.Radiobutton(lfcolorpoint, text="green",
    variable=quadrantVar, value=0, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="red/yellow",
    variable=quadrantVar, value=1, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="blue",
    variable=quadrantVar, value=2, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)
tk.Radiobutton(lfcolorpoint, text="purple",
    variable=quadrantVar, value=3, command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

lfcolorbalance = ttk.LabelFrame(frame3, text="colorbalance: I can't see the effect!")
lfcolorbalance.pack(fill="x", expand="yes")
tk.Radiobutton(lfcolorbalance, variable=varImageEffect,
        text='colorbalance',value='colorbalance',command=cbButtons).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_lens_Var = tk.DoubleVar()
scColorbalance_lens_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="lens",
    variable=scColorbalance_lens_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_r_Var = tk.DoubleVar()
scColorbalance_r_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="r",
    variable=scColorbalance_r_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_g_Var = tk.DoubleVar()
scColorbalance_g_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="g",
    variable=scColorbalance_g_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_b_Var = tk.DoubleVar()
scColorbalance_b_Var.set(1)
tk.Scale(lfcolorbalance, from_=0, to=256,
    orient=tk.HORIZONTAL, length=140, label="b",
    variable=scColorbalance_b_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_u_Var = tk.IntVar()
scColorbalance_u_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="u",
    variable=scColorbalance_u_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

scColorbalance_v_Var = tk.IntVar()
scColorbalance_v_Var.set(0)
tk.Scale(lfcolorbalance, from_=0, to=255,
    orient=tk.HORIZONTAL, length=140, label="v",
    variable=scColorbalance_v_Var, command=cbScaleSetting).pack(anchor=tk.W, side=tk.LEFT)

#=======================================
print("start")
startCamHandler()

tk.mainloop()




updated@2016-04-15:
Current Raspbian Jessie come with PIL installed by default, but no ImageTk. If you run Python script reported with error:
ImportError: cannot import name ImageTk

Install python-imaging-tk
$ sudo apt-get install python-imaging-tk



Updated@2021-03-09: