Friday, 22 April 2016

Heng - Sprint 3: Integration of Kivy

Author: Heng Zhen Jing
Date: 22/04/2016
Title: Sprint 3 - Integration of Kivy

From the last sprint, a Kivy interface with buttons that enable camera screen to be pop up and take picture was successfully created. The most recent photo captured will then displayed on the interface. In this sprint, few changes have to be made to accommodate the following working conditions:

1.) Integration of Kivy into Kamil's thread. 
******************************************************************************
def init(self):
  # Put your self.registerOutput here
  self.registerOutput("Settings",Obj("face",False,"Color",False))
  appInst.tvcsSelf = self
  appInst.run()

def run(Self):

  pass
******************************************************************************
What the code above does is essentially initialize the python file where Kivy coding was written, through the main thread. With the help of Kamil and Luke, the initialization was successfully triggered by declaring appInst = MyApp(), which is the main interface of Kivy. MyApp() is then being recognized by the main system and can be run by "appInst.run()" command.


2.) Send output flags to trigger other functions. 
*******************************************************************************
# Callback function for photo button
def photo_callback(obj):
# Send output flag to trigger Face Recognition Function
appInst.tvcsSelf.output("settings",Obj("face",True,"color",False))
        # Define filename with timestamp
        photoName = "thumbnail.jpg"
        # Resize the high res photo to create thumbnail

        Image.open(photoPath + photoName).resize(photoResize, Image.ANTIALIAS).save(photoPath + "thumbnail.jpg")
*********************************************************************************
In other words, flags indicating True or False have to be sent across modules, and recognized by all the other functions. For instance, the following flags will be sent to trigger Face Recognition function.When the associated button is pressed, the above function will be called and run. The command "appInst.tvcsSelf.output("settings",Obj("face",True,"color",False))" is sending flags to indicate face = True, color = False. These flags will be recognized by both Face Recognition and Color Detection program. If the Face Recognition program detects face = True, then it will start running its work. Meanwhile, Color Detection will not run anything as the received flag is saying color = False.



3.) Import parent directory. 
*********************************************************************************
import sys
import os.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(_file_),os.path)))

import DynamicObjectV2
Obj = DynamicObjectV2.Class
********************************************************************************* 
Issue arose when the following code was added. In order for these to work, we have to run Kivy coding on CV2 environment (i.e workon cv). However, Kivy program could not run. After several debugs and tests, we had found out that Kivy and its associated library PILLOW were not being installed on CV2 environment. Therefore, by refering to the last blog post, the installation of KIVY and PILLOW were done again on CV2. Still, the program could not run, but this time with another type of error, where Kivy.require could not be recognized. The problem was finally solved by naming the Kivy.py as Kivy2.py. This is because if the python file is named Kivy, system is unable to import which Kivy, either Kivy.py or Kivy library. 


4.) After debugging and testing, the final code below is now able to run on CV2 environment, and each button pressed will send different flags, thus triggering other functions to be performed.


********************************************************************************
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/Desktop/latest/tvcs-master/photobooth/" #path to folder where images are stored
photoName = "thumbnail.jpg" #save image as thumbnail.jpg
photoResize = 512, 384 #resize to sepcific resolution


# Import from parent directory
import sys
import os.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(_file_),os.path)))

import DynamicObjectV2
Obj = DynamicObjectV2.Class


# Main interface
class MyApp(App):
        # Display the latest thumbnail
        photo = kivyImage(source="/home/pi/Desktop/latest/tvcs-master/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)
colorButton = Button(text="Color")
                colorButton.bind(on_press=color_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)
                photobox.add_widget(colorButton)

                return photobox

# Callback for thumbnail refresh
        def callback(self, instance):
                self.photo.reload()

appInst = MyApp()

# This callback will be bound to the button:
def press_callback(obj):
        if obj.text == 'Exit':
                appInst.tvcsSelf.output("EXIT KIVY")
os.kill(os.getpid(),signal.SIGINT)
        
# Callback function for photo button
def photo_callback(obj):
# Send output flag to trigger Face Recognition Function
appInst.tvcsSelf.output("settings",Obj("face",True,"color",False))
        # Define filename with timestamp
        photoName = "thumbnail.jpg"
        # Resize the high res photo to create thumbnail
        Image.open(photoPath + photoName).resize(photoResize, Image.ANTIALIAS).save(photoPath + "thumbnail.jpg")

# Callback function for color button
def color_callback(obj):
# Send output flag to trigger Face Recognition Function
appInst.tvcsSelf.output("settings",Obj("face",False,"color",True))
        # Define filename with timestamp
        photoName = "thumbnail.jpg"
        # Resize the high res photo to create thumbnail
        Image.open(photoPath + photoName).resize(photoResize, Image.ANTIALIAS).save(photoPath + "thumbnail.jpg")
            
def init(self):
# Put your self.registerOutput here
self.registerOutput("Settings",Obj("face",False,"Color",False))
appInst.tvcsSelf = self
appInst.run()

def run(Self):
pass
    

if __name__ == '__main__':

        MyApp().run()

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

Heng Zhen Jing 
entry #8

No comments:

Post a Comment