# das skript dient nur als demo. hier kan man sowohl kreise loeschen(rechte maustaste zum mittelpunkt des kreises), und gleichzeitig radien regional zuweisen(linke maustaste gedrueckthalten und ziehen)
# in der praxis wird das aber hintereinander gemacht: erst radien zuweisen, dann detektion drueber einpaar mal laufen lassen, und dann falsch detektiere kreise loeschen

import sys
from PyQt4 import QtGui, QtCore #ich glaube auf den Pi ist PyQt4 installiert. Ersetzt das dann einfach PySide 
import numpy as np 
import cv2
from time import sleep
#--------------Kuenstliche Kamera Daten und detektierte Kreise etc.
full=cv2.imread('fullhorst.bmp',0).astype(np.uint8)
num_regions=3
radii=np.empty(3,dtype=object)                      #hier kommt spaeter rein, welche region, welche behaelterradien aufweist
circles=np.empty(3,dtype=object)
circles[0]=[[314,58,10],[352,92,11],[412,122,9]]    #detektierte kreise
circles[1]=[[175,396,10],[152,426,11],[ 98,416,9]]
circles[2]=[[127,139,12],[ 87,190,13],[101,253,14]]
region1=cv2.imread('region1.bmp',0).astype(np.uint8)
region2=cv2.imread('region2.bmp',0).astype(np.uint8)
region3=cv2.imread('region3.bmp',0).astype(np.uint8)
regions=[region1,region2,region3]                   #detektierte regionen
rohling=np.zeros((500,500,1),dtype=np.uint8)
#------------------------------------------------------------------

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        self.setWindowOpacity(1)
        # Init QLabel
        self.positionQLabel = QtGui.QLabel(self)        # hier wird das Label erstellt, wo das bild angezeigt wird
        self.update_drawing()                           # siehe unten: das bild wird ein mal aufgefrischt
        self.positionQLabel.setMouseTracking(True)      # hier wird der moustraker aktiviert
        self.positionQLabel.installEventFilter(self)    # eventfilter nicht vergessen
        # Init QLayout
        layoutQHBoxLayout = QtGui.QHBoxLayout()         # kein plan wofuer das ist...
        layoutQHBoxLayout.addWidget(self.positionQLabel)    
        self.setLayout(layoutQHBoxLayout)
        self.show()

    def eventFilter(self, source, event): #die funktion "eventFilter" ist ueberladen. die muss so genannt werden, sonst wird sie nicht automatisch aufgerufen
        if event is not None: #erst wenn die Maus auf das Labelfenster kommt, fang an die events zu speichern
            self.evt=event    # ist hier unoetig, vielleicht spaeter noetig
            self.xc=event.x() #xcoord
            self.yc=event.y() #ycoord
            
        if event.type() == QtCore.QEvent.MouseButtonPress: # wenn eine maustaste runtergedrueckt wurde...

            self.down=True # ...flag setzen
            if event.button() == QtCore.Qt.MouseButton.RightButton: #bei rechter maustaste falsche kreise loeschen
                self.delete_shit()
            if event.button() == QtCore.Qt.MouseButton.LeftButton: #bei linker maustaste radien an die regionen zuweisen
                self.assign_region()
            self.update_drawing() 
        elif event.type() == QtCore.QEvent.MouseButtonRelease: # falls eine maustaste losgelassen wurde
            self.down=False # flag auf false. das ist notwendig, um festzustellen ob eine taste noch gehalten wird. in moment macht es nur sinn die linke zu halten. falls die rechte aus gehalten werden soll, muss man seperate if statements reinhauen und seperate flags setzen
        return super(QCustomWidget, self).eventFilter(source, event)


    def delete_shit(self):
        global circles #detektierte kreise
        startpos=self.xc,self.yc #klickposition
        index=0 
        for reg in regions: # lauf durch die 3 regionen
            if reg[startpos[1],startpos[0]]: # falls die aktuelle region bei der klickposition weiss ist, dann bist du in dieser region
                distances=[(x[0]-startpos[0])*(x[0]-startpos[0])+(x[1]-startpos[1])*(x[1]-startpos[1]) for x in circles[index]] # distanzen zu den kreisen in dieser region
                
                inder=0          
                for d in distances:
                    if d <=100: #sobald eine quadratische distanz kleiner 100 gefunden, diesen kreis loeschen, und forschleife aufhoeren
                        del circles[index][inder]
                        break 
                    inder+=1
                break # sobald richtige region gefunden, for schleife aufhoeren...
            index+=1 #...anaonsten weitersuchen
    
    def update_drawing(self):
        cvImg=full.copy() 
        for reg_index in xrange(num_regions):
            if circles[reg_index] is not None:
                for circ in circles[reg_index]:
                    cv2.circle(cvImg,(circ[0],circ[1]),circ[2],50,1)
        
        height, width= cvImg.shape
        bytearr=cvImg.data
        qImg = QtGui.QImage(bytearr, width, height, QtGui.QImage.Format_Indexed8)
        self.positionQLabel.setPixmap(QtGui.QPixmap.fromImage(qImg))# zeichne q img aufs label drauf
        
    def assign_region(self):
        global radii,circles
        startpos=self.xc,self.yc
        endpos=startpos
        foliant=full.copy()
        for reg_index in xrange(num_regions):
            if circles[reg_index] is not None:
                for circ in circles[reg_index]:
                    cv2.circle(foliant,(circ[0],circ[1]),circ[2],50,1)
        while self.down:
            QtGui.QApplication.processEvents()
            cvImg=foliant.copy()
            endpos=self.xc,self.yc
            sleep(0.01)
            midpoint=np.divide(np.add(startpos,endpos),2)
            diff=np.subtract(startpos,endpos)
            radius=(np.sqrt(diff[0]*diff[0]+diff[1]*diff[1])/2).astype(np.uint16)
            cv2.circle(cvImg,(midpoint[0],midpoint[1]),radius,50,1)
            height, width= cvImg.shape
            bytearr=cvImg.data
            qImg = QtGui.QImage(bytearr, width, height, QtGui.QImage.Format_Indexed8)
            self.positionQLabel.setPixmap(QtGui.QPixmap.fromImage(qImg))
            if self.down ==False:
                index=0
                for reg in regions:
                   
                    if reg[midpoint[1],midpoint[0]]!=0:
                        
                        radii[index]=radius
                        break
                    index+=1
            
        print "regional zugeschriebene Radien: {} ".format(radii) # hier kommt spaeter ne zeile hin, die die zugewiesenen radien an den kreisdetektor weitergibt
            
            
            
        
#---keine ahnung warum man ne daemliche qapplication starten muss, ihr wisst das besser        
if QtGui.QApplication.instance() is not None:
    myQApplication=QtGui.QApplication.instance()
else: 
    myQApplication = QtGui.QApplication(sys.argv)


myQTestWidget = QCustomWidget()
myQTestWidget.show()
myQApplication.exec_()
