Exemple #1
0
    def load_iris(self):
        #load a file using the widget
        name, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, 'Load Iris Position and Diameter', '',
            "Image files (*.png *.jpg *.jpeg *.tif *.tiff *.PNG *.JPG *.JPEG *.TIF *.TIFF)"
        )

        if not name:
            pass
        else:
            #if windows then transform / to \ (python stuffs)
            name = os.path.normpath(name)
            #if the measurements window is open then close it, the measures will be updated with the new eyes position
            if self._new_window is not None:
                self._new_window.close()

            #if the photo was already processed then get the information for the
            #txt file, otherwise process the photo using the landmark ans pupil
            #localization algorithms
            file_txt = name[:-4]
            file_txt = (file_txt + '.txt')
            if os.path.isfile(file_txt):
                shape, lefteye, righteye, _ = get_info_from_txt(file_txt)

                dx_left = lefteye[0] - shape[27, 0]
                dy_left = shape[27, 1] - lefteye[1]

                dx_right = shape[27, 0] - righteye[0]
                dy_right = shape[27, 1] - righteye[1]

                self.displayImage._lefteye = [
                    self.displayImage._shape[27, 0] + dx_left,
                    self.displayImage._shape[27, 1] - dy_left, lefteye[2]
                ]
                self.displayImage._righteye = [
                    self.displayImage._shape[27, 0] - dx_right,
                    self.displayImage._shape[27, 1] - dy_right, lefteye[2]
                ]
                self.displayImage.set_update_photo()

            else:
                QtWidgets.QMessageBox.warning(
                    self, "Warning",
                    "Iris information for this photograph is not avaliable",
                    QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
Exemple #2
0
    def validate_exit(self):
        exit = True
        #save landmarks file if not available
        if self.displayImage._shape is not None:  # only save if there is a shape
            file_txt = self._file_name[0:-4] + '.txt'
            if not (os.path.isfile(file_txt)):
                #the file doesn'e exists, save it
                save_txt_file(self._file_name, self.displayImage._shape,
                              self.displayImage._lefteye,
                              self.displayImage._righteye,
                              self.displayImage._boundingbox)
            else:
                #the is a file available, compare with current values and save only if there are changes
                shape, lefteye, righteye, _ = get_info_from_txt(file_txt)

                if (shape == self.displayImage._shape).all() and (
                        lefteye == self.displayImage._lefteye) and (
                            righteye == self.displayImage._righteye):
                    #no change move forward
                    pass
                else:
                    buttonReply = QMessageBox.question(
                        self, 'Save changes',
                        "Landamarks positions were modified.<br>Do you want to save the changes?",
                        QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel,
                        QMessageBox.Cancel)
                    if buttonReply == QMessageBox.Yes:
                        save_txt_file(self._file_name,
                                      self.displayImage._shape,
                                      self.displayImage._lefteye,
                                      self.displayImage._righteye,
                                      self.displayImage._boundingbox)
                    elif buttonReply == QMessageBox.No:
                        pass
                    elif buttonReply == QMessageBox.Cancel:
                        exit = False

            return exit
Exemple #3
0
    def load_file(self, name):

        #        #load a file using the widget
        #        name,_ = QtWidgets.QFileDialog.getOpenFileName(
        #                self,'Load Image',
        #                '',"Image files (*.png *.jpg *.jpeg *.tif *.tiff *.PNG *.JPG *.JPEG *.TIF *.TIFF)")
        #
        #        if not name:
        #            pass
        #        else:
        #the user will load an single image so get rid of Patient and the
        # changephotoAction in the toolbar
        self._Patient = None

        #if windows then transform / to \ (python stuffs)
        name = os.path.normpath(name)
        self._file_name = name
        #if the measurements window is open then close it
        if self._new_window is not None:
            self._new_window.close()
        #load image
        self.displayImage._opencvimage = cv2.imread(name)

        #if the photo was already processed then get the information for the
        #txt file, otherwise process the photo using the landmark ans pupil
        #localization algorithms
        file_txt = name[:-4]
        file_txt = (file_txt + '.txt')
        if os.path.isfile(file_txt):
            shape, lefteye, righteye, boundingbox = get_info_from_txt(file_txt)
            self.displayImage._lefteye = lefteye
            self.displayImage._righteye = righteye
            self.displayImage._shape = shape
            self.displayImage._boundingbox = boundingbox
            self.displayImage._points = None
            self.displayImage.update_view()
        else:
            #if the image is too large then it needs to be resized....
            h, w, d = self.displayImage._opencvimage.shape

            #if the image is too big then we need to resize it so that the landmark
            #localization process can be performed in a reasonable time
            self._Scale = 1  #start from a clear initial scale
            if h > 1500 or w > 1500:
                if h >= w:
                    h_n = 1500
                    self._Scale = h / h_n
                    w_n = int(np.round(w / self._Scale, 0))
                    #self.displayImage._opencvimage=cv2.resize(self.displayImage._opencvimage, (w_n, h_n), interpolation=cv2.INTER_AREA)
                    temp_image = cv2.resize(self.displayImage._opencvimage,
                                            (w_n, h_n),
                                            interpolation=cv2.INTER_AREA)
                    #self._image = image
                else:
                    w_n = 1500
                    self._Scale = w / w_n
                    h_n = int(np.round(h / self._Scale, 0))
                    #self.displayImage._opencvimage=cv2.resize(self.displayImage._opencvimage, (w_n, h_n), interpolation=cv2.INTER_AREA)
                    temp_image = cv2.resize(self.displayImage._opencvimage,
                                            (w_n, h_n),
                                            interpolation=cv2.INTER_AREA)
                    #self._image = image

#                    #now that the image has been reduced, ask the user if the image
#                    #should be saved for continue the processing, otherwise the
#                    #processing cannot continue with the large image
#
#                    #get the image name (separete it from the path)
#                    delimiter = os.path.sep
#                    split_name=name.split(delimiter)
#
#                    #the variable 'name' contains the file name and the path, we now
#                    #get the file name and assign it to the photo object
#                    file_name = split_name[-1]
#                    new_file_name = file_name[:-4]+'_small.png'
#
#                    choice = QtWidgets.QMessageBox.information(self, 'Large Image',
#                            'The image is too large to process.\n\nPressing OK will create a new file\n%s\nin the current folder. This file will be used for processing.\nOtherwise, click Close to finalize the App.'%new_file_name,
#                            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Close, QtWidgets.QMessageBox.Ok)
#
#                    if choice == QtWidgets.QMessageBox.Close :
#                        self.close()
#                        app.exec_()
#                    else:
#                        #create a new, smaller image and use that for processing
#                        name = name[:-4]+'_small.png'
#                        self._file_name = name
#                        cv2.imwrite(name,self.displayImage._opencvimage)
            else:
                #the image is of appropiate dimensions so no need for modification
                temp_image = self.displayImage._opencvimage.copy()
                #pass

            #get the landmarks using dlib, and the and the iris
            #using Dougman's algorithm
            #This is done in a separate thread to prevent the gui from
            #freezing and crashing

            #create worker, pass the image to the worker
            #self.landmarks = GetLandmarks(self.displayImage._opencvimage)
            self.landmarks = GetLandmarks(temp_image)
            #move worker to new thread
            self.landmarks.moveToThread(self.thread_landmarks)
            #start the new thread where the landmark processing will be performed
            self.thread_landmarks.start()
            #Connect Thread started signal to Worker operational slot method
            self.thread_landmarks.started.connect(self.landmarks.getlandmarks)
            #connect signal emmited by landmarks to a function
            self.landmarks.landmarks.connect(self.ProcessShape)
            #define the end of the thread
            self.landmarks.finished.connect(self.thread_landmarks.quit)
Exemple #4
0
    def Process_File(self):
        
        #put some info in the appropiate place
        self.InfoPhotograph._file_name = self._ImageAddress
        self.InfoPhotograph._photo = cv2.imread(self._ImageAddress)
        
        #split the file name from its extension
        file_name,extension = os.path.splitext(self.InfoPhotograph._file_name)
        delimiter = os.path.sep
        name=file_name.split(delimiter)

        self.InfoPhotograph._name =  name[-1] #keep only the last portion (the rest is the physical address of the file)
        self.InfoPhotograph._extension = extension[1:]
        self.InfoPhotograph._ID = self.WidgetName
        
        if self.WidgetName == "Rest":
            self.InfoPhotograph._Tag = "Rest"
        elif self.WidgetName == "SmallSmile":
            self.InfoPhotograph._Tag = "Best Smile"
        elif self.WidgetName == "LargeSmile":
            self.InfoPhotograph._Tag = "Biggest Smile"
        elif self.WidgetName == "EyeBrow":   
            self.InfoPhotograph._Tag = "Brow Elevation"
        elif self.WidgetName == "EyeClosureGently":   
            self.InfoPhotograph._Tag = "Gentle Eye Closure"
        elif self.WidgetName == "EyeClosureTight": 
            self.InfoPhotograph._Tag = "Tight Eye Closure"
        elif self.WidgetName == "PuckeringLips":    
            self.InfoPhotograph._Tag = "Pucker Lips"
        elif self.WidgetName == "DentalShow":     
            self.InfoPhotograph._Tag = "Show Teeth"

        #if the photo was already processed then get the information for the
        #txt file, otherwise process the photo using the landmark ans pupil
        #localization algorithms 
        name = os.path.normpath(self._ImageAddress)
        file_txt=name[:-4]
        file_txt = (file_txt + '.txt')
        if os.path.isfile(file_txt):
            shape,lefteye,righteye,boundingbox = get_info_from_txt(file_txt)
            self.InfoPhotograph._lefteye = lefteye
            self.InfoPhotograph._righteye = righteye 
            self.InfoPhotograph._shape = shape
            self.InfoPhotograph._boundingbox = boundingbox
            self.InfoPhotograph._points = None
            
            
            #we now have all the info, emit the information to the main widget
            self.dropped.emit(self.InfoPhotograph)    
        else:
            #if the image is too large then it needs to be resized....
            h,w,d = self.InfoPhotograph._photo.shape

            #if the image is too big then we need to resize it so that the landmark 
            #localization process can be performed in a reasonable time 
            self._Scale = 1  #start from a clear initial scale
            if h > 1500 or w > 1500 :
                if h >= w :
                    h_n = 1500
                    self._Scale = h/h_n
                    w_n = int(np.round(w/self._Scale,0))
                    temp_image = cv2.resize(self.InfoPhotograph._photo, (w_n, h_n), interpolation=cv2.INTER_AREA)
                else :
                    w_n = 1500
                    self._Scale = w/w_n
                    h_n = int(np.round(h/self._Scale,0))
                    temp_image = cv2.resize(self.InfoPhotograph._photo, (w_n, h_n), interpolation=cv2.INTER_AREA)

            else:
                #the image is of appropiate dimensions so no need for modification
                temp_image = self.InfoPhotograph._photo.copy()
                #pass
            
            #get the landmarks using dlib, and the and the iris 
            #using Dougman's algorithm  
            #This is done in a separate thread to prevent the gui from 
            #freezing and crashing
            

            #create worker, pass the image to the worker
            #self.landmarks = GetLandmarks(self.displayImage._opencvimage)
            self.landmarks = GetLandmarks(temp_image, self._ModelName)
            #move worker to new thread
            self.landmarks.moveToThread(self.thread_landmarks)
            #start the new thread where the landmark processing will be performed
            self.thread_landmarks.start() 
            #Connect Thread started signal to Worker operational slot method
            self.thread_landmarks.started.connect(self.landmarks.getlandmarks)
            #connect signal emmited by landmarks to a function
            self.landmarks.landmarks.connect(self.ProcessShape)
            #define the end of the thread
            self.landmarks.finished.connect(self.thread_landmarks.quit) 
Exemple #5
0
    def picture_loaded(self, local_address, WidgetName):
        
        
        self.WidgetName = WidgetName
        pixmap = QtGui.QPixmap(local_address)
        self.setPhoto(pixmap)
        self._hasImage = True  #indicate that there is an image
        self._ImageAddress = os.path.normpath(local_address) #store the image address in a class variable
        
        file_name,extension = os.path.splitext(local_address)
        
        
        #put some info in the appropiate place
        self.InfoPhotograph._file_name = self._ImageAddress
        self.InfoPhotograph._photo = cv2.imread(self._ImageAddress)
        
        #split the file name from its extension
        file_name,extension = os.path.splitext(self.InfoPhotograph._file_name)
        delimiter = os.path.sep
        name=file_name.split(delimiter)

        self.InfoPhotograph._name =  name[-1] #keep only the last portion (the rest is the physical address of the file)
        self.InfoPhotograph._extension = extension[1:]
        self.InfoPhotograph._ID = self.WidgetName
        
        if self.WidgetName == "Rest":
            self.InfoPhotograph._Tag = "Rest"
        elif self.WidgetName == "SmallSmile":
            self.InfoPhotograph._Tag = "Best Smile"
        elif self.WidgetName == "LargeSmile":
            self.InfoPhotograph._Tag = "Biggest Smile"
        elif self.WidgetName == "EyeBrow":   
            self.InfoPhotograph._Tag = "Brow Elevation"
        elif self.WidgetName == "EyeClosureGently":   
            self.InfoPhotograph._Tag = "Gentle Eye Closure"
        elif self.WidgetName == "EyeClosureTight": 
            self.InfoPhotograph._Tag = "Tight Eye Closure"
        elif self.WidgetName == "PuckeringLips":    
            self.InfoPhotograph._Tag = "Pucker Lips"
        elif self.WidgetName == "DentalShow":     
            self.InfoPhotograph._Tag = "Show Teeth"
            
        self.InfoPhotograph._lefteye = None
        self.InfoPhotograph._righteye = None 
        self.InfoPhotograph._shape = None
        self.InfoPhotograph._boundingbox = None
        self.InfoPhotograph._points = None
        
        self.InfoPhotograph._OpenEmotrics = False
                
                
        #now verify if there is a txt file already avaliable 
        if os.path.isfile(file_name+'.txt'):
            #if the txt file already exists then the information 
            #is extracted and placed in memory  
            shape,lefteye,righteye,boundingbox = get_info_from_txt(file_name+'.txt')
            self.InfoPhotograph._lefteye = lefteye
            self.InfoPhotograph._righteye = righteye 
            self.InfoPhotograph._shape = shape
            self.InfoPhotograph._boundingbox = boundingbox
            self.InfoPhotograph._points = None
            
            #set background green to inform that shape information is already avaliable
            self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(204,255,204)))
            
            
        
        #we now have all the info, emit the information to the main widget
        self.dropped.emit(self.InfoPhotograph)    
Exemple #6
0
 def dropEvent(self, event):
     if event.mimeData().hasUrls():           
         for url in event.mimeData().urls():               
             local_address = str(url.toLocalFile())                
             file_name,extension = os.path.splitext(local_address)
             if extension in self._validextensions:
                 event.setDropAction(QtCore.Qt.CopyAction) 
                 #conditiones meet, accept event and set background 
                 event.accept()
                 self.setBackground()
                 
                 pixmap = QtGui.QPixmap(local_address)
                 self.setPhoto(pixmap)
                 self._hasImage = True  #indicate that there is an image
                 self._ImageAddress = os.path.normpath(local_address) #store the image address in a class variable
                 
                 
                 #verify is a new patient was added comparing the address of the existing images with the one that was dropeed 
                 if self.InfoPhotograph._file_name == self._ImageAddress:
                     #this is not a new patient, the user is just adding the same image ...
                     self.InfoPhotograph._NewPatient = False
                 else:
                     #this is a new patient, we have to inform about this to the main window
                     self.InfoPhotograph._NewPatient = True 
                 
                 #put some info in the appropiate place
                 self.InfoPhotograph._file_name = self._ImageAddress
                 self.InfoPhotograph._photo = cv2.imread(self._ImageAddress)
                 
                 #split the file name from its extension
                 file_name,extension = os.path.splitext(self.InfoPhotograph._file_name)
                 delimiter = os.path.sep
                 name=file_name.split(delimiter)
         
                 self.InfoPhotograph._name =  name[-1] #keep only the last portion (the rest is the physical address of the file)
                 self.InfoPhotograph._extension = extension[1:]
                 self.InfoPhotograph._ID = self.WidgetName
                 
                 if self.WidgetName == "Rest":
                     self.InfoPhotograph._Tag = "Rest"
                 elif self.WidgetName == "SmallSmile":
                     self.InfoPhotograph._Tag = "Best Smile"
                 elif self.WidgetName == "LargeSmile":
                     self.InfoPhotograph._Tag = "Biggest Smile"
                 elif self.WidgetName == "EyeBrow":   
                     self.InfoPhotograph._Tag = "Brow Elevation"
                 elif self.WidgetName == "EyeClosureGently":   
                     self.InfoPhotograph._Tag = "Gentle Eye Closure"
                 elif self.WidgetName == "EyeClosureTight": 
                     self.InfoPhotograph._Tag = "Tight Eye Closure"
                 elif self.WidgetName == "PuckeringLips":    
                     self.InfoPhotograph._Tag = "Pucker Lips"
                 elif self.WidgetName == "DentalShow":     
                     self.InfoPhotograph._Tag = "Show Teeth"
                     
                 self.InfoPhotograph._lefteye = None
                 self.InfoPhotograph._righteye = None 
                 self.InfoPhotograph._shape = None
                 self.InfoPhotograph._boundingbox = None
                 self.InfoPhotograph._points = None
                 
                 self.InfoPhotograph._OpenEmotrics = False
                 
                 
                 #now verify if there is a txt file already avaliable 
                 if os.path.isfile(file_name+'.txt'):
                     #if the txt file already exists then the information 
                     #is extracted and placed in memory 
             
                     shape,lefteye,righteye,boundingbox = get_info_from_txt(file_name+'.txt')
                     self.InfoPhotograph._lefteye = lefteye
                     self.InfoPhotograph._righteye = righteye 
                     self.InfoPhotograph._shape = shape
                     self.InfoPhotograph._boundingbox = boundingbox
                     self.InfoPhotograph._points = None
                     
                     #set background green to inform that shape information is already avaliable
                     self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(204,255,204)))
                     
                     
                 #we now have all the info, emit the information to the main widget
                 self.dropped.emit(self.InfoPhotograph)    
                 
             else:
                 event.ignore()
     else:
         event.ignore()   
Exemple #7
0
def compute_health_score(path_, Healthy_Side, pandas_df=None):

    path_ = path_
    all_Files = os.listdir(path_)
    all_Files.sort()
    ext_txt = ('.txt')
    Files = [i for i in all_Files if i.endswith(tuple(ext_txt))]
    ext_jpg = ('.jpg')
    Images = [i for i in all_Files if i.endswith(tuple(ext_jpg))]

    shape = []
    lefteye = []
    righteye = []
    boundingbox = []
    for file in Files:
        try:
            shape_, lefteye_, righteye_, boundingbox_ = get_info_from_txt(
                os.path.join(path_, file))
        except:
            print(os.path.join(path_, file))
            return

        shape.append(shape_)
        lefteye.append(lefteye_)
        righteye.append(righteye_)
        boundingbox.append(boundingbox_)

    CalibrationType = 'Iris'
    CalibrationValue = 11.77
    LeftRest, RightRest, _, _, IPrest = get_measurements_from_data(
        shape[0], lefteye[0], righteye[0], CalibrationType, CalibrationValue)
    LeftEyeBrow, RightEyeBrow, _, _, IPEyeBrow = get_measurements_from_data(
        shape[1], lefteye[1], righteye[1], CalibrationType, CalibrationValue)
    LeftEyeClosureGently, RightEyeClosureGently, _, _, IPEyeClosureGently = get_measurements_from_data(
        shape[2], lefteye[2], righteye[2], CalibrationType, CalibrationValue)
    LeftEyeClosureTight, RightEyeClosureTight, _, _, IPEyeClosureTight = get_measurements_from_data(
        shape[3], lefteye[3], righteye[3], CalibrationType, CalibrationValue)
    LeftSmallSmile, RightSmallSmile, _, _, IPSmallSmile = get_measurements_from_data(
        shape[4], lefteye[4], righteye[4], CalibrationType, CalibrationValue)
    LeftLargeSmile, RightLargeSmile, _, _, IPLargeSmile = get_measurements_from_data(
        shape[5], lefteye[5], righteye[5], CalibrationType, CalibrationValue)
    LeftPuckeringLips, RightPuckeringLips, _, _, IPPuckeringLips = get_measurements_from_data(
        shape[6], lefteye[6], righteye[6], CalibrationType, CalibrationValue)
    LeftDentalShow, RightDentalShow, _, _, IPDentalShow = get_measurements_from_data(
        shape[7], lefteye[7], righteye[7], CalibrationType, CalibrationValue)

    ##Static Measures
    # I'm following Tessa's nomenclature

    # 1) EyeBrow Elevation at rest
    a_left, a_right = LeftRest.BrowHeight, RightRest.BrowHeight
    if Healthy_Side == 'Right':
        Brow_at_rest = a_left / a_right
    else:
        Brow_at_rest = a_right / a_left

    Brow_at_rest = np.round(Brow_at_rest * 100, 1)

    # 2) Palpebral Fissure width at rest
    c_left, c_right = LeftRest.PalpebralFissureHeight, RightRest.PalpebralFissureHeight

    if Healthy_Side == 'Right':
        PalpebralFissure_at_rest = c_right / c_left
    else:
        PalpebralFissure_at_rest = c_left / c_right

    PalpebralFissure_at_rest = np.round(PalpebralFissure_at_rest * 100, 1)

    # 3) Oral commissure at rest
    e_right, d_right = np.sin((RightRest.SmileAngle - 90) * np.pi /
                              180) * RightRest.CommissureExcursion, np.cos(
                                  (RightRest.SmileAngle - 90) * np.pi /
                                  180) * RightRest.CommissureExcursion
    e_left, d_left = np.sin((LeftRest.SmileAngle - 90) * np.pi /
                            180) * LeftRest.CommissureExcursion, np.cos(
                                (LeftRest.SmileAngle - 90) * np.pi /
                                180) * LeftRest.CommissureExcursion
    if Healthy_Side == 'Right':
        #e_left is the disease side
        if e_left < e_right and e_left > 0:
            OralCommissure_at_rest = 1 - ((e_right - e_left) / e_right)
        else:
            OralCommissure_at_rest = d_left / d_right
    else:
        #e_right is the disease side
        if e_right < e_left and e_right > 0:
            OralCommissure_at_rest = 1 - ((e_left - e_right) / e_left)
        else:
            OralCommissure_at_rest = d_right / d_left

    OralCommissure_at_rest = np.round(OralCommissure_at_rest * 100, 1)

    #Static_Score = np.array([abs(100-Brow_at_rest), abs(100-PalpebralFissure_at_rest), abs(100-OralCommissure_at_rest )]).sum()
    #np.round(Static_Score,1)

    ##Dynamic Measures
    # 4) Brow Elevation
    b_left, b_right = LeftEyeBrow.BrowHeight, RightEyeBrow.BrowHeight
    if Healthy_Side == 'Right':
        EyeBrowElevation = (b_left - a_left) / (b_right - a_right)
    else:
        EyeBrowElevation = (b_right - a_right) / (b_left - a_left)

    EyeBrowElevation = np.round(EyeBrowElevation * 100, 1)

    # 5)Eye closure gentle
    g_left_gentle, g_right_gentle = LeftEyeClosureGently.PalpebralFissureHeight, RightEyeClosureGently.PalpebralFissureHeight
    if g_left_gentle < 1: g_left_gentle = 0
    if g_right_gentle < 1: g_right_gentle = 0
    #g might be negative (measurement errors)
    if Healthy_Side == 'Right':
        GentleEyeClosure = (c_left - abs(g_left_gentle)) / c_left
    else:
        GentleEyeClosure = (c_right - abs(g_right_gentle)) / c_right

    GentleEyeClosure = np.round(GentleEyeClosure * 100, 1)

    # 6)Eye closure full
    g_left_full, g_right_full = LeftEyeClosureTight.PalpebralFissureHeight, RightEyeClosureTight.PalpebralFissureHeight
    if g_left_full < 1: g_left_full = 0
    if g_right_full < 1: g_right_full = 0
    if Healthy_Side == 'Right':
        FullEyeClosure = (c_left - abs(g_left_full)) / c_left
    else:
        FullEyeClosure = (c_right - abs(g_right_full)) / c_right

    FullEyeClosure = np.round(FullEyeClosure * 100, 1)

    # 6) Oral Commissure with Smile
    # question for Tessa -> Is this with small or large smile? I'll do it with large smile for the moment
    f_left, f_right = LeftRest.CommissureExcursion, RightRest.CommissureExcursion
    h_left, h_right = LeftLargeSmile.CommissureExcursion, RightLargeSmile.CommissureExcursion
    #if with small smile, then comment above line an uncomment line below
    # h_left, h_right = LeftSmallSmile.CommissureExcursion, RightSmallSmile.CommissureExcursion
    if Healthy_Side == 'Right':
        OralCommissureWithSmile = (h_left - f_left) / (h_right - f_right)
    else:
        OralCommissureWithSmile = (h_right - f_right) / (h_left - f_left)

    OralCommissureWithSmile = np.round(OralCommissureWithSmile * 100, 1)

    #7) Lower Lip EEE

    j_left, j_right = LeftDentalShow.DentalShow, RightDentalShow.DentalShow
    if Healthy_Side == 'Right':
        #making sure that it will work if j_right is zero
        try:
            LowerLipEEE = j_left / j_right
        except:
            LowerLipEEE = np.nan
    else:
        #making sure that it will work if j_left is zero
        try:
            LowerLipEEE = j_right / j_left
        except:
            LowerLipEEE = np.nan

    LowerLipEEE = np.round(LowerLipEEE * 100, 1)

    #Dynamic_Score = np.array([abs(100-EyeBrowElevation), abs(100-GentleEyeClosure), abs(100-FullEyeClosure), abs(100-OralCommissureWithSmile), abs(100-LowerLipEEE)]).sum()
    #np.round(Dynamic_Score,1)

    ##Synkineis Measurements
    #Ocular synkinesis
    k1_left, k1_right = LeftLargeSmile.PalpebralFissureHeight, RightLargeSmile.PalpebralFissureHeight
    k2_left, k2_right = LeftPuckeringLips.PalpebralFissureHeight, RightPuckeringLips.PalpebralFissureHeight
    if Healthy_Side == 'Right':
        OcularSynkinesis1 = k1_left / k1_right
        OcularSynkinesis2 = k2_left / k2_right
    else:
        OcularSynkinesis1 = k1_right / k1_left
        OcularSynkinesis2 = k2_right / k2_left

    if OcularSynkinesis1 <= OcularSynkinesis2:
        OcularSynkinesis = OcularSynkinesis1
    else:
        OcularSynkinesis = OcularSynkinesis2

    OcularSynkinesis = np.round(OcularSynkinesis * 100, 1)

    #apply corrections to remove everything less than zero
    if Brow_at_rest < 0: Brow_at_rest = 0
    if PalpebralFissure_at_rest < 0: PalpebralFissure_at_rest = 0
    if OralCommissure_at_rest < 0: OralCommissure_at_rest = 0
    if EyeBrowElevation < 0: EyeBrowElevation = 0
    if GentleEyeClosure < 0: GentleEyeClosure = 0
    if FullEyeClosure < 0: FullEyeClosure = 0
    if OralCommissureWithSmile < 0: OralCommissureWithSmile = 0
    if LowerLipEEE < 0: LowerLipEEE = 0
    if OcularSynkinesis < 0: OcularSynkinesis = 0

    #    ##Computing the score based on Tessa's idea
    #    if Brow_at_rest<= 100:
    score_brow_rest = 100 - abs(100 - Brow_at_rest)
    score_PalpebralFissure_rest = 100 - abs(100 - PalpebralFissure_at_rest)
    score_OralCommissure_rest = 100 - abs(100 - OralCommissure_at_rest)

    score_EyeBrowElevation = 100 - abs(100 - EyeBrowElevation)
    score_GentleEyeClosure = 100 - abs(100 - GentleEyeClosure)
    score_FullEyeClosure = 100 - abs(100 - FullEyeClosure)
    score_OralCommissureWithSmile = 100 - abs(100 - OralCommissureWithSmile)
    score_LowerLipEEE = 100 - abs(100 - LowerLipEEE)

    score_OcularSynkinesis = 100 - abs(100 - OcularSynkinesis)

    print(score_brow_rest, score_PalpebralFissure_rest,
          score_OralCommissure_rest)

    StaticScore = (score_brow_rest + score_PalpebralFissure_rest +
                   score_OralCommissure_rest) / 3
    DynamicScore = (score_EyeBrowElevation + score_GentleEyeClosure +
                    score_FullEyeClosure + score_OralCommissureWithSmile +
                    score_LowerLipEEE) / 5
    SynkinesisScore = score_OcularSynkinesis

    TotalScore = (StaticScore + DynamicScore + SynkinesisScore) / 3
    #StaticScore, DynamicScore, SynkinesisScore ,TotalScore

    if pandas_df is not None:  #Save results in a data frame

        df_columns = [
            'Diagnosis', 'Subject', 'Healthy_Side', 'Eyebrow at Rest',
            'Palpebral Fissure at Rest', 'Oral Commissure at Rest',
            'Static Score', 'Eyebrow Elevation', 'Gentle Eye Closure',
            'Full Eye Closure', 'Oral Commissure with Smile',
            'Lower Lip with EEE', 'Dynamic Score', 'Ocular Synkenisis',
            'Total Score'
        ]

        #create the dataframe and set the index
        if os.path.isfile(pandas_df):  #the dataframe alreasy exists, opne it
            DataFrame = pd.read_csv(pandas_df, index_col=0)
        else:  #the file doesn't exist, create it
            DataFrame = pd.DataFrame(columns=df_columns)

        if 'normal' in path_:
            diag = 'normal'
        elif 'completeflaccid' in path_:
            diag = 'completeflaccid'
        else:
            diag = 'completeSynkinetic'

        subject = path_.split('\\')[-1]

        #datus = [diag, subject, Healthy_Side, Brow_at_rest, PalpebralFissure_at_rest, OralCommissure_at_rest, StaticScore,
        #         EyeBrowElevation, GentleEyeClosure, FullEyeClosure, OralCommissureWithSmile, LowerLipEEE, DynamicScore,
        #         OcularSynkinesis, TotalScore]

        datus = [
            diag, subject, Healthy_Side, Brow_at_rest,
            PalpebralFissure_at_rest, OralCommissure_at_rest, StaticScore,
            score_EyeBrowElevation, score_GentleEyeClosure,
            score_FullEyeClosure, score_OralCommissureWithSmile,
            score_LowerLipEEE, DynamicScore, score_OcularSynkinesis, TotalScore
        ]

        DataFrame = DataFrame.append(pd.Series(datus, index=df_columns),
                                     ignore_index=True)

        DataFrame.to_csv(pandas_df)
Exemple #8
0
    def LoadImage(self,position):
        #load a file using the widget
        name,_ = QFileDialog.getOpenFileName(
                self,'Load Image',
                '',"Image files (*.png *.jpg *.jpeg *.tif *.tiff *.PNG *.JPG *.JPEG *.TIF *.TIFF)")
        if not name:
            pass
        else:
            #if windows then transform / to \ (python stuffs)
            name = os.path.normpath(name)
            #load image into memory 
            self._Photo = cv2.imread(name)
            #is this information going to be the first or second photo, that 
            #information is in the variable 'position'
            self._PhotoPosition = position

            #get the image name (separete it from the path)
            delimiter = os.path.sep
            split_name=name.split(delimiter)
            
            #the variable 'name' contains the file name and the path, we now
            #get the file name and assign it to the photo object
            self._file_name = name
            self._name = split_name[-1]
            
            

            
            #if the photo was already processed then get the information for the
            #txt file, otherwise process the photo using the landmark ans pupil
            #localization algorithms 
            file_txt=name[:-4]
            file_txt = (file_txt + '.txt')
            if os.path.isfile(file_txt):
                shape,lefteye,righteye, boundingbox = get_info_from_txt(file_txt)
                
                #create a temporary photo object and fill its values. This variable
                #contains all the information that will be passed to the main 
                #window 
                temp_photo = PhotoObject()
                temp_photo._file_name = self._file_name
                temp_photo._name = self._name
                temp_photo._photo = self._Photo                
                temp_photo._lefteye = lefteye
                temp_photo._righteye = righteye 
                temp_photo._boundingbox = boundingbox
                temp_photo._shape = shape
                temp_photo._points = None
                #put all the information in the correct place (according to 
                #'position')
                self.AssignPhoto(temp_photo, self._PhotoPosition, 1)
            else:
                                #if the image is too large then it needs to be resized....
                h,w,d = self._Photo.shape

                #if the image is too big then we need to resize it so that the landmark 
                #localization process can be performed in a reasonable time 
                self._Scale = 1
                if h > 1500 or w > 1500 :
                    if h >= w :
                        h_n = 1500
                        self._Scale = h/h_n
                        w_n = int(np.round(w/self._Scale,0))
                        #self._Photo=cv2.resize(self._Photo, (w_n, h_n), interpolation=cv2.INTER_AREA)
                        temp_image = cv2.resize(self._Photo, (w_n, h_n), interpolation=cv2.INTER_AREA)
                        #self._image = image
                    else :
                        w_n = 1500
                        self._Scale = w/w_n
                        h_n = int(np.round(h/self._Scale,0))
                        #self._Photo=cv2.resize(self._Photo, (w_n, h_n), interpolation=cv2.INTER_AREA)
                        temp_image = cv2.resize(self._Photo, (w_n, h_n), interpolation=cv2.INTER_AREA)
                        #self._image = image     
                 
                    
#                    #now that the image has been reduced, ask the user if the image 
#                    #should be saved for continue the processing, otherwise the 
#                    #processing cannot continue with the large image
#                    
#                    #get the image name (separete it from the path)
#                    delimiter = os.path.sep
#                    split_name=name.split(delimiter)
#            
#                    #the variable 'name' contains the file name and the path, we now
#                    #get the file name and assign it to the photo object
#                    file_name = split_name[-1]
#                    new_file_name = file_name[:-4]+'_small.png'
#                    
#                    choice = QtWidgets.QMessageBox.information(self, 'Large Image', 
#                            'The image is too large to process.\n\nPressing OK will create a new file\n%s\nin the current folder. This file will be used for processing.\nOtherwise, click Close to finalize the App.'%new_file_name, 
#                            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Close, QtWidgets.QMessageBox.Ok)
#
#                    if choice == QtWidgets.QMessageBox.Close :
#                        self.close()
#                        app.exec_()
#                    else:
#                        #create a new, smaller image and use that for processing
#                        name = name[:-4]+'_small.png'
#                        self._file_name = name
#                        cv2.imwrite(name,self._Photo)
#                        
#                        self._name = self._name[:-4]+'_small.png'
                else:
                    temp_image = self._Photo.copy()
                    #pass
                
                
                
                
                #get the landmarks using dlib, and the and the iris 
                #using Dougman's algorithm  
                #This is done in a separate thread to prevent the gui from 
                #freezing and crashing
                
                #create worker, pass the image to the worker
                ##self.landmarks = GetLandmarks(self._Photo)
                self.landmarks = GetLandmarks(temp_image, self._ModelName)
                #move worker to new thread
                self.landmarks.moveToThread(self.thread_landmarks)
                #start the new thread where the landmark processing will be performed
                self.thread_landmarks.start() 
                #Connect Thread started signal to Worker operational slot method
                self.thread_landmarks.started.connect(self.landmarks.getlandmarks)
                #connect signal emmited by landmarks to a function
                self.landmarks.landmarks.connect(self.ProcessShape)
                #define the end of the thread
                self.landmarks.finished.connect(self.thread_landmarks.quit)