import cv2
import numpy as np
from config import datasetImageSize
import math

# Show current eyes with diff
def displayCurrentDiff(eye0, eye1, eye0previous, eye1previous, stopFrame=False):
	current = np.hstack((eye0.astype(np.uint8),eye1.astype(np.uint8)))
	last = np.hstack((eye0previous.astype(np.uint8),eye1previous.astype(np.uint8)))
	showDifference(current,last)

	# Debug frame by frame
	if stopFrame:
		cv2.waitKey(0)

#Display whole history as seen by LSTM
def displayHistoryDiffs(framesDiffHistory, fps):
	framesDiffHistoryImages = []
	for diff, _ in framesDiffHistory:
		framesDiffHistoryImages.append(getShowable(diff))

	img = None
	#Size of display square. Ex. 64 -> 8
	squareSize = int(math.sqrt(len(framesDiffHistory)))
	for rowIndex in range(squareSize):
		#Debug history
		rowImg = np.hstack(framesDiffHistoryImages[rowIndex*squareSize:rowIndex*squareSize+squareSize])
		img = np.vstack((img,rowImg)) if img is not None else rowImg

	#Write FPS on image
	cv2.putText(img,"FPS: {}".format(int(fps)),(3,9), cv2.FONT_HERSHEY_SIMPLEX, 0.3, 255)
	cv2.imshow("Frame history",img)

# Returns blank frame difference in float numpy array
def getBlankFrameDiff():
	return np.zeros((datasetImageSize,datasetImageSize)).reshape([datasetImageSize,datasetImageSize,1])

# Returns difference frame in float numpy array
def getDifferenceFrame(t1, t0):
	diff = t1.astype(float) - t0.astype(float)
	return diff

# Computes difference and returns it in a
# format good for OpenCV imshow
def getShowableDifference(t1, t0):
	diff = getDifferenceFrame(t1,t0)
	return getShowable(diff)

# Converts float diff to good OpenCV format for display
def getShowable(diff):
	diff = (diff+255.)/2.
	return diff.astype(np.uint8)

# Displays difference between frames
def showDifference(t1,t0):
	#Resize for consistency
	t0 = cv2.resize(t0,(400,400))
	t1 = cv2.resize(t1,(400,400))

	#Get displayable diff
	diff = getShowableDifference(t1,t0)

	#Resize to show better
	t0 = cv2.resize(t0,(100,100))
	t1 = cv2.resize(t1,(100,100))
	diff = cv2.resize(diff,(100,100))

	#Display
	img = np.hstack((t0,t1,diff))
	t0 = cv2.equalizeHist(t0)
	t1 = cv2.equalizeHist(t1)

	#Get displayable diff
	diff = getShowableDifference(t1,t0)

	#Resize to show better
	t0 = cv2.resize(t0,(100,100))
	t1 = cv2.resize(t1,(100,100))
	diff = cv2.resize(diff,(100,100))

	#Display
	processedImg = np.hstack((t0,t1,diff))

	cv2.imshow("Difference", np.vstack((img,processedImg)))


import datetime
import icu
from collections import defaultdict
from copy import deepcopy

from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.forms import ModelForm, CheckboxSelectMultiple, TextInput, DateInput, BooleanField, ModelMultipleChoiceField
from django.template import defaultfilters

from urnik.templatetags.tags import dan_tozilnik_mnozina
from urnik.utils import teden_dneva
from .layout import nastavi_sirine_srecanj, nastavi_barve

MIN_URA, MAX_URA = 7, 20
ENOTA_VISINE = 1 / (MAX_URA - MIN_URA)
DNEVI = ('ponedeljek', 'torek', 'sreda', 'četrtek', 'petek')
ENOTA_SIRINE = 1 / len(DNEVI)
DAYS_IN_WEEK = 7

collator = icu.Collator.createInstance(icu.Locale(settings.LANGUAGE_CODE))

class OsebaQuerySet(models.QuerySet):

    def aktivni(self):
        slusatelji = self.filter(predmeti__isnull=False)
        ucitelji = self.filter(srecanja__isnull=False)
        return (slusatelji | ucitelji).distinct()

class Oseba(models.Model):
    ime = models.CharField(max_length=192)
    priimek = models.CharField(max_length=192)
    email = models.EmailField(blank=True)
    domaca_stran = models.CharField(max_length=192, blank=True)
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='oseba')

    objects = OsebaQuerySet.as_manager()

    class Meta:
        verbose_name_plural = 'osebe'
        default_related_name = 'osebe'
        ordering = ('priimek', 'ime')

    @property
    def priimek_ime(self):
        if self.ime:
            return '{} {}'.format(self.priimek, self.ime)
        else:
            return self.priimek

    def __str__(self):
        if self.ime:
            return '{} {}'.format(self.ime, self.priimek)
        else:
            return self.priimek

    def __lt__(self, other):
        return self.vrstni_red() < other.vrstni_red()

    def vrstni_red(self):
        if self.ime:
            return (collator.getSortKey(self.priimek), collator.getSortKey(self.ime))
        else:
            return (collator.getSortKey(self.priimek), )

    def vsa_srecanja(self, semester):
        return (self.srecanja.filter(semester=semester) | semester.srecanja.filter(predmet__slusatelji=self)).distinct()

class Letnik(models.Model):
    MATEMATIKA, FIZIKA = 'M', 'F'
    ODDELEK = (
        (MATEMATIKA, 'matematika'), (FIZIKA, 'fizika'),
    )
    oddelek = models.CharField(max_length=1, choices=ODDELEK, blank=True)
    smer = models.CharField(max_length=192)
    leto = models.CharField(max_length=192, null=True)
    kratica = models.CharField(max_length=64)

    class Meta:
        verbose_name_plural = 'letniki'
        default_related_name = 'letniki'
        ordering = ('oddelek', 'smer', 'leto')

    def __str__(self):
        if self.leto:
            return '{}, {}'.format(self.smer, self.leto)
        else:
            return self.smer

    def srecanja(self, semester):
        return semester.srecanja.filter(predmet__letniki=self).distinct()

class UcilnicaQuerySet(models.QuerySet):
    VELIKOST = [
        ('majhna', 'majhna'),
        ('obicajna', 'običajna'),
        ('velika', 'velika'),
    ]

    # TODO: fix this mess
    def ustrezne(self, tip, oddelek):
        if oddelek == 'MAT':
            obicajna = Ucilnica.MATEMATICNA
        else:
            obicajna = Ucilnica.FIZIKALNA
        if tip == 'velika':
            ustrezne = self.filter(tip=obicajna, velikost__gte=60)
            alternative = self.filter(velikost__gte=45)
        elif tip == 'obicajna':
            ustrezne = self.filter(tip=obicajna, velikost__gte=30, velikost__lt=60)
            alternative = self.filter(velikost__gte=24, velikost__lt=80)
        elif tip == 'majhna':
            ustrezne = self.filter(tip=obicajna, velikost__lt=30)
            alternative = self.filter(velikost__lt=40)
        elif tip == 'racunalniska':
            ustrezne = self.filter(tip=Ucilnica.RACUNALNISKA)
            alternative = self.none()
        elif tip == 'praktikum':
            ustrezne = self.filter(tip=Ucilnica.PRAKTIKUM)
            alternative = self.none()
        else:
            ustrezne = self.none()
            alternative = self.filter(velikost__isnull=True)

        return list(ustrezne), list(alternative.exclude(pk__in=ustrezne))

    def ustrezne_velikosti(self, velikosti):
        if not velikosti:
            return self.all()
        ustrezne = self.none()
        if 'majhna' in velikosti:
            ustrezne |= self.filter(velikost__lt=30)
        if 'obicajna' in velikosti:
            ustrezne |= self.filter(velikost__gte=30, velikost__lt=60)
        if 'velika' in velikosti:
            ustrezne |= self.filter(velikost__gte=60)
        return ustrezne

    def objavljene(self):
        return self.filter(tip__in=Ucilnica.OBJAVLJENI_TIPI)

class Ucilnica(models.Model):
    MATEMATICNA, FIZIKALNA, RACUNALNISKA = 'M', 'F', 'R'
    PRAKTIKUM, PISARNA, ZUNANJA = 'P', 'K', 'X'
    TIP = (
        (MATEMATICNA, 'matematična'), (FIZIKALNA, 'fizikalna'),
        (RACUNALNISKA, 'računalniška'), (PRAKTIKUM, 'praktikum'),
        (PISARNA, 'pisarna'), (ZUNANJA, 'zunanja'),
    )
    OBJAVLJENI_TIPI = (
        MATEMATICNA,
        FIZIKALNA,
        RACUNALNISKA,
        PRAKTIKUM,
    )

    tip = models.CharField(max_length=1, choices=TIP, default=ZUNANJA, blank=True)
    oznaka = models.CharField(max_length=192, unique=True)
    kratka_oznaka = models.CharField(max_length=10, blank=True)
    velikost = models.PositiveSmallIntegerField(blank=True, null=True)
    objects = UcilnicaQuerySet.as_manager()

    class Meta:
        verbose_name_plural = 'ucilnice'
        default_related_name = 'ucilnice'
        ordering = ('oznaka',)

    def __str__(self):
        return self.oznaka

    def __lt__(self, other):
        return self.vrstni_red() < other.vrstni_red()

    def kratko_ime(self):
        if self.kratka_oznaka:
            return self.kratka_oznaka
        return self.oznaka

    def vrstni_red(self):
        return collator.getSortKey(self.oznaka)

class Predmet(models.Model):
    ime = models.CharField(max_length=192)
    kratica = models.CharField(max_length=64)
    stevilo_studentov = models.PositiveSmallIntegerField(blank=True, null=True)
    slusatelji = models.ManyToManyField('urnik.Oseba', blank=True)
    letniki = models.ManyToManyField('urnik.Letnik', blank=True)

    class Meta:
        verbose_name_plural = 'predmeti'
        default_related_name = 'predmeti'
        ordering = ('ime',)

    def __str__(self):
        return self.ime

    def __lt__(self, other):
        return self.vrstni_red() < other.vrstni_red()

    def vrstni_red(self):
        return collator.getSortKey(self.ime)

    def kratice_letnikov(self):
        return ', '.join(letnik.kratica for letnik in self.letniki.all())

class SemesterQuerySet(models.QuerySet):
    def v_obdobju(self, od, do):
        return self.filter(do__gte=od, od__lte=do)

class Semester(models.Model):
    ime = models.CharField(max_length=192)
    od = models.DateField()
    do = models.DateField()
    objavljen = models.BooleanField(default=False)

    objects = SemesterQuerySet.as_manager()

    class Meta:
        verbose_name_plural = 'semestri'
        ordering = ('od',)

    def __str__(self):
        return self.ime

    def pripravi_kopijo(self):
        novi_semester = Semester.objects.create(
            ime=self.ime + ' (kopija)',
            od=self.od + datetime.timedelta(days=365),
            do=self.do + datetime.timedelta(days=365),
            objavljen=False
        )
        for srecanje in self.srecanja.all():
            srecanje.podvoji(novi_semester=novi_semester)
        return novi_semester

    def prihodnji_tedni(self):
        razlika = datetime.timedelta(weeks=1)
        tedni = set()
        danes = datetime.date.today()
        dan = danes
        while dan < self.do:
            tedni.add(teden_dneva(dan))
            dan += razlika
        if self.do >= danes:
            tedni.add(teden_dneva(self.do))
        return tedni

class SrecanjeQuerySet(models.QuerySet):

    def odlozena(self):
        return self.filter(dan__isnull=True, ura__isnull=True).select_related('ucilnica', 'predmet').prefetch_related('ucitelji')

    def neodlozena(self):
        return self.filter(dan__isnull=False, ura__isnull=False)

    def prekrivanja(self):
        prekrivanja_ucilnic = defaultdict(set)
        prekrivanja_oseb = defaultdict(set)
        srecanja = self.neodlozena().select_related(
            'ucilnica',
        ).prefetch_related(
            'ucitelji',
            'predmet__slusatelji'
        )
        for srecanje in srecanja:
            for ura in range(srecanje.ura, srecanje.ura + srecanje.trajanje):
                for ucitelj in srecanje.ucitelji.all():
                    prekrivanja_oseb[(ucitelj, srecanje.dan, ura)].add(srecanje)
                if srecanje.predmet:
                    for slusatelj in srecanje.predmet.slusatelji.all():
                        prekrivanja_oseb[(slusatelj, srecanje.dan, ura)].add(srecanje)
                prekrivanja_ucilnic[(srecanje.ucilnica, srecanje.dan, ura)].add(srecanje)
        prekrivanja_po_tipih = {
            'Prekrivanja učilnic': prekrivanja_ucilnic,
            'Prekrivanja oseb': prekrivanja_oseb,
        }
        return {
            opis_tipa: {
                prekrivanje: srecanja
                for prekrivanje, srecanja in prekrivanja_tipa.items()
                if len(srecanja) > 1 and str(prekrivanje[0]).strip() != 'X'
            }
            for opis_tipa, prekrivanja_tipa in prekrivanja_po_tipih.items()
        }

    def urnik(self, barve=[]):
        self = self.neodlozena(
        ).order_by(
            'dan', 'ura', 'trajanje'
        ).distinct(
        ).select_related(
            'ucilnica', 'predmet'
        ).prefetch_related(
            'predmet__letniki', 'ucitelji', 'predmet__slusatelji'
        )
        nastavi_sirine_srecanj(self)
        nastavi_barve(self, barve)
        return self

class Termin(object):
    def __init__(self, dan, ura):
        self.dan = dan
        self.ura = ura

    def style(self):
        left = (self.dan - 1) * ENOTA_SIRINE
        top = (self.ura - MIN_URA) * ENOTA_VISINE
        height = ENOTA_VISINE
        width = ENOTA_SIRINE
        return 'position: absolute; left: {:.2%}; width: {:.2%}; top: {:.2%}; height: {:.2%};'.format(left, width, top, height)

class TerminUrejanje(Termin):
    ZASEDEN = 'zaseden'

    def __init__(self, dan, ura, ustrezne, alternative, zasedenost_ucilnic, srecanje):
        super().__init__(dan, ura)
        self.ucilnice = []
        self.zasedenost = self.ZASEDEN
        ure = range(self.ura, self.ura + srecanje.trajanje)
        proste_ustrezne = False
        deloma_proste_ustrezne = False
        proste_alternative = False
        deloma_alternative = False

        for ucilnica in alternative:
            ucilnica = deepcopy(ucilnica)
            ucilnica.ustreznost = 'alternativa'
            self.ucilnice.append(ucilnica)
        for ucilnica in ustrezne:
            ucilnica = deepcopy(ucilnica)
            ucilnica.ustreznost = 'ustrezna'
            self.ucilnice.append(ucilnica)
        self.ucilnice.sort()

        def prosta(zasedenost_ucilnic, ucilnica, dan, ura):
            return ucilnica not in zasedenost_ucilnic.get((dan, ura), [])

        for ucilnica in self.ucilnice:
            if all(prosta(zasedenost_ucilnic, ucilnica, dan, ura) for ura in ure):
                ucilnica.zasedenost = 'prosta'
                if ucilnica.ustreznost == 'ustrezna':
                    proste_ustrezne = True
                else:
                    proste_alternative = True
            elif any(prosta(zasedenost_ucilnic, ucilnica, dan, ura) for ura in ure):
                ucilnica.zasedenost = 'deloma_prosta'
                if ucilnica.ustreznost == 'ustrezna':
                    deloma_proste_ustrezne = True
                else:
                    deloma_alternative = True
            else:
                ucilnica.zasedenost = 'zasedena'

        if proste_ustrezne:
            self.zasedenost = 'prosto'
        elif deloma_proste_ustrezne and proste_alternative:
            self.zasedenost = 'proste_le_alternative'
        elif deloma_proste_ustrezne:
            self.zasedenost = 'deloma'
        elif proste_alternative:
            self.zasedenost = 'proste_alternative'
        elif deloma_alternative:
            self.zasedenost = 'deloma_proste_alternative'

class Srecanje(models.Model):
    PREDAVANJA, SEMINAR, VAJE, LABORATORIJSKE_VAJE = 'P', 'S', 'V', 'L'
    TIP = (
        (PREDAVANJA, 'predavanja'), (SEMINAR, 'seminar'),
        (VAJE, 'vaje'), (LABORATORIJSKE_VAJE, 'laboratorijske vaje'),
    )
    semester = models.ForeignKey('urnik.Semester', on_delete=models.PROTECT)
    predmet = models.ForeignKey('urnik.Predmet', null=True, blank=True, on_delete=models.SET_NULL)
    tip = models.CharField(max_length=1, choices=TIP, blank=True)
    oznaka = models.CharField(max_length=64, blank=True)
    ucitelji = models.ManyToManyField('urnik.Oseba', blank=True)
    dan = models.PositiveSmallIntegerField(choices=enumerate(DNEVI, 1), blank=True, null=True)
    ura = models.PositiveSmallIntegerField(blank=True, null=True)
    trajanje = models.PositiveSmallIntegerField(null=True)
    ucilnica = models.ForeignKey('urnik.Ucilnica', null=True, blank=True, on_delete=models.SET_NULL)
    objects = SrecanjeQuerySet.as_manager()

    class Meta:
        verbose_name_plural = 'srečanja'
        default_related_name = 'srecanja'
        ordering = ('predmet', 'tip', 'oznaka', 'dan', 'ura', 'trajanje')

    def __str__(self):
        if self.dan and self.ura:
            return '{}, {}{}, {}, {}, {}–{}, {}'.format(
                self.predmet, self.tip, self.oznaka, ', '.join(str(ucitelj) for ucitelj in self.ucitelji.all()),
                self.get_dan_display(), self.ura, self.ura + self.trajanje,
                self.ucilnica
            )
        else:
            return '{}, {}{}, {}, odloženo, {}'.format(
                self.predmet, self.tip, self.oznaka, ', '.join(str(ucitelj) for ucitelj in self.ucitelji.all()),
                self.ucilnica
            )

    @property
    def od(self):
        return self.ura

    @property
    def do(self):
        if self.ura:
            return self.ura + self.trajanje

    def se_po_urah_prekriva(self, od, do):
        return self.od < do and od < self.do

    def podvoji(self, novi_semester=None):
        stari_ucitelji = list(self.ucitelji.all())
        self.id = None
        if novi_semester is not None:
            self.semester = novi_semester
        self.save()
        for ucitelj in stari_ucitelji:
            self.ucitelji.add(ucitelj)

    def odlozi(self):
        self.dan = None
        self.ura = None
        self.save()

    def nastavi_trajanje(self, trajanje):
        self.trajanje = trajanje
        self.save()

    def premakni(self, dan, ura, ucilnica):
        self.dan = dan
        self.ura = ura
        self.ucilnica = ucilnica
        self.save()

    def lahko_skrajsam(self):
        return self.trajanje > 1

    def lahko_podaljsam(self):
        return not self.ura or self.do < MAX_URA

    def lahko_odlozim(self):
        return self.dan and self.ura

    def po_potrebi_okrajsano_ime_predmeta(self):
        if hasattr(self, 'sirina') and ((self.sirina >= 0.5 and len(self.predmet.ime) < 45 and self.trajanje > 1) or self.sirina == 1):
            return self.predmet.ime
        else:
            return self.predmet.kratica

    def povezana_srecanja(self):
        srecanja = self.semester.srecanja
        letniki_poslusajo = srecanja.filter(predmet__letniki__in=self.predmet.letniki.all())
        ucitelj_uci = srecanja.filter(ucitelji__in=self.ucitelji.all())
        ucitelj_poslusa = srecanja.filter(predmet__slusatelji__in=self.ucitelji.all())
        return (letniki_poslusajo | ucitelj_uci | ucitelj_poslusa).exclude(
            pk=self.pk
        ).distinct()

    def style(self):
        if self.dan and self.ura and hasattr(self, 'sirina'):
            left = (self.dan - 1 + self.zamik) * ENOTA_SIRINE
            top = (self.ura - MIN_URA) * ENOTA_VISINE
            height = self.trajanje * ENOTA_VISINE
            width = self.sirina * ENOTA_SIRINE
            return 'left: {:.2%}; width: {:.2%}; top: {:.2%}; height: {:.2%};'.format(
                left, width, top, height)
        else:
            return ''

    def css_classes(self):
        classes = []
        if hasattr(self, 'leftmost') and self.leftmost: classes.append('leftmost')
        if hasattr(self, 'rightmost') and self.rightmost: classes.append('rightmost')
        return ' '.join(classes)

    def prosti_termini(self, tip, oddelek):
        ustrezne, alternative = Ucilnica.objects.ustrezne(tip=tip, oddelek=oddelek)
        if self.ucilnica not in ustrezne and self.ucilnica not in alternative:
            ustrezne.insert(0, self.ucilnica)

        zasedenost_ucilnic = defaultdict(set)
        for srecanje in self.semester.srecanja.neodlozena().filter(ucilnica__in=ustrezne + alternative).exclude(pk=self.pk).select_related('ucilnica'):
            for ura in range(srecanje.ura, srecanje.ura + srecanje.trajanje):
                zasedenost_ucilnic[(srecanje.dan, ura)].add(srecanje.ucilnica)

        termini = {}
        for dan in range(1, 6):
            for ura in range(MIN_URA, MAX_URA - self.trajanje + 1):
                termini[(dan, ura)] = TerminUrejanje(
                    dan=dan,
                    ura=ura,
                    ustrezne=ustrezne,
                    alternative=alternative,
                    zasedenost_ucilnic=zasedenost_ucilnic,
                    srecanje=self,
                )
        return termini

    def dnevi_med(self, od, do):
        od = max(od, self.semester.od)
        dan = od + datetime.timedelta((self.dan - (od.weekday()+1)) % DAYS_IN_WEEK)
        assert dan.weekday() + 1 == self.dan, "Ups."
        dan_konca = min(self.semester.do, do)
        razlika = datetime.timedelta(weeks=1)
        while dan <= dan_konca:
            yield dan
            dan += razlika

class RezervacijaQuerySet(models.QuerySet):

    def v_tednu(self, ponedeljek):
        nedelja = ponedeljek + datetime.timedelta(days=6)
        return self.filter(
            dan_konca__isnull=True,
            dan__gte=ponedeljek,
            dan__lte=nedelja,
        ) | self.filter(
            dan_konca__isnull=False,
            dan__lte=nedelja,
        ).exclude(
            dan_konca__lt=ponedeljek,
        )

    def prihajajoce(self):
        return self.filter(dan__gte=datetime.date.today()) | self.filter(dan_konca__gte=datetime.date.today())

class Rezervacija(models.Model):
    ucilnice = models.ManyToManyField('urnik.Ucilnica', blank=False,
                                      limit_choices_to={'tip__in': Ucilnica.OBJAVLJENI_TIPI}, verbose_name='Učilnice')
    osebe = models.ManyToManyField('urnik.Oseba', verbose_name='Osebe')
    dan = models.DateField(verbose_name='Dan začetka', blank=False, null=False, help_text='Za kateri dan želite rezervirati')
    dan_konca = models.DateField(blank=True, null=True, verbose_name='Dan konca', help_text='Dan konca rezervacije; izpolnite le, če je drugačen od začetka')
    MOZNE_URE = tuple((u, str(u)+":00") for u in range(MIN_URA, MAX_URA+1))
    od = models.PositiveSmallIntegerField(blank=False, null=False, choices=MOZNE_URE, help_text='Od katere ure želite rezervirati')
    do = models.PositiveSmallIntegerField(blank=False, null=False, choices=MOZNE_URE, help_text='Do katere ure želite rezervirati')
    opomba = models.CharField(max_length=192, blank=False, null=False, help_text='Razlog za rezervacijo')
    potrjena = models.BooleanField(default=False, null=False, help_text='Ali so to rezervacijo potrdili posvečeni ljudje')
    avtor_rezervacije = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, help_text='Kdo je dejansko naredil rezervacijo', on_delete=models.CASCADE)
    cas_rezervacije = models.DateTimeField(auto_now_add=True, help_text="Datum in čas, ko je bila rezervacija narejena", verbose_name='Datum in čas rezervacije')

    objects = RezervacijaQuerySet.as_manager()

    @property
    def zacetek(self):
        return self.dan

    @property
    def konec(self):
        return self.dan_konca or self.dan

    def __str__(self):
        if self.dan_konca:
            return "Rezervacija od {} do {}, {}–{} za {}".format(self.zacetek, self.konec, self.od, self.do, self.opomba)
        else:
            return "Rezervacija dne {}, {}–{} za {}".format(self.zacetek, self.od, self.do, self.opomba)

    class Meta:
        verbose_name_plural = 'rezervacije'
        default_related_name = 'rezervacije'
        ordering = ('dan', 'od', 'do')

    def dnevi(self):
        return self.dnevi_med(self.zacetek, self.konec)

    def prihajajoci_dnevi(self):
        return self.dnevi_med(datetime.date.today(), self.konec)

    def dnevi_med(self, od, do):
        dan = max(self.zacetek, od)
        dan_konca = min(self.konec, do)
        razlika = datetime.timedelta(days=1)
        while dan <= dan_konca:
            yield dan
            dan += razlika

    def se_po_urah_prekriva(self, od, do):
        return self.od < do and od < self.do

class RezervacijeModelMultipleChoiceField(ModelMultipleChoiceField):
    def __init__(self, *args, **kwargs):
        ModelMultipleChoiceField.__init__(self, *args, **kwargs)
        it = self.iterator(self)
        self.choices = [it.choice(obj) for obj in sorted(self.queryset)]

class OsebeModelMultipleChoiceField(RezervacijeModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.priimek_ime

class UcilniceModelMultipleChoiceField(RezervacijeModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.oznaka

class RezevacijeForm(ModelForm):

    PREKRIVANJA = 'prekrivanja'

    osebe = OsebeModelMultipleChoiceField(queryset=Oseba.objects.all(),
                                          help_text='Osebe, ki si lastijo to rezervacijo')
    ucilnice = UcilniceModelMultipleChoiceField(queryset=Ucilnica.objects.objavljene(),
                                                help_text='Izberite učilnice, ki jih želite rezervirati',
                                                widget=CheckboxSelectMultiple())
    use_required_attribute = False

    class Meta:
        model = Rezervacija
        fields = ['ucilnice', 'osebe', 'dan', 'dan_konca', 'od', 'do', 'opomba']
        widgets = {
            'dan': DateInput(attrs={'placeholder': 'npr. 15. 1. 2019', 'class': 'datepicker'}),
            'dan_konca': DateInput(attrs={'placeholder': 'ponavadi prazno, lahko tudi npr. 17. 1. 2019', 'class': 'datepicker'}),
            'opomba': TextInput(attrs={'placeholder': 'npr. izpit Analiza 1 FIN'}),
        }

    def __init__(self, *args, **kwargs):
        dovoli_prekrivanja = kwargs.pop('dovoli_prekrivanja', None)
        super(RezevacijeForm, self).__init__(*args, **kwargs)
        if dovoli_prekrivanja:
            self.fields['ignoriraj_prekrivanja'] = BooleanField(
                required=False, initial=False,
                help_text='Zavedam se prekrivanj in vseeno želim rezervirati izbrane učilnice '
                          'v izbranih dnevih in urah.')

    def clean_dan(self):
        dan = self.cleaned_data['dan']
        if dan < datetime.date.today():
            raise ValidationError("Datum rezervacije mora biti v prihodnosti.")
        return dan

    def clean(self):
        cleaned = super().clean()
        if self.errors:
            return cleaned

        od = cleaned.get('od')
        do = cleaned.get('do')
        if od >= do:
            self.add_error(None, ValidationError("Ura začetka rezervacije mora biti pred uro konca rezervacije."))

        dan = cleaned.get('dan')
        konec = cleaned.get('dan_konca')
        if konec:
            if dan == konec:
                self.cleaned_data['dan_konca'] = None
            elif dan > konec:
                self.add_error(None, ValidationError("Dan začetka rezervacije moda biti "
                                                     "pred dnevom konca rezervacije."))
        ignoriraj = cleaned.get('ignoriraj_prekrivanja')
        if not ignoriraj:
            self._preveri_konflikte(cleaned)

        return self.cleaned_data

    def _preveri_konflikte(self, cleaned):
        from urnik.iskanik_konfliktov import IskalnikKonfliktov
        ucilnice = cleaned.get('ucilnice')
        dan = cleaned.get('dan')
        konec = cleaned.get('dan_konca') or dan
        od = cleaned.get('od')
        do = cleaned.get('do')
        iskalnik = IskalnikKonfliktov(ucilnice, dan, konec)
        iskalnik.dodaj_srecanja()
        iskalnik.dodaj_rezervacije(Rezervacija.objects.prihajajoce())

        date_format = lambda d: defaultfilters.date(d, "D, j. b")
        for u in ucilnice:
            d = dan
            while d <= konec:
                konflikti = iskalnik.konflikti(u, d, od, do)
                for r in konflikti.rezervacije:
                    oseba = r.osebe.all()[:1]
                    self.add_error(None, ValidationError(
                        'Vaša rezervacija bi se prekrivala z rezervacijo osebe %(oseba)s %(dan)s '
                        'od %(od)i do %(do)i z razlogom %(razlog)s.',
                        params={
                            'oseba': oseba[0] if oseba else 'neznan',
                            'dan': "od {} do {}".format(date_format(r.dan), date_format(r.dan_konca))
                            if r.dan_konca else "dne {}".format(date_format(r.dan)),
                            'razlog': r.opomba,
                            'od': r.od,
                            'do': r.do,
                        },
                        code=RezevacijeForm.PREKRIVANJA,
                    ))

                for s in konflikti.srecanja:
                    self.add_error(None, ValidationError(
                        'Vaša rezervacija bi se prekrivala s predmetom %(predmet)s (%(semester)s), ki se izvaja '
                        'ob %(dan_v_tednu)s od %(od)i do %(do)i.',
                        params={
                            'predmet': s.predmet,
                            'semester': s.semester,
                            'dan_v_tednu': dan_tozilnik_mnozina(s.dan),
                            'od': s.od,
                            'do': s.do,
                        },
                        code=RezevacijeForm.PREKRIVANJA,
                    ))

                d += datetime.timedelta(days=1)


# Copyright 2017 John Carr
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import datetime

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.x509.oid import NameOID

def get_selfsigned_certificate(store, private_key):
    if store.has_certificate('selfsigned'):
        return store.get_certificate('selfsigned')

    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, "DOCKER-ENROLLMENT"),
    ])

    backend = default_backend()

    cert = x509.CertificateBuilder().\
        subject_name(subject).\
        issuer_name(issuer).\
        public_key(private_key.public_key()).\
        serial_number(x509.random_serial_number()).\
        not_valid_before(datetime.datetime.utcnow()).\
        not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=10)).\
        add_extension(
            x509.SubjectAlternativeName([x509.DNSName('localhost')]),
            critical=False
        ).\
        sign(private_key, hashes.SHA256(), backend)

    store.set_certificate('selfsigned', cert)

    return cert


""" This module defines serializers for recipe models """

from chezcosa.recipes.models import Recipe
from rest_framework import serializers

# pylint: disable=too-few-public-methods
class RecipeSerializer(serializers.HyperlinkedModelSerializer):
    """ This class defines the serializer for the recipe model """

    # pylint: disable=too-few-public-methods
    class Meta:
        """ This class lists the fields of the model that should be part of the
        view
        """

        model = Recipe
        fields = (
            'url', 'user', 'created', 'title', 'category', 'ingredients',
            'comment', 'image_url', 'thumb_url'
        )


#!/usr/bin/env python3
from moviepy.editor import VideoFileClip
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2
import os
import math

"""
test images: 960x540
challenge: 1280x738
"""

def display_lines_on_image(lines,image):
    # Iterate over the output line structures and draw lines on a blank image
    line_image = np.copy(image)*0 # creating a blank to draw lines on
    for line in lines:
        cv2.line(line_image,(int(line.x1),int(line.y1)),(int(line.x2),int(line.y2)),(255,0,0),10)

    # Draw the lines on the edge image
    lines_edges = cv2.addWeighted(image, 0.8, line_image, 1, 0)
    return lines_edges

def display_raw_lines_on_image(lines,image):
    # Iterate over the output "lines" and draw lines on a blank image
    line_image = np.copy(image)*0 # creating a blank to draw lines on
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)

    # Draw the lines on the edge image
    lines_edges = cv2.addWeighted(image, 0.8, line_image, 1, 0)
    return lines_edges

def l2norm(values):
    return math.sqrt(sum([v**2 for v in values]))

def mix(a,b,ratio_a):
    return a*ratio_a + b*(1-ratio_a)

class Line:
    """
    Store the representation of a line as segment coordinates, direction vector, mean position, length and score
    Provides merging functionalities, extrapolation
    """

    def __init__(self,x1,y1,x2,y2):
        self.x1 = float(x1)
        self.y1 = float(y1)
        self.x2 = float(x2)
        self.y2 = float(y2)
        self.compute_from_coordinates()

    def reorient_coordinates(self):
        """
        Force y1 to be minimum and y2 maximum
        """
        if self.y1 > self.y2:
            self.x2,self.x1 = self.x1,self.x2
            self.y2,self.y1 = self.y1,self.y2

    def compute_from_coordinates(self):
        """
        Recompute line properties from its segment coordinates
        """
        self.reorient_coordinates()
        self.vector = [self.x2 - self.x1 , self.y2 - self.y1]
        self.length = l2norm(self.vector)
        self.angle = math.atan2(self.vector[1],self.vector[0])
        self.x = (self.x1+self.x2)/2
        self.y = (self.y1+self.y2)/2
        self.score = self.length

    def get_x_given_y(self,y):
        """
        Compute X coordinate for a given Y coordinate based on mean position and vector
        """
        if self.vector[1]==0:
            dy = 0
        else:
            dy = (y - self.y) / self.vector[1]
        dx = dy * self.vector[0]
        x = self.x + dx
        return x

    def merge(self,line):
        """
        Merge current line with another one based on score
        """

        # Compute weight of each line based on respective scores
        rself = self.score / (self.score+line.score)

        # Compute coordinates of merged line (minimum and maximum Y, extrapolate for X, mix with ratio)
        min_y = min(self.y1,line.y1)
        max_y = max(self.y2,line.y2)
        sx1 = self.get_x_given_y(min_y)
        lx1 = line.get_x_given_y(min_y)
        sx2 = self.get_x_given_y(max_y)
        lx2 = line.get_x_given_y(max_y)
        self.y1 = min_y
        self.y2 = max_y
        self.x1 = mix(sx1,lx1,rself)
        self.x2 = mix(sx2,lx2,rself)

        # Recompute new line, new score is sum of both lines scores
        score = self.score + line.score
        self.compute_from_coordinates()
        self.score = score

    def __str__(self):
        return "%s length %f angle %f score %f"%(str(self.vector),self.length,self.angle,self.score)

def get_angle_difference(a1,a2):
    """
    Return smallest angle difference
    """
    a = a1 - a2
    while a>math.pi: a-=math.pi*2
    while a<-math.pi: a+=math.pi*2
    return a

def are_lines_similar(l1,l2):
    # Check angular difference is not too large
    delta_angle = get_angle_difference(l1.angle,l2.angle)
    if abs(delta_angle) > 0.1:
        return False

    # Check horizatonal distance at mean Y coordinates is not too large
    avgy = (l1.y + l2.y) / 2
    x1 = l1.get_x_given_y(avgy)
    x2 = l2.get_x_given_y(avgy)
    if abs(x1-x2)>25:
        return False
    return True

class LanesFinder:
    """
    Analyses successive frames to detect lanes and display them
    """

    def __init__(self):
        self.initialized = False

    def process_image(self,image):
        """
        Process a frame and return the image with detected lanes drawn on it
        """

        # On first frame, compute image sizes and region of interest (as ratio of sizes)
        if not self.initialized:
            self.last_lines = []
            self.ysize = image.shape[0]
            self.xsize = image.shape[1]
            self.yregion = int(self.ysize*0.60)
            self.xregion_left = int(self.xsize*0.47)
            self.xregion_right = int(self.xsize*0.53)
            self.initialized = True

        # Extract raw lines
        lines , edges = self.find_lines_on_image(image)

        # Compute lane lines
        plines = self.group_lines(lines)

        # Draw lines on image
        result_image = display_lines_on_image(plines,image)

        return result_image

    def find_lines_on_image(self,image):
        """
        Extract raw lines on image (gaussian smoothing + canny + polygon mask +  hough)
        Parameters are more or less same as exercices
        """

        # Convert to gray
        gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)

        # Define a kernel size and apply Gaussian smoothing
        kernel_size = 5
        blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)

        # Define our parameters for Canny and apply
        low_threshold = 50
        high_threshold = 150
        edges = cv2.Canny(blur_gray, low_threshold, high_threshold)

        # Next we'll create a masked edges image using cv2.fillPoly()
        mask = np.zeros_like(edges)
        ignore_mask_color = 255

        # This time we are defining a four sided polygon to mask
        imshape = image.shape
        vertices = np.array([[(0,self.ysize),(self.xregion_left, self.yregion), (self.xregion_right, self.yregion), (self.xsize,self.ysize)]], dtype=np.int32)
        cv2.fillPoly(mask, vertices, ignore_mask_color)
        masked_edges = cv2.bitwise_and(edges, mask)

        # Define the Hough transform parameters
        # Make a blank the same size as our image to draw on
        rho = 2 # distance resolution in pixels of the Hough grid
        theta = np.pi/90 # angular resolution in radians of the Hough grid
        threshold = 15     # minimum number of votes (intersections in Hough grid cell)
        min_line_length = 40 #minimum number of pixels making up a line
        max_line_gap = 20    # maximum gap in pixels between connectable line segments

        # Run Hough on edge detected image
        # Output "lines" is an array containing endpoints of detected line segments
        lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
                                    min_line_length, max_line_gap)

        return lines,edges

    def group_lines(self,lines):
        """
        Process all raw lines and try to merge them together and with previously identified lanes
        """

        # Transform relevant raw lines to Line instances
        plines = []
        for line in lines:
            for x1,y1,x2,y2 in line:
                l = Line(x1,y1,x2,y2)
                # Filter out lines with angles out of relevant ranges
                if l.angle>math.pi/3 and l.angle<2*math.pi/3:
                    continue
                if l.angle<math.pi/8 or l.angle>7*math.pi/8:
                    continue
                plines.append(l)

        # Initialize groups with previously found lanes
        groups = self.last_lines

        # Process all lines and merge to existing groups or add them as new groups
        # print("\nLines")
        for l in plines:
            # print(l)
            for g in groups:
                if are_lines_similar(l,g):
                    g.merge(l)
                    break
            else:
                groups.append(l)

        # Sort by reverse score and keep best two detections
        groups = sorted(groups,reverse=True,key=lambda v:v.score)
        # print ("\nGroups")
        # for l in groups:
            # print (l)
        if len(groups)>2:
            groups = groups[:2]

        # Force high score in selected lanes for merging at next frame (similar to a moving average)
        for l in groups:
            l.score = 2000
        self.last_lines = groups

        return groups

if __name__=="__main__":
    # Process all images
    for img_file in os.listdir("test_images"):
        lanes_finder = LanesFinder()
        image = mpimg.imread("test_images/"+img_file)
        result_image = lanes_finder.process_image(image)
        #mpimg.imsave("test_images_output/"+img_file,result_image)

    # Process all videos
    for video_file in os.listdir("test_videos"):
        lanes_finder = LanesFinder()
        input_file = "test_videos/"+video_file
        output_file = "test_videos_output/"+video_file
        input_clip = VideoFileClip(input_file)
        output_clip = input_clip.fl_image(lanes_finder.process_image)
        output_clip.write_videofile(output_file, audio=False)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : nn_module.py
# @Author: Gavin
# @Date  : 2018/10/25
# @Desc  :
from torch.autograd import Variable
import torch
from torch import nn

class RNN(nn.Module):
    """
    lstm模型
    """

    def __init__(self, input_size, hidden_size, num_layers):
        super(RNN, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.h_state = None

        self.rnn = nn.LSTM(
            input_size=self.input_size,
            hidden_size=self.hidden_size,
            num_layers=self.num_layers,
            batch_first=True,
        )
        self.out = nn.Linear(hidden_size, 1)

    def forward(self, x, h_state):
        r_out, h_state = self.rnn(x, h_state)

        '''outs = []  # save all predictions
        for time_step in range(r_out.size(1)):  # calculate output for each time step
            outs.append(self.out(r_out[:, time_step, :]))'''
        # outs.append(self.out(r_out[:, -1, :]))
        #return torch.stack(outs, dim=1), h_state
        out = self.out(r_out)
        return out, h_state

def repackage_h_state(h):
    """
    隐藏层解包
    :param h:
    :return:
    """
    if type(h) is torch.Tensor:
        return Variable(h.data)
    else:
        return tuple(repackage_h_state(i) for i in h)


from django.shortcuts import render, HttpResponse, redirect
from mainApp.models import Distributor, Retailer, Company, CompanyProducts
from django.db import IntegrityError
# Create your views here.
def distributorAuthenticated(function):

    def wrap(request, *args, **kwargs):
        #try:
        if request.session['user']:
            distributor = Distributor.objects.filter(id=kwargs['distributor_id']).first()
            if distributor:
                if distributor.email == request.session['user']:
                    return function(request, *args, **kwargs)
                else:
                    return render(request,'general/404.html',{})
            else:
                return render(request,'general/404.html',{})
        else:
            return redirect('mainApp:login')
        # except:
        #     return redirect('mainApp:login')
    return wrap

@distributorAuthenticated
def distributor_edit(request,distributor_id):
    if request.method=='GET':
        distributor = Distributor.objects.filter(id=distributor_id).first()

        return render(request,'distributor/distributor_edit.html',{
            "data":distributor
        })
    else:
        data = request.POST.dict()
        print(data)
        del data['csrfmiddlewaretoken']
        distributor = Distributor.objects.filter(id=distributor_id)
        try:
            distributor.update(
                **data
            )
        except IntegrityError as e:
            messages = {}
            messages['gst'] = "GST number must be unique."
            return render(request,"distributor/distributor_edit.html",{
                "data":data,
                "messages":messages,
            })

        return render(request,"distributor/distributor_edit.html",{
                "data":data,
                "success":True,
            })

@distributorAuthenticated
def distributor_retailers(request,distributor_id):
    if request.method=='GET':
        distributor = Distributor.objects.filter(id=distributor_id).first()
        associated_retailers = distributor.distributor_retailers.all()
        non_associated_retailers = Retailer.objects.exclude(id__in=associated_retailers)
        return render(request,'distributor/distributor_retailers.html',{
            "associated_retailers":associated_retailers,
            "non_associated_retailers":non_associated_retailers,
            "distributor":distributor
        })
    else:
        data = request.POST
        print(data)
        retailer_id = int(data.get("add_retailer_id"))
        retailer = Retailer.objects.get(id=retailer_id)
        distributor = Distributor.objects.filter(id=distributor_id).first()
        distributor.distributor_retailers.add(retailer)
        return redirect('distributor:distributor_retailers',distributor_id=distributor_id)

@distributorAuthenticated
def distributor_retailer_remove(request,distributor_id,retailer_id):
    distributor = Distributor.objects.filter(id=distributor_id).first()
    retailer = Retailer.objects.get(id=retailer_id)
    distributor.distributor_retailers.remove(retailer)
    return redirect('distributor:distributor_retailers',distributor_id=distributor_id)

@distributorAuthenticated
def distributor_companies(request,distributor_id):
    distributor = Distributor.objects.get(id=distributor_id)
    distributor_companies = distributor.company_set.all()
    return render(request,'distributor/distributor_companies.html',{
        "associated_companies":distributor_companies,
        "distributor":distributor,
    })


import sqlite3

INIT_DB = [
	"""
	CREATE TABLE `Task` (
		`id`	INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
		`title`	TEXT NOT NULL,
		`created`	TEXT NOT NULL DEFAULT (datetime('now')),
		`deadline`	TEXT,
		`start`	TEXT NOT NULL DEFAULT (datetime('now')),
		`priority`	INTEGER NOT NULL DEFAULT 1,
		`done`	TEXT,
		`context`	INTEGER NOT NULL REFERENCES Context(id) ON DELETE CASCADE
	);
	""",
	"""
	CREATE TABLE `Context` (
		`id`	INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
		`path`	TEXT NOT NULL UNIQUE,
		`priority`	INTEGER NOT NULL DEFAULT 1,
		`visibility`	TEXT NOT NULL DEFAULT 'normal'
	);
	""",
	"""
	INSERT INTO `Context` (path) VALUES ('')
	""",
	"""
	CREATE INDEX `PathIndex` ON `Context` (`path` ASC);
	"""
]

def main():
	conn = sqlite3.connect('data.sqlite')
	for stmt in INIT_DB:
		conn.execute(stmt)

if __name__ == '__main__':
	main()


from tkinter import *
from tkinter import messagebox as tm
import datetime
import time
import os
import sqlite3
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using :0.0')
    os.environ.__setitem__('DISPLAY', ':0.0')

#connecting database
conn=sqlite3.connect("Library_System.db")
c=conn.cursor()

#creating new window
root=Tk()
root.geometry("800x800")
root.title("RETURN BOOKS")

#adding background image
log_label = Label(height=800, width=800)
image21 = PhotoImage(file="ret1.gif")
log_label.config(image=image21)
log_label.image = image21
log_label.place(x=0, y=0)

localtime=time.asctime(time.localtime(time.time()))
today=datetime.date.today()    #to get system's current date

lblinfo = Label(root,font=('Times new roman' ,30, 'bold' ),text="Library Management System",fg="Red",bg="cyan",bd=10,anchor='w')
lblinfo.place(x=150,y=10)
lblinfo = Label(font=('Arial' ,20),text=localtime,fg="steel blue",anchor=W,bg="cyan")
lblinfo.place(x=220,y=70)
lblinfo = Label(font=( 'Times new roman' ,20, 'bold','italic','underline' ),text="RETURN BOOKS",bg="cyan",fg="Red",bd=10,anchor='w')
lblinfo.place(x=250,y=120)

#labels
label_rollno = Label( text="Roll No",fg="red",font=("Arial ", 20))
select_dept=Label(text="Select Department",fg='red',font=("Arial",20))
label_bookid = Label( text="Book ID",fg="red",font=("Arial ", 20))
label_issuedate = Label( text="Issue Date",fg="red",font=("Arial ", 20))
label_returndate = Label( text="Return Date",fg="red",font=("Arial ", 20))

#textbox
entry_rollno = Entry(width=20,font=('Times',20))
entry_bookid = Entry(width=20,font=('Times',20))

label_rollno.place(x=120,y=200)
select_dept.place(x=120,y=250)
label_bookid.place(x=120,y=300)
label_issuedate.place(x=120,y=350)
label_returndate.place(x=120,y=400)

entry_rollno.place(x=370,y=200)
entry_bookid.place(x=370,y=300)

#to show department of student with entered roll no
def _view_():
    global bid1
    bid1 = []
    data = c.execute("SELECT Dept_Name FROM Student WHERE Roll_No=?",[entry_rollno.get()])
    for i in data:
        bid1.extend(i)
    global dep
    dep = Label(text=bid1[0],font=('Times', 20))
    dep.place(x=370, y=250)

def _view1_():
    #to check if book with entered book id is present
    bid = []
    data = c.execute("SELECT Book_ID FROM Books")
    for i in data:
        bid.extend(i)
    found = 0
    for i in bid:
        if entry_bookid.get() in bid:
            found=1
            global dates
            global dates1

            #to get issue date from books_issued table
            dates=[]
            q="SELECT Issue_Date From Books_Issued WHERE (Roll_No=? and Book_ID=?)"
            b=c.execute(q,[entry_rollno.get(),entry_bookid.get()])
            for i in b:
                dates.extend(i)

            #to get actual return date from books_issued table
            dates1=[]
            q1 = "SELECT Return_Date From Books_Issued WHERE (Roll_No=? and Book_ID=?)"
            b1 = c.execute(q1, [entry_rollno.get(), entry_bookid.get()])
            for i in b1:
                dates1.extend(i)

            #labels
            entry_issuedate = Label(text=dates[0], font=('Times', 20))
            entry_returndate = Label(text=dates1[0], font=('Times', 20))
            entry_issuedate.place(x=370, y=350)
            entry_returndate.place(x=370, y=400)

            #to find difference between actual return date from table and current date
            rd=datetime.datetime.strptime(dates1[0],"%Y-%m-%d")
            difference = today - rd.date()
            global fine_pay
            #if current date is greater or equal to return date from table
            if difference.days>=0:
                sel="SELECT Fine from Student WHERE Roll_No=?"
                s=c.execute(sel,[entry_rollno.get()])
                m=[]
                for i in s:
                    m.extend(i)
                fine_pay=(difference.days*5)+m[0]

            #if book returned before actual return date
            else:
                sel="SELECT Fine from Student WHERE Roll_No=?"
                s=c.execute(sel,[entry_rollno.get()])
                m=[]
                for i in s:
                    m.extend(i)
                fine_pay=m[0]

            #label to show balance fine
            entry_balfine=Label(text=fine_pay,font=('Times',20))
            entry_balfine.place(x=370,y=450)
            break
    if found != 1:
        tm.showerror(title="Error", message="Invalid Book ID")

view = Button( text="View", fg="red", font=("Arial Bold",10),command=_view_)
view.place(x=680,y=200)
view1 = Button( text="View", fg="red", font=("Arial Bold",10),command=_view1_)
view1.place(x=680,y=300)

label_balfine=Label(text="Bal. Fine",fg="red",font=("Arial ", 20))
label_balfine.place(x=120,y=450)
label_finepaid=Label(text="Fine Paid",fg="red",font=("Arial ", 20))
label_finepaid.place(x=120,y=500)
entry_finepaid=Entry(width=20,font=('Times',20))
entry_finepaid.place(x=370,y=500)

#function for submit button
def _submit_btn_clicked():
    if entry_rollno.get() == "" or entry_bookid.get() == "":
        tm.showerror("Error", "Field cannot be blank")
    else:
        #to update balance fine in students table
        fp=int(fine_pay)
        fip=entry_finepaid.get()
        bal=fp-int(fip)
        if bal<0:
            tm.showerror("Error", "Paid fine cannot be greter than balance")
        else:
            ab="UPDATE Student set Fine=? WHERE Roll_No=?"
            c.execute(ab,[bal,entry_rollno.get()])
            conn.commit()

            #to delete student record from book_issued table
            query = "DELETE from Books_Issued WHERE (Roll_No=? and Book_ID=?)"
            c.execute(query, [entry_rollno.get(), entry_bookid.get()])
            conn.commit()

            #to update no of copies of books available
            status = []
            q = "SELECT Available FROM Books WHERE Book_ID=?"
            a = c.execute(q, [entry_bookid.get()])
            for i in a:
                status.extend(i)
            available = status[0]
            available = available + 1
            q = "UPDATE Books SET Available=? WHERE Book_ID=?"
            c.execute(q, [available, entry_bookid.get()])
            tm.showinfo(title="Success", message="Done!")
            conn.commit()
            root.destroy()
            os.system('python window_1.py')

subbtn = Button(text="submit", fg="red", font=("Arial Bold", 20), command=_submit_btn_clicked)
subbtn.place(x=200, y=650)

def back():
    root.destroy()
    os.system('python window_1.py')

backbtn = Button( text="Back", fg="red", font=("Arial Bold",20),command =back)
backbtn.place(x=400,y=650)

root.mainloop()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
sys.path.append('/usr/local/lib/python3.5/site-packages')
import gi
import shutil
import cv2
import os
import copy as cp
import decimal
import openpyxl
from openpyxl import Workbook
from pathlib import Path
import numpy as np
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib, GdkPixbuf
from natsort import natsorted
from PIL import Image
from time import sleep
import smbus
import time

builder = Gtk.Builder()
builder.add_from_file("Interface.glade")

window = builder.get_object("mainMenu")
image = builder.get_object("image1")
lblHasil = builder.get_object("lblHasil")
lblPersamaan = builder.get_object("lblPersamaan")
window.set_position(Gtk.WindowPosition.CENTER)
window.show_all()

class mainWindowHandler:

    global filename
    global foldername
    global tmpfolder
    global inputaction
    global lastRow
    global lastNo

    # Define some device parameters
    I2C_ADDR  = 0x3f # I2C device address
    LCD_WIDTH = 16   # Maximum characters per line

    # Define some device constants
    LCD_CHR = 1 # Mode - Sending data
    LCD_CMD = 0 # Mode - Sending command

    LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
    LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
    LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
    LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line

    LCD_BACKLIGHT  = 0x08  # On
    #LCD_BACKLIGHT = 0x00  # Off

    ENABLE = 0b00000100 # Enable bit

    # Timing constants
    E_PULSE = 0.0005
    E_DELAY = 0.0005

    #Open I2C interface
    #bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
    bus = smbus.SMBus(1) # Rev 2 Pi uses 1

    def __init__(self):
        # Initialise display
        self.lcd_init()

    def lcd_init(self):
      # Initialise display
      self.lcd_byte(0x33,self.LCD_CMD) # 110011 Initialise
      self.lcd_byte(0x32,self.LCD_CMD) # 110010 Initialise
      self.lcd_byte(0x06,self.LCD_CMD) # 000110 Cursor move direction
      self.lcd_byte(0x0C,self.LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
      self.lcd_byte(0x28,self.LCD_CMD) # 101000 Data length, number of lines, font size
      self.lcd_byte(0x01,self.LCD_CMD) # 000001 Clear display
      time.sleep(self.E_DELAY)

    def lcd_byte(self, bits, mode):
      # Send byte to data pins
      # bits = the data
      # mode = 1 for data
      #        0 for command

      bits_high = mode | (bits & 0xF0) | self.LCD_BACKLIGHT
      bits_low = mode | ((bits<<4) & 0xF0) | self.LCD_BACKLIGHT

      # High bits
      self.bus.write_byte(self.I2C_ADDR, bits_high)
      self.lcd_toggle_enable(bits_high)

      # Low bits
      self.bus.write_byte(self.I2C_ADDR, bits_low)
      self.lcd_toggle_enable(bits_low)

    def lcd_toggle_enable(self, bits):
      # Toggle enable
      time.sleep(self.E_DELAY)
      self.bus.write_byte(self.I2C_ADDR, (bits | self.ENABLE))
      time.sleep(self.E_PULSE)
      self.bus.write_byte(self.I2C_ADDR,(bits & ~self.ENABLE))
      time.sleep(self.E_DELAY)

    def lcd_string(self, message,line):
      # Send string to display

      message = message.ljust(self.LCD_WIDTH," ")

      self.lcd_byte(line, self.LCD_CMD)

      for i in range(self.LCD_WIDTH):
        self.lcd_byte(ord(message[i]),self.LCD_CHR)

    def printkelcd(self, message1, message2):
        self.lcd_string(message1,self.LCD_LINE_1)
        self.lcd_string(message2,self.LCD_LINE_2)

    def onDeleteWindow(self, * args):
        Gtk.main_quit(*args)

    def add_filters(self, dialog):
        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_pattern("*")
        dialog.add_filter(filter_any)

    def btnInputFile_clicked_cb(self, button):
        self.inputaction = 2
        dialog = Gtk.FileChooserDialog("Please choose your file", window,
                                       Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                                   Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        self.add_filters(dialog)
        response = dialog.run()
        if (response == Gtk. ResponseType.OK):
            self.filename = dialog.get_filename()
            image.set_from_file(self.filename)
        dialog.destroy()

    def btnInputFolder_clicked_cb(self, button):
        self.inputaction=1
        dialog = Gtk.FileChooserDialog("Please choose your folder", window,
                                       Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                                   Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

        response = dialog.run()
        if (response == Gtk. ResponseType.OK):
            self.foldername = dialog.get_filename()
        dialog.destroy()

    def btnInputCamera_clicked_cb(self, button):
        self.inputaction=3
        print("Gambar telah diambil")

    def savetoXLSX(self):
        wb = Workbook()

        excel_data = Path("data/data.xlsx")
        if excel_data.is_file():
            book = openpyxl.load_workbook('data/data.xlsx')

            sheet = book.active
            self.lastRow = sheet['C2'].value
            self.lastNo = sheet['C3'].value
            path=os.getcwd()
            path = path.replace(" ", "%20")
            dirFiles = natsorted(os.listdir(self.foldername))

            if self.inputaction==1:
                for file in dirFiles:
                    if (file.endswith(".png") or file.endswith(".jpg") or file.endswith(".jpeg")):

                        filename = os.path.join(self.foldername+"/"+file)
                        print ("Processing file: " + filename)
                        shutil.copyfile(filename, "data/sumber/"+str(self.lastNo)+".png")
                        luasDaun = self.countAreaObject(filename, True)
                        rgbDaun = self.RGBCount(filename, True)
                        kelilingDaun = self.countKeliling(filename, True)
                        persamaanluas = self.persamaan_luas(luasDaun)
                        persamaankeliling = self.persamaan_keliling(kelilingDaun)
                        persamaanrgb = self.persamaan_rgb(rgbDaun)
                        umurluas = self.cekumur_luas(persamaanluas)
                        umurkeliling = self.cekumur_keliling(persamaankeliling)
                        umurrgb = self.cekumur_rgb(persamaanrgb)

                        sheet['A'+str(self.lastRow)]=self.lastNo
                        sheet['B'+str(self.lastRow)]=filename
                        #Luas
                        sheet['C'+str(self.lastRow)]=luasDaun[0]
                        sheet['D'+str(self.lastRow)]=luasDaun[1]
                        sheet['E'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/luasdaun/"+str(self.lastNo)+"_atas.png\",\"LINK\")"
                        sheet['F'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/luasdaun/"+str(self.lastNo)+"_bawah.png\",\"LINK\")"
                        sheet['AP'+str(self.lastRow)] = persamaanluas
                        sheet['AS'+str(self.lastRow)] = umurluas

                        #RGB
                        colRgb = 7
                        for i in rgbDaun:
                            item = i.tolist()
                            for x in item:
                                sheet.cell(row=self.lastRow, column=colRgb).value = x
                                colRgb +=1

                        sheet['AK'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/rgbdaun/"+str(self.lastNo)+".png\",\"LINK\")"
                        sheet['AR'+str(self.lastRow)] = persamaanrgb
                        sheet['AU'+str(self.lastRow)] = umurrgb

                        #Keliling
                        sheet['AL'+str(self.lastRow)]=kelilingDaun[0]
                        sheet['AM'+str(self.lastRow)]=kelilingDaun[1]
                        sheet['AN'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/kelilingdaun/"+str(self.lastNo)+"_atas.png\",\"LINK\")"
                        sheet['AO'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/kelilingdaun/"+str(self.lastNo)+"_bawah.png\",\"LINK\")"
                        sheet['AQ'+str(self.lastRow)] = persamaankeliling
                        sheet['AT'+str(self.lastRow)] = umurkeliling
                        self.lastRow +=1
                        self.lastNo +=1
                        print ("\n")
                sheet['C2'] = self.lastRow
                sheet['C3'] = self.lastNo
                book.save("data/data.xlsx")
            else:
                shutil.copyfile(self.filename, "data/sumber/"+str(self.lastNo)+".png")
                luasDaun = self.countAreaObject(self.filename, True)
                rgbDaun = self.RGBCount(self.filename, True)
                kelilingDaun = self.countKeliling(self.filename, True)
                sheet['A'+str(self.lastRow)]=self.lastNo
                sheet['B'+str(self.lastRow)]=self.filename
                #Luas
                sheet['C'+str(self.lastRow)]=luasDaun[0]
                sheet['D'+str(self.lastRow)]=luasDaun[1]
                sheet['E'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/luasdaun/"+str(self.lastNo)+"_atas.png\",\"LINK\")"
                sheet['F'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/luasdaun/"+str(self.lastNo)+"_bawah.png\",\"LINK\")"

                #RGB
                colRgb = 7
                for i in rgbDaun:
                    item = i.tolist()
                    for x in item:
                        sheet.cell(row=self.lastRow, column=colRgb).value = x
                        colRgb +=1

                sheet['AK'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/rgbdaun/"+str(self.lastNo)+".png\",\"LINK\")"
                #Keliling
                sheet['AL'+str(self.lastRow)]=kelilingDaun[0]
                sheet['AM'+str(self.lastRow)]=kelilingDaun[1]
                sheet['AN'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/kelilingdaun/"+str(self.lastNo)+"_atas.png\",\"LINK\")"
                sheet['AO'+str(self.lastRow)]="=HYPERLINK(\"file://"+path+"/data/kelilingdaun/"+str(self.lastNo)+"_bawah.png\",\"LINK\")"
                self.lastRow +=1
                self.lastNo +=1
                sheet['C2'] = self.lastRow
                sheet['C3'] = self.lastNo
                book.save("data/data.xlsx")

    def btnSave_clicked_cb(self, button):
        self.savetoXLSX()
        print ("selesai menyimpan")

    def on_btnLuasDaun_clicked(self, button):
        if (self.inputaction==1):
            #inputfromfolder
            print("test")
        else:
            jumlahluas = self.countAreaObject(self.filename, False)
            persamaanluas = self.persamaan_luas(jumlahluas)
            umurluas = self.cekumur_luas(persamaanluas)
            lblPersamaan.set_text("(" + str(umurluas) + ")")

    def on_btnRgbDaun_clicked(self, button):
        if (self.inputaction==1):
            #inputfromfolder
            print("test")
        else:
            jumlahrgb = self.RGBCount(self.filename, False)
            persamaanrgb = self.persamaan_rgb(jumlahrgb)
            umurrgb = self.cekumur_rgb(persamaanrgb)
            lblPersamaan.set_text("(" + str(umurrgb) + ")")

    def on_btnKelilingDaun_clicked(self, button):
        if (self.inputaction==1):
            #inputfromfolder
            print("test")
        else:
            jumlahkeliling = self.countKeliling(self.filename, False)
            persamaankeliling = self.persamaan_keliling(jumlahkeliling)
            umurkeliling = self.cekumur_keliling(persamaankeliling)
            lblPersamaan.set_text("(" + str(umurkeliling) + ")")

    def cekumur_keliling(self, inputvar):
        hasil = 0
        #umur 1 bulan
        if (inputvar>=0.7 and inputvar<=0.71):
            hasil = 1
        if (inputvar>=0.749000001 and inputvar<=0.77):
            hasil = 1
        if (inputvar>=0.7460000010 and inputvar<=0.8100000000):
            hasil = 1
        if (inputvar>=0.9250000100 and inputvar<=0.9370000000):
            hasil = 1

        #umur 2 bulan
        if (inputvar>=0.7100000100 and inputvar<=0.7140000000):
            hasil = 2
        if (inputvar>=0.7270000010 and inputvar<=0.7490000000):
            hasil = 2
        if (inputvar>=0.9000000100 and inputvar<=0.9250000000):
            hasil = 2
        if (inputvar>=0.9383500010 and inputvar<=0.9390000000):
            hasil = 2

        #umur 3 bulan
        if (inputvar>=0.7140000001 and inputvar<=0.7150000000):
            hasil = 3
        if (inputvar>=0.7190000010 and inputvar<=0.7270000000):
            hasil = 3
        if (inputvar>=0.8500000100 and inputvar<=0.9000000000):
            hasil = 3
        if (inputvar>=0.9370000010 and inputvar<=0.9383500000):
            hasil = 3
        if (inputvar>=0.9390000010 and inputvar<=0.9392000000):
            hasil = 3

        #umur 4 bulan
        if (inputvar>=0.7150000010 and inputvar<=0.7155000000):
            hasil = 4
        if (inputvar>=0.7170000010 and inputvar<=0.7190000000):
            hasil = 4
        if (inputvar>=0.8100000100 and inputvar<=0.8500000000):
            hasil = 4
        if (inputvar>=0.9392500010 and inputvar<=0.9400000000):
            hasil = 4

        #umur 5 bulan
        if (inputvar>=0.7155000001 and inputvar<=0.7170000000):
            hasil = 5
        if (inputvar>=0.7700000010 and inputvar<=0.7460000000):
            hasil = 5
        if (inputvar>=0.9392000001 and inputvar<=0.9392500000):
            hasil = 5

        print ("Umur daun adalah: " + str(hasil))
        self.printkelcd("Umur daun adalah", str(hasil) + " Bulan")
        return hasil

    def cekumur_luas(self, inputvar):
        hasil = 0

        #umur 1 bulan
        if (inputvar>=0.998500000001000 and inputvar<=0.998800000000000):
            hasil = 1
        if (inputvar>=0.999000000000000 and inputvar<=1.000000000000000):
            hasil = 1

        #umur 2 bulan
        if (inputvar>=0.990355240000000 and inputvar<=0.990355248900000):
            hasil = 2
        if (inputvar>=0.990355255000001 and inputvar<=0.990355256500000):
            hasil = 2
        if (inputvar>=0.990355500000000 and inputvar<=0.990355862000000):
            hasil = 2
        if (inputvar>=0.990356000001000 and inputvar<=0.990356500000000):
            hasil = 2
        if (inputvar>=0.990358000001000 and inputvar<=0.990450000000000):
            hasil = 2
        if (inputvar>=0.990500000001000 and inputvar<=0.996000000000000):
            hasil = 2
        if (inputvar>=0.996500000010000 and inputvar<=0.998500000000000):
            hasil = 2
        if (inputvar>=0.998800000001000 and inputvar<=0.999000000000000):
            hasil = 2

        #umur 3 bulan
        if (inputvar>=0.990355249000000 and inputvar<=0.990355249250000):
            hasil = 3
        if (inputvar>=0.990355249303001 and inputvar<=0.990355249305000):
            hasil = 3
        if (inputvar>=0.990355249430001 and inputvar<=0.990355249450000):
            hasil = 3
        if (inputvar>=0.990355250000000 and inputvar<=0.990355253000000):
            hasil = 3
        if (inputvar>=0.990355256500010 and inputvar<=0.990355259000000):
            hasil = 3
        if (inputvar>=0.990355260000100 and inputvar<=0.990355499999000):
            hasil = 3
        if (inputvar>=0.990355862000001 and inputvar<=0.990356000000000):
            hasil = 3
        if (inputvar>=0.990356500000010 and inputvar<=0.990358000000000):
            hasil = 3
        if (inputvar>=0.990451000000000 and inputvar<=0.990500000000000):
            hasil = 3

        #umur 4 bulan
        if (inputvar>=0.990355249260000 and inputvar<=0.990355249266999):
            hasil = 4
        if (inputvar>=0.990355249267111 and inputvar<=0.990355249267600):
            hasil = 4
        if (inputvar>=0.990355249269000 and inputvar<=0.990355249271000):
            hasil = 4
        if (inputvar>=0.990355249281001 and inputvar<=0.990355249283000):
            hasil = 4
        if (inputvar>=0.990355249285001 and inputvar<=0.990355249303000):
            hasil = 4
        if (inputvar>=0.990355249305001 and inputvar<=0.990355249340000):
            hasil = 4
        if (inputvar>=0.990355249400010 and inputvar<=0.990355249430000):
            hasil = 4
        if (inputvar>=0.990355249480001 and inputvar<=0.990355250000000):
            hasil = 4
        if (inputvar>=0.990355253000010 and inputvar<=0.990355255000000):
            hasil = 4
        if (inputvar>=0.996000000010000 and inputvar<=0.996500000000000):
            hasil = 4

        #umur 5 bulan
        if (inputvar>=0.990355249267000 and inputvar<=0.990355249267110):
            hasil = 5
        if (inputvar>=0.990355249267601 and inputvar<=0.990355249268999):
            hasil = 5
        if (inputvar>=0.990355249271001 and inputvar<=0.990355249281000):
            hasil = 5
        if (inputvar>=0.990355249283001 and inputvar<=0.990355249285000):
            hasil = 5
        if (inputvar>=0.990355249340010 and inputvar<=0.990355249400000):
            hasil = 5
        if (inputvar>=0.990355249450010 and inputvar<=0.990355249480000):
            hasil = 5
        if (inputvar>=0.990355259000010 and inputvar<=0.990355260000000):
            hasil = 5

        print ("Umur daun adalah: " + str(hasil))
        return hasil

    def cekumur_rgb(self, inputvar):
        inputvar = inputvar*100000
        hasil = 0

        #umur 1 bulan
        if (inputvar>=0.029369724484205 and inputvar<=0.029719015774401):
            hasil = 1
        if (inputvar>=0.030505103311023 and inputvar<=0.0325):
            hasil = 1
        if (inputvar>=0.039230750612453 and inputvar<=0.042599):
            hasil = 1
        if (inputvar>=0.145315385263545 and inputvar<=0.211297905573164):
            hasil = 1
        if (inputvar>=0.214007566327266 and inputvar<=0.217214368282262):
            hasil = 1
        if (inputvar>=0.21775070875511 and inputvar<=0.219367890609806):
            hasil = 1

        #umur 2 bulan
        if (inputvar>=0.0326 and inputvar<=0.034066493664224):
            hasil = 2
        if (inputvar>=0.055999 and inputvar<=0.063999):
            hasil = 2
        if (inputvar>=0.079999 and inputvar<=0.139999):
            hasil = 2
        if (inputvar>=0.211586807805377 and inputvar<=0.213999):
            hasil = 2
        if (inputvar>=0.217493983284268 and inputvar<=0.217699):
            hasil = 2
        if (inputvar>=0.219406643722113 and inputvar<=0.219799):
            hasil = 2
        if (inputvar>=801 and inputvar<=1090):
            hasil = 2
        if (inputvar>=1250 and inputvar<=2000):
            hasil = 2
        if (inputvar>=3562.99 and inputvar<=3566):
            hasil = 2
        if (inputvar>=3610 and inputvar<=3610.469):
            hasil = 2
        if (inputvar>=3611 and inputvar<=3627):
            hasil = 2
        if (inputvar>=3656 and inputvar<=3668):
            hasil = 2
        if (inputvar>=3669 and inputvar<=12000):
            hasil = 2

        #umur 3 bulan
        if (inputvar>=0.02 and inputvar<=0.021):
            hasil = 3
        if (inputvar>=0.0273 and inputvar<=0.0285):
            hasil = 3
        if (inputvar>=2 and inputvar<=80):
            hasil = 3
        if (inputvar>=2101 and inputvar<=3220):
            hasil = 3
        if (inputvar>=3261 and inputvar<=3295):
            hasil = 3
        if (inputvar>=3321 and inputvar<=3370):
            hasil = 3
        if (inputvar>=3421 and inputvar<=3563):
            hasil = 3
        if (inputvar>=3583 and inputvar<=3609):
            hasil = 3
        if (inputvar>=3609.5 and inputvar<=3609.9):
            hasil = 3
        if (inputvar>=3610.47 and inputvar<=3611):
            hasil = 3
        if (inputvar>=3627.1 and inputvar<=3639.999):
            hasil = 3
        if (inputvar>=3663 and inputvar<=3668.999):
            hasil = 3

        #umur 4 bulan
        if (inputvar>=0.0001 and inputvar<=0.0104):
            hasil = 4
        if (inputvar>=0.0108 and inputvar<=0.012):
            hasil = 4
        if (inputvar>=0.0137 and inputvar<=0.0138):
            hasil = 4
        if (inputvar>=0.021 and inputvar<=0.0215):
            hasil = 4
        if (inputvar>=0.022 and inputvar<=0.0225):
            hasil = 4
        if (inputvar>=0.026 and inputvar<=0.0269):
            hasil = 4
        if (inputvar>=0.0285 and inputvar<=0.02935):
            hasil = 4
        if (inputvar>=0.03 and inputvar<=0.0305):
            hasil = 4
        if (inputvar>=81 and inputvar<=800):
            hasil = 4
        if (inputvar>=1091 and inputvar<=1249):
            hasil = 4
        if (inputvar>=3221 and inputvar<=3260):
            hasil = 4
        if (inputvar>=3371 and inputvar<=3420):
            hasil = 4
        if (inputvar>=3566.1 and inputvar<=3582.99):
            hasil = 4
        if (inputvar>=3609.1 and inputvar<=3609.499):
            hasil = 4
        if (inputvar>=3609.91 and inputvar<=3609.9):
            hasil = 4

        #umur 5 bulan
        if (inputvar>=0.01199 and inputvar<=0.013699):
            hasil = 5
        if (inputvar>=0.01381 and inputvar<=0.019999):
            hasil = 5
        if (inputvar>=0.02151 and inputvar<=0.021999):
            hasil = 5
        if (inputvar>=0.02551 and inputvar<=0.02559):
            hasil = 5
        if (inputvar>=0.027 and inputvar<=0.027299):
            hasil = 5
        if (inputvar>=0.034067 and inputvar<=0.039):
            hasil = 5
        if (inputvar>=0.0426 and inputvar<=0.055998):
            hasil = 5
        if (inputvar>=0.064 and inputvar<=0.07998):
            hasil = 5
        if (inputvar>=0.2198 and inputvar<=1.99):
            hasil = 5
        if (inputvar>=3628 and inputvar<=3655.99):
            hasil = 5
        print ("Umur daun adalah: " + str(hasil))
        return hasil

    def persamaan_rgb(self, inputvar):
        #tahap penjumlahan
        inputvar2 = cp.deepcopy(inputvar)
        indexItem = 0
        for i in inputvar:
            item = i.tolist()
            sumofItem = 0
            for x in item:
                x1= x*0.01
                sumofItem = sumofItem + x1
            inputvar2[indexItem]=sumofItem
            indexItem +=1

        v11=1.4004
        v21=-0.2972
        v31=1.5537
        v41=-1.2604
        v51=0.6302
        v12=-3.5916
        v22=0.7617
        v32=-2.7840
        v42=2.2625
        v52=2.0473
        v13=1.2331
        v23=1.5439
        v33=-1.9324
        v43=7.1158
        v53=1.9876
        v14=0.8985
        v24=-0.0452
        v34=-0.9155
        v44=-2.7155
        v54=-1.8111
        v15=1.8386
        v25=-1.0646
        v35=-1.0175
        v45=-0.2514
        v55=0.3470
        v16=-1.1064
        v26=4.5201
        v36=-1.1779
        v46=3.0497
        v56=-0.4884
        v17=-3.3348
        v27=-0.2015
        v37=2.0500
        v47=-0.0438
        v57=-0.3871
        v18=0.7826
        v28=0.6025
        v38=-3.0437
        v48=1.9025
        v58=1.7143
        v19=1.1794
        v29=-2.5524
        v39=-5.2434
        v49=-0.2866
        v59=2.0611
        v110=-2.9668
        v210=-3.6863
        v310=0.5320
        v410=-1.7164
        v510=0.4906
        bz1=0.8734
        bz2=-1.7877
        bz3=1.0375
        bz4=-5.1055
        bz5=-5.6914
        w1=-3.3221
        w2=-0.5377
        w3=0.7797
        w4=-1.7300
        w5=6.3210
        b0=4.2648
        e=10

        #tahap pembobotan
        z_in1=w1+((inputvar2[0]*v11)+(inputvar2[1]*v12)+(inputvar2[2]*v13)+(inputvar2[3]*v14)+(inputvar2[4]*v15)+(inputvar2[5]*v16)+(inputvar2[6]*v17)+(inputvar2[7]*v18)+(inputvar2[8]*v19)+(inputvar2[9]*v110))
        z_in2=w2+((inputvar2[0]*v21)+(inputvar2[1]*v22)+(inputvar2[2]*v23)+(inputvar2[3]*v24)+(inputvar2[4]*v25)+(inputvar2[5]*v26)+(inputvar2[6]*v27)+(inputvar2[7]*v28)+(inputvar2[8]*v29)+(inputvar2[9]*v210))
        z_in3=w3+((inputvar2[0]*v31)+(inputvar2[1]*v32)+(inputvar2[2]*v33)+(inputvar2[3]*v34)+(inputvar2[4]*v35)+(inputvar2[5]*v36)+(inputvar2[6]*v37)+(inputvar2[7]*v38)+(inputvar2[8]*v39)+(inputvar2[9]*v310))
        z_in4=w4+((inputvar2[0]*v41)+(inputvar2[1]*v42)+(inputvar2[2]*v43)+(inputvar2[3]*v44)+(inputvar2[4]*v45)+(inputvar2[5]*v46)+(inputvar2[6]*v47)+(inputvar2[7]*v48)+(inputvar2[8]*v49)+(inputvar2[9]*v410))
        z_in5=w5+((inputvar2[0]*v51)+(inputvar2[1]*v52)+(inputvar2[2]*v53)+(inputvar2[3]*v54)+(inputvar2[4]*v55)+(inputvar2[5]*v56)+(inputvar2[6]*v57)+(inputvar2[7]*v58)+(inputvar2[8]*v59)+(inputvar2[9]*v510))

        #fungsi aktivasi
        z1=1/(1+pow(e,-(z_in1)))
        z2=1/(1+pow(e,-(z_in2)))
        z3=1/(1+pow(e,-(z_in3)))
        z4=1/(1+pow(e,-(z_in4)))
        z5=1/(1+pow(e,-(z_in5)))

        #output
        y_in=b0+((z1*bz1)+(z2*bz2)+(z3*bz3)+(z4*bz4)+(z5*bz5))
        result=1/(1+pow(e,-(y_in)))
        print("Hasilt persamaan: " + str(result))
        return result

    def persamaan_keliling(self, inputvar):
        var11=2.0157
        var21=-2.5408
        var31=2.9785
        var41=0.0689
        var51=-4.3687
        var12=-1.8502
        var22=0.5244
        var32=0.3451
        var42=0.1044
        var52=2.0059

        bz1=-0.7890
        bz2=0.4114
        bz3=-1.6262
        bz4=3.3549
        bz5=-0.3437

        w1=-2.4535
        w2=-2.9795
        w3=3.2752
        w4=0.8474
        w5=4.2016

        b0=-0.5387
        e=10

        #tahap pembobotan
        z_in1=w1+((inputvar[0]*var11)+(inputvar[1]*var12))
        z_in2=w2+((inputvar[0]*var21)+(inputvar[1]*var22))
        z_in3=w3+((inputvar[0]*var31)+(inputvar[1]*var32))
        z_in4=w4+((inputvar[0]*var41)+(inputvar[1]*var42))
        z_in5=w5+((inputvar[0]*var51)+(inputvar[1]*var52))

        #fungsi aktivasi
        z1=1/(1+pow(e,-(z_in1)))
        z2=1/(1+pow(e,-(z_in2)))
        z3=1/(1+pow(e,-(z_in3)))
        z4=1/(1+pow(e,-(z_in4)))
        z5=1/(1+pow(e,-(z_in5)))

        #output
        y_in=b0+((z1*bz1)+(z2*bz2)+(z3*bz3)+(z4*bz4)+(z5*bz5))
        result=1/(1+pow(e,-(y_in)))
        print("Hasilt persamaan: " + str(result))
        return result

    def persamaan_luas(self, inputvar):
        inputvar[0] = inputvar[0]*0.1
        inputvar[1] = inputvar[1]*0.1
        v11=0.5430
        v21=1.6464
        v31=-5.5055
        v41=0.6884
        v51=-0.5672
        v12=6.3309
        v22=-4.7068
        v32=-7.0952
        v42=-5.5650
        v52=-1.6284
        bz1=-0.7986
        bz2=1.6986
        bz3=-3.3620
        bz4=1.4270
        bz5=-9.4362
        w1=-6.6344
        w2=-1.6962
        w3=4.1913
        w4=6.2366
        w5=-2.4389
        b0=2.8101
        e=10

        #tahap pembobotan
        z_in1=w1+((inputvar[0]*v11)+(inputvar[1]*v12))
        z_in2=w2+((inputvar[0]*v21)+(inputvar[1]*v22))
        z_in3=w3+((inputvar[0]*v31)+(inputvar[1]*v32))
        z_in4=w4+((inputvar[0]*v41)+(inputvar[1]*v42))
        z_in5=w5+((inputvar[0]*v51)+(inputvar[1]*v52))

        #fungsi aktivasi
        z1=1/(1+pow(e,-(z_in1)))
        z2=1/(1+pow(e,-(z_in2)))
        z3=1/(1+pow(e,-(z_in3)))
        z4=1/(1+pow(e,-(z_in4)))
        z5=1/(1+pow(e,-(z_in5)))

        #output
        y_in=b0+((z1*bz1)+(z2*bz2)+(z3*bz3)+(z4*bz4)+(z5*bz5))
        result=1/(1+pow(e,-(y_in)))
        print("Hasilt persamaan: " + str(result))
        return result

    def RGBCount(self, filename, saveImage):
        global rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8, rgb9, rgb10
        img = cv2.imread(filename)
        rgb_read=cv2.imread(filename)
        height, width = img.shape[:2]
        #get rgb
        #point 1
        rgb1 = rgb_read[int(height * .5)-20,0+100]
        #point 2
        rgb2 = rgb_read[int(height * .5)-20,50+int((width-150) * .30)]
        #point 3
        rgb3 = rgb_read[int(height * .5)-20,50+int((width-150) * .55)]
        #point 4
        rgb4 = rgb_read[int(height * .5)-20,50+int((width-150) * .70)]
        #point 5
        rgb5 = rgb_read[int(height * .5)-20,50+int((width-150) * .80)]

        #point 6
        rgb6 = rgb_read[int(height * .5)+20,0+100]
        #point 7
        rgb7 = rgb_read[int(height * .5)+20,50+int((width-150) * .30)]
        #point 8
        rgb8 = rgb_read[int(height * .5)+20,50+int((width-150) * .55)]
        #point 9
        rgb9 = rgb_read[int(height * .5)+20,50+int((width-150) * .70)]
        #point 10
        rgb10 = rgb_read[int(height * .5)+20,50+int((width-150) * .80)]

        #point 1
        cv2.line(img, (0+100,int(height * .5)-20),(0+100,int(height * .5)-20),(0,0,255),5)
        #point 2
        cv2.line(img, (100+int((width-150) * .30),int(height * .5)-20),(100+int((width-150) * .30),int(height * .5)-20),(0,0,255),5)
        #point 3
        cv2.line(img, (100+int((width-150) * .55),int(height * .5)-20),(100+int((width-150) * .55),int(height * .5)-20),(0,0,255),5)
        #point 4
        cv2.line(img, (100+int((width-150) * .70),int(height * .5)-20),(100+int((width-150) * .70),int(height * .5)-20),(0,0,255),5)
        #point 5
        cv2.line(img, (100+int((width-150) * .80),int(height * .5)-20),(100+int((width-150) * .80),int(height * .5)-20),(0,0,255),5)

        #point 6
        cv2.line(img, (0+100,int(height * .5)+20),(0+100,int(height * .5)+20),(0,0,255),5)
        #point 7
        cv2.line(img, (100+int((width-150) * .30),int(height * .5)+20),(100+int((width-150) * .30),int(height * .5)+20),(0,0,255),5)
        #point 8
        cv2.line(img, (100+int((width-150) * .55),int(height * .5)+20),(100+int((width-150) * .55),int(height * .5)+20),(0,0,255),5)
        #point 9
        cv2.line(img, (100+int((width-150) * .70),int(height * .5)+20),(100+int((width-150) * .70),int(height * .5)+20),(0,0,255),5)
        #point 10
        cv2.line(img, (100+int((width-150) * .80),int(height * .5)+20),(100+int((width-150) * .80),int(height * .5)+20),(0,0,255),5)

        if saveImage==True:
            cv2.imwrite("data/rgbdaun/"+ str(self.lastNo)+".png", img)
        else:
            cv2.imwrite("rgbdaun.png", img)

        #image.set_from_file("rgbdaun.png")

        print("RGB Titik ke 1:" ,rgb1)
        print("RGB Titik ke 2:" ,rgb2)
        print("RGB Titik ke 3:" ,rgb3)
        print("RGB Titik ke 4:" ,rgb4)
        print("RGB Titik ke 5:" ,rgb5)
        print("RGB Titik ke 6:" ,rgb6)
        print("RGB Titik ke 7:" ,rgb7)
        print("RGB Titik ke 8:" ,rgb8)
        print("RGB Titik ke 9:" ,rgb9)
        print("RGB Titik ke 10:" ,rgb10)

        lblHasil.set_text("Titik ke 1: " + str(rgb1) + "\n" +
                          "Titik ke 2: " + str(rgb2) + "\n" +
                          "Titik ke 3: " + str(rgb3) + "\n" +
                          "Titik ke 4: " + str(rgb4) + "\n" +
                          "Titik ke 5: " + str(rgb5) + "\n" +
                          "Titik ke 6: " + str(rgb6) + "\n" +
                          "Titik ke 7: " + str(rgb7) + "\n" +
                          "Titik ke 8: " + str(rgb8) + "\n" +
                          "Titik ke 9: " + str(rgb9) + "\n" +
                          "Titik ke 10: " + str(rgb10))
        result = [rgb1, rgb2,rgb3,rgb4,rgb5, rgb6, rgb7, rgb8, rgb9, rgb10]
        return result

    def countKeliling(self, filename, saveImage):
        global kelilingAtas, kelilingBawah
        #reading the image
        image = cv2.imread(filename)

        edged = cv2.Canny(image, 70, 150)

        count_keliling = cv2.countNonZero(edged)

        height, width = edged.shape[:2]
        # Let's get the starting pixel coordiantes (top left of cropped top)
        start_row, start_col = int(0), int(0)
        # Let's get the ending pixel coordinates (bottom right of cropped top)
        end_row, end_col = int(height * .5), int(width)
        cropped_top = edged[start_row:end_row , start_col:end_col]
        if saveImage==True:
            cv2.imwrite("data/kelilingdaun/"+str(self.lastNo)+"_atas.png",cropped_top)
        else:
            cv2.imwrite("countourTop.png",cropped_top)
        h_top, w_top = edged.shape[:2]
        cons_keliling = 33 #19cmx+(2*7cm) 7cm = 14cm/2 satu sisi tidak dihitung karna dibagi 2
        #dapatkan ukuan pixel per cm
        cons_divided = ((2*h_top) + w_top)/cons_keliling
        cropped_top = np.array(cropped_top)

        count_keliling = cv2.countNonZero(cropped_top)
        kelilingAtas=round(count_keliling/cons_divided)

        # Let's get the starting pixel coordiantes (top left of cropped bottom)
        start_row, start_col = int(height * .5), int(0)
        # Let's get the ending pixel coordinates (bottom right of cropped bottom)
        end_row, end_col = int(height), int(width)
        cropped_bot = edged[start_row:end_row , start_col:end_col]
        if saveImage==True:
            cv2.imwrite("data/kelilingdaun/"+str(self.lastNo)+"_bawah.png",cropped_bot)
        else:
            cv2.imwrite("countourBot.png",cropped_bot)
        h_bot, w_bot = cropped_bot.shape[:2]
        cropped_bot = np.array(cropped_bot)

        count_keliling = cv2.countNonZero(cropped_bot)
        kelilingBawah=round(count_keliling/cons_divided)

        print("Keliling daun bagian atas: ", kelilingAtas)
        print("Keliling daun bagian bawah: ", kelilingBawah)
        lblHasil.set_text("(" + str(kelilingAtas) + "," + str(kelilingBawah)+ ")")
        result = [kelilingAtas, kelilingBawah]
        return result

    def countAreaObject(self, filename, saveImage):
        global luasdauntop, luasdaunbot

        img = cv2.imread(filename)

        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        gray = cv2.medianBlur(gray, 5)
        #cv2.imwrite("gray.jpg",gray)
        ret, thresh = cv2.threshold(gray, 70, 255,cv2.THRESH_BINARY)

        height, width = thresh.shape[:2]
        # Let's get the starting pixel coordiantes (top left of cropped top)
        start_row, start_col = int(0), int(0)
        # Let's get the ending pixel coordinates (bottom right of cropped top)
        end_row, end_col = int(height * .5), int(width)
        cropped_top = thresh[start_row:end_row , start_col:end_col]

        h_top, w_top = cropped_top.shape[:2]

        cons_luas = 133 #19cmx7cm 7cm = 14cm/2
        #dapatkan ukuan pixel per cm
        cons_divided = (h_top * w_top)/cons_luas

        cropped_top = np.array(cropped_top)
        if saveImage==True:
            cv2.imwrite("data/luasdaun/"+str(self.lastNo)+"_atas.png", cropped_top)
        else:
            cv2.imwrite("cropped_top.png", cropped_top)

        count_white_top = cv2.countNonZero(cropped_top)
        luasdauntop = (h_top * w_top)- count_white_top
        luasdauntop = round(luasdauntop/cons_divided)
        print("Luas daun bagian atas: ", luasdauntop)

        # Let's get the starting pixel coordiantes (top left of cropped bottom)
        start_row, start_col = int(height * .5), int(0)
        # Let's get the ending pixel coordinates (bottom right of cropped bottom)
        end_row, end_col = int(height), int(width)
        cropped_bot = thresh[start_row:end_row , start_col:end_col]
        h_bot, w_bot = cropped_bot.shape[:2]
        cropped_bot = np.array(cropped_bot)

        if saveImage==True:
            cv2.imwrite("data/luasdaun/"+str(self.lastNo)+"_bawah.png", cropped_bot)
        else:
            cv2.imwrite("cropped_bot.png", cropped_bot)
        count_white_bot = cv2.countNonZero(cropped_bot)
        luasdaunbot = (h_bot * w_bot)- count_white_bot
        luasdaunbot = round(luasdaunbot/cons_divided)

        print("Luas daun bagian bawah: ", luasdaunbot)
        lblHasil.set_text("(" + str(luasdauntop) + "," + str(luasdaunbot)+ ")")
        result = [luasdauntop,luasdaunbot]
        return result

    def thresholdingTest(self, filename):
        #reading the image
        image = cv2.imread(filename)
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        gray = cv2.medianBlur(gray, 5)
        cv2.imwrite("gray.jpg",gray)
        for i in range(127):
            ret, thresh = cv2.threshold(gray, i, 255,cv2.THRESH_BINARY)
            cv2.imwrite("thresh"+str(i)+".jpg",thresh)
            th2 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
            cv2.imwrite("adaptivethresh"+str(i)+".jpg",thresh)

        print ("selesai")
    def background_remover4(self, filename):
        # Read image
        im_in = cv2.imread(filename, cv2.IMREAD_GRAYSCALE);

        # Threshold.
        # Set values equal to or above 220 to 0.
        # Set values below 220 to 255.

        th, im_th = cv2.threshold(im_in, 70, 255, cv2.THRESH_BINARY_INV);

        # Copy the thresholded image.
        im_floodfill = im_th.copy()

        # Mask used to flood filling.
        # Notice the size needs to be 2 pixels than the image.
        h, w = im_th.shape[:2]
        mask = np.zeros((h+2, w+2), np.uint8)

        # Floodfill from point (0, 0)
        cv2.floodFill(im_floodfill, mask, (0,0), 255);

        # Invert floodfilled image
        im_floodfill_inv = cv2.bitwise_not(im_floodfill)
        test = cv2.bitwise_and(im_floodfill)
        test2 = cv2.bitwise_and(im_floodfill_inv)
        # Combine the two images to get the foreground.
        im_out = im_th | im_floodfill_inv

        # Display images.
        cv2.imwrite("Thresholded Image.jpg", im_th)
        cv2.imwrite("Floodfilled Image.jpg", im_floodfill)
        cv2.imwrite("Inverted Floodfilled Image.jpg", im_floodfill_inv)
        cv2.imwrite("Foreground.jpg", im_out)
        cv2.imwrite("Foreground1.jpg", test)
        cv2.imwrite("Foreground2.jpg", test2)

    def background_remover3(self, img):
        stencil = np.zeros(img.shape).astype(img.dtype)
        #(_, cnts, _) = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        contours = [np.array([[100, 180], [200, 280], [200, 180]]), np.array([[280, 70], [12, 20], [80, 150]])]
        color = [255, 255, 255]
        cv2.fillPoly(stencil, contours, color)
        result = cv2.bitwise_and(img, stencil)
        cv2.imwrite("result.jpg", result)

    def background_remover2(self, filename):
        original_image = cv2.imread(filename)
        # 1 Convert to gray & Normalize
        gray_img = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
        gray_img = sharp(cv2.get_contrasted(gray_img))
        gray_img = normalize(gray_img, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC1)
        cv2.imwrite("Gray.jpg", gray_img)

        # 2 Find Threshold
        gray_blur = cv2.GaussianBlur(gray_img, (7, 7), 0)
        adapt_thresh_im = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 1)
        max_thresh, thresh_im = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
        thresh = cv2.bitwise_or(adapt_thresh_im, thresh_im)

        # 3 Dilate
        gray = cv2.Canny(thresh, 88, 400, apertureSize=3)
        gray = cv2.dilate(gray, None, iterations=8)
        gray = cv2.erode(gray, None, iterations=8)
        cv2.imwrite("Trheshold.jpg", gray)

        # 4 Flood
        contours, _ = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        contour_info = []
        for c in contours:
            contour_info.append((
                c,
                cv2.isContourConvex(c),
                cv2.contourArea(c),
            ))
        contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
        max_contour = contour_info[0]
        holes = np.zeros(gray_img.shape, np.uint8)
        drawContours(holes, max_contour, 0, 255, -1)
        cv2.imwrite("Holes.jpg", holes)

        mask = cv2.GaussianBlur(holes, (15, 15), 0)
        mask = np.dstack([mask] * 3)  # Create 3-channel alpha mask

        mask = mask.astype('float32') / 255.0  # Use float matrices,
        img = original_image.astype('float32') / 255.0  # for easy blending
        masked = (mask * img) + ((1 - mask) * (0,0,1))  # Blend
        masked = (masked * 255).astype('uint8')

        cv2.imwrite("Maked.jpg", masked)

    def get_holes(self, image, thresh):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        im_bw = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY)[1]
        im_bw_inv = cv2.bitwise_not(im_bw)

        (_, cnts, _) = cv2.findContours(im_bw_inv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for cnt in cnts:
            cv2.drawContours(im_bw_inv, [cnt], 0, 255, -1)
        cv2.imwrite("testss.jpg", im_bw_inv)
        nt = cv2.bitwise_not(im_bw)
        im_bw_inv = cv2.bitwise_or(im_bw_inv, nt)
        return im_bw_inv

    def remove_background(self, image, thresh, scale_factor=.25, kernel_range=range(1, 15), border=None):
        border = border or kernel_range[-1]

        holes = self.get_holes(image, thresh)
        small = cv2.resize(holes, None, fx=scale_factor, fy=scale_factor)
        bordered = cv2.copyMakeBorder(small, border, border, border, border, cv2.BORDER_CONSTANT)

        for i in kernel_range:
            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2*i+1, 2*i+1))
            bordered = cv2.morphologyEx(bordered, cv2.MORPH_CLOSE, kernel)

        unbordered = bordered[border: -border, border: -border]
        mask = cv2.resize(unbordered, (image.shape[1], image.shape[0]))
        fg = cv2.bitwise_and(image, image, mask=mask)
        return fg

    def background_remover(self, imgo):
        height, width = imgo.shape[:2]

        #Create a mask holder
        mask = np.zeros(imgo.shape[:2],np.uint8)

        #Grab Cut the object
        bgdModel = np.zeros((1,65),np.float64)
        fgdModel = np.zeros((1,65),np.float64)

        #Hard Coding the Rect… The object must lie within this rect.
        rect = (10,10,width-30,height-30)
        cv2.grabCut(imgo,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
        mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
        img1 = imgo*mask[:,:,np.newaxis]

        #Get the background
        background = imgo - img1

        #Change all pixels in the background that are not black to white
        background[np.where((background > [0,0,0]).all(axis = 2))] = [255,255,255]

        #Add the background and the image
        final = background + img1
        return final

    def getMultiImage(self):
        camera = cv2.VideoCapture(0)

        for i in range(10):
            print ("Taking image")
            retval, camera_capture = camera.read()
            file = "tmp.png"
            file = self.checkfile(file)
            cv2.imwrite(file, camera_capture)
        del(camera)

    def checkfile(self, path):
         path      = os.path.expanduser(path)

         if not os.path.exists(path):
            return path

         root, ext = os.path.splitext(os.path.expanduser(path))
         dir       = os.path.dirname(root)
         fname     = os.path.basename(root)
         candidate = fname+ext
         index     = 0
         ls        = set(os.listdir(dir))
         while candidate in ls:
                 candidate = "{}_{}{}".format(fname,index,ext)
                 index    += 1
         return os.path.join(dir,candidate)

builder.connect_signals(mainWindowHandler())

Gtk.main()