Wednesday, 16 March 2016

Heng - Sprint 2: Kivy with Camera

Author: Heng Zhen Jing
Date: 01/03/2016
Title: Sprint 2 - Kivy with Camera

Following with the last blog entry, several GUI interfaces are available but Kivy seems to be the most elegant in term of looking and user-friendly. Below is the installation of Kivy

Installation of Kivy

1.) Add APT sources for Gstreamer 1.0 in /etc/apt/sources.list:

  deb http://vontaene.de/raspbian-updates/ . main

#When you see DEB commands, go to sudo nano /etc/apt/sources.list then add the DEB command there in its entirety before executing the deb command.

2.) Add APT key for vontaene.de:

pi@raspberrypi ~ $ gpg --keyserver keyserver.ubuntu.com --recv 0C667A3E
pi@raspberrypi ~ $ gpg -a --export 0C667A3E | sudo apt-key add -

3.) Install the dependencies:

sudo apt-get update
sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
    pkg-config libgl1-mesa-dev libgles2-mesa-dev \
    python-setuptools libgstreamer1.0-dev git-core \
    gstreamer1.0-plugins-{bad,base,good,ugly} \
    gstreamer1.0-{omx,alsa} python-dev

4.) Install pip from source:

wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
sudo python get-pip.py

5.) Install Cython from sources
sudo pip install cython

6.) Build and use kivy inplace

git clone https://github.com/kivy/kivy
cd kivy

make
echo "export PYTHONPATH=$(pwd):\$PYTHONPATH" >> ~/.profile
source ~/.profile

Installation of Pillow

sudo pip install --upgrade pillow

Pillow is a Python Imaging Library that adds image processing capabilities to your Python interpreter. This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities. We would need this library to perform the command Image.open() to open the image file captured by the camera.

Implementation

Firstly, 2 buttons and 1 image file will pop out on the GUI interface. The image file is the most recent image that was captured. When user press the button "Photo", a camera screen preview will be initiated on the screen. After 5 secs, it will automatically take an image. This image is then saved, and will be shown out. This main idea can then brings in the functions such as Face Detection or Colour/Object Detection. The video below shows the successful implementation:

The following code is the modification of the following link below:
http://frederickvandenbosch.be/?p=1297

*********************************************************************************
import os, time
import kivy
import PIL

kivy.require('1.9.2') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image as kivyImage
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
from PIL import Image

# Some variables
photoPath = "/home/pi/photobooth/"
photoName = time.strftime("%Y%m%d%H%M%S") + "_photobooth.jpg"
photoResize = 512, 384

# This callback will be bound to the button:
def press_callback(obj):
        if obj.text == 'Exit':
                App.Exit()
        
# Callback function for photo button
def photo_callback(obj):
        # Define filename with timestamp
        photoName = time.strftime("%Y%m%d%H%M%S") + "_photobooth.jpg"
        # Take photo using "raspistill"
        os.system("sudo raspistill -p '144,48,512,384' --vflip -w 1920 -h 1440 -o " + photoPath + photoName)
        # Resize the high res photo to create thumbnail
        Image.open(photoPath + photoName).resize(photoResize, Image.ANTIALIAS).save(photoPath + "thumbnail.jpg")

class MyApp(App):
        # Display the latest thumbnail
        photo = kivyImage(source="/home/pi/photobooth/thumbnail.jpg")

        def build(self):
                # Set up the layout
                photobox = GridLayout(cols=3, spacing=10, padding=10)

                # Create the UI objects (and bind them to callbacks, if necessary)
                photoButton = Button(text="photo", size_hint=(.20, 1)) # Button: 20% width, 100% height
                photoButton.bind(on_press=photo_callback) # when pressed, trigger the photo_callback function
                Button3 = Button(text="Exit")
                Button3.bind(on_press=press_callback)
                
                # Periodically refresh the displayed photo using the callback function
                Clock.schedule_interval(self.callback, 1)

                # Add the UI elements to the layout
                photobox.add_widget(photoButton)
                photobox.add_widget(self.photo)
                photobox.add_widget(Button3)
                
                return photobox
            
        # Callback for thumbnail refresh
        def callback(self, instance):
                self.photo.reload()

if __name__ == '__main__':
        MyApp().run()

*********************************************************************************



No comments:

Post a Comment