Unable to close the camera in pyqt5 even though i am able to close the window when i press the back button but camera is still running

Viewed 59

I am Unable to close the camera in pyqt5 even though i am able to close the window when i press the back button but camera is still running. Need Help. I have created two Windows:mainwindow and out_window MainWidow python code is given below:

"""

import sys
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets,QtGui
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog
import resource



from out_window import Ui_OutputDialog

class Ui_Dialog(QDialog):
    
    def __init__(self):
        super(Ui_Dialog, self).__init__()
        loadUi("mainwindow.ui", self)



        self.runButton.clicked.connect(self.runSlot)
        self.dataset.clicked.connect(self.dataSlot)
        
        

        self._new_window = None
        self.Videocapture_ = None
    

    def refreshAll(self):
        """
        Set the text of lineEdit once it's valid
        """
        self.Videocapture_ = "0"

    # @pyqtSlot()
    def runSlot(self):
        """
        Called when the user presses the Run button
        """
        print("Clicked Run")
        self.refreshAll()
        print(self.Videocapture_)
        self.hide()  # hide the main window
        self.outputWindow_()  # Create and open new output window
 
    # @pyqtSlot()
    def dataSlot(self):
        """
        Called when the user presses the Run button
        """
        print("Clicked Run")
        self.refreshAll()
        print(self.Videocapture_)
        self.hide()  # hide the main window
        self.dataWindow_()  # Create and open new output window
    
    def dataWindow_(self):
        """
        Created new window for vidual output of the video in GUI
        """
        self._new_window = Ui_OutputDialog()
        self._new_window.show()
        self._new_window.dataset(self.Videocapture_)
        print("Taking Dataset")

   

    def outputWindow_(self):
        """
        Created new window for vidual output of the video in GUI
        """
        self._new_window = Ui_OutputDialog()
        self._new_window.show()
        self._new_window.startVideo(self.Videocapture_)
        print("Video Played")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Dialog()
    ui.show()
    sys.exit(app.exec_())



"""

Output Window I have created a previous function that is connected to a backBtn.All i want is when i click the back button it should close the current window and all of its functions along with the camera and move back to the previous window.

"""

from turtle import back
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from platform import release
from time import sleep
from xml.etree.ElementTree import tostring
from PyQt5.QtWidgets import QApplication, QDialog
import sys


from PyQt5 import QtCore, QtGui, QtWidgets
from pickle import FRAME
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSlot, QTimer
from PyQt5.QtWidgets import QDialog
import cv2
from cv2 import VideoCapture
import face_recognition
from matplotlib import image
from matplotlib.pyplot import close, show
import numpy as np
import datetime
from datetime import datetime
import os

from scipy.misc import face

# from mainwindow import UI_Dialog

# import mainwindow
# from mainwindow import Ui_Dialog
TOLERANCE = 0.8
FRAME_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = 'cnn'


class Ui_OutputDialog(QDialog):


    def __init__(self):

        # self.capturing = True
        # self.c = cv2.VideoCapture(0)

        super(Ui_OutputDialog, self).__init__()
        loadUi("./outputwindow.ui", self)
        self.image = None
        self.backBtn.clicked.connect(lambda:self.close())
        self.backBtn.clicked.connect(self.previous)
    
    
    
        
    def previous(self):
        from mainwindow import Ui_Dialog
        self.back = Ui_Dialog()
        self.back.show()
        


    
        
        


  
    
   
        

        
        

    # @pyqtSlot()
    def dataset(self,camera_name):
        # self.timer = QTimer(self)  # Create Timer
        
       
    
        face_classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
        def face_crop(img):
            gray = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
            faces = face_classifier.detectMultiScale(gray,1.3,5)
            
            if faces is ():
                return None
            for (x,y,w,h) in faces:
                cropped_face = img[y:y+h, x:x+w]
            return cropped_face
    
        newUser = input('Enter New User Name: ')
        if newUser:
            parent_path = 'known_faces/'
            joined = os.path.join(parent_path,newUser)
            os.mkdir(joined)
  
        video_capture = cv2.VideoCapture(0)
        img_id = 0
        while True:
            ret,frame = video_capture.read()
            # Capture frame-by-frame
            frame = cv2.flip(frame,1)
            if face_crop(frame) is not None:
                img_id+=1
                face = cv2.resize(face_crop(frame),(200,200))
                file_name_path = f"{joined}/"+str(img_id)+'.jpg'
                cv2.imwrite(file_name_path,face)
                cv2.putText(face, str(img_id),(50,50),cv2.FONT_HERSHEY_COMPLEX, 2,(0,255,0),2)
    
                qformat = QImage.Format_Indexed8
                if len(face.shape) == 3:
                    if face.shape[2] == 4:
                        qformat =QImage.Format_RGBA888
                    else:
                        qformat = QImage.Format_RGB888
                face = QImage(face, face.shape[1],face.shape[0],qformat)
                face = face.rgbSwapped()
                self.imgLabel.setPixmap(QPixmap.fromImage(face))
                self.imgLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
            # self.timer.timeout.connect(self.update_frame)  # Connect timeout to the output function
            # self.timer.start(40)  # emit the timeout() signal at x=40ms
    
            if cv2.waitKey(1)==27 or img_id == 20:
                break
                
        cv2.destroyAllWindows()
        video_capture.release()
        


    
            


    


    # @pyqtSlot()
    def startVideo(self, camera_name):
        """
        :param camera_name: link of camera or usb camera
        :return:
        """
        if len(camera_name) == 1:
            self.capture = cv2.VideoCapture(int(camera_name))
        else:
            self.capture = cv2.VideoCapture(camera_name)
        self.timer = QTimer(self)  # Create Timer
        
        
        
        
        KNOWN_FACES_DIR = 'known_faces'
        if not os.path.exists(KNOWN_FACES_DIR):
            os.mkdir(KNOWN_FACES_DIR)
        # known face encoding and known face name list
        images = []
        self.known_names = []
        self.known_faces = []
        attendance_list = os.listdir(KNOWN_FACES_DIR)
        # print(attendance_list)
        # Start from here
        for name in os.listdir(KNOWN_FACES_DIR):
        
            # Next we load every file of faces of known person
            for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):

                # Load an image
                image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')

                # Get 128-dimension face encoding
                # Always returns a list of found faces, for this purpose we take first face only (assuming one face per image as you can't be twice on one image)
                boxes = face_recognition.face_locations(image)
                encoding = face_recognition.face_encodings(image)[0]
                # encoding = face_recognition.face_encodings(image,boxes)[0]

                # Append encodings and name
                self.known_faces.append(encoding)
                self.known_names.append(name)
        print('Processing unknown faces...')



    # Below one is working


        
        self.timer.timeout.connect(self.update_frame)  # Connect timeout to the output function
        self.timer.start(40)  # emit the timeout() signal at x=40ms

    def face_rec_(self, frame, known_faces, known_names):
        """
        :param frame: frame from camera
        :param known_faces: known face encoding
        :param known_names: known face names
        :return:
        """
        # csv
        def mark_attendance(name):
            """
            :param name: detected face known or unknown one
            :return:
            """
            with open('Attendance.csv', 'r+') as f:
                
                myDataList = f.readlines()
                nameList = []
                for line in myDataList:
                    entry = line.split(',')
                    nameList.append(entry[0])
                if name not in nameList:
                    now = datetime.now()
                    dtString = now.strftime('%H:%M:%S')
                    f.writelines(f'\n{name},{dtString}')

        
        locations = face_recognition.face_locations(frame,number_of_times_to_upsample=1, model="hog")
        encodings = face_recognition.face_encodings(frame,locations)
    
        for face_encoding,face_location in zip(encodings,locations):
            results = face_recognition.compare_faces(known_faces,face_encoding,TOLERANCE)
            faceDis = face_recognition.face_distance(known_faces,face_encoding)
            #print(faceDis)
            matchIndex = np.argmin(faceDis)
    
            if results[matchIndex]:
                if faceDis[matchIndex]< 0.50:
                    name = known_names[matchIndex].upper()
                    mark_attendance(name)
                else:
                    name = 'Unknown'
                    y1, x2, y2, x1 = face_location
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.rectangle(frame, (x1, y2 - 35), (x2, y2), (0, 0, 255), cv2.FILLED)
                    cv2.putText(frame, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)

                print(name)
                y1,x2,y2,x1 = face_location
                y1, x2, y2, x1 = y1*4,x2*4,y2*4,x1*4
                cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)
                cv2.rectangle(frame,(x1,y2-35),(x2,y2),(0,255,0),cv2.FILLED)
                cv2.putText(frame,name,(x1+6,y2-6),cv2.FONT_HERSHEY_COMPLEX,1,(255,255,255),2)

        return frame
   
        

    def update_frame(self):
        ret, self.image = self.capture.read()
   
        self.displayImage(self.image, self.known_faces, self.known_names, 1)

    def displayImage(self, image, known_faces, known_names, window=1):
        """
        :param image: frame from camera
        :param known_faces: known face encoding list
        :param known_names: known face names
        :param window: number of window
        :return:
        """
        image = cv2.resize(image, (640, 480))
        try:
            image = self.face_rec_(image, known_faces, known_names)
        except Exception as e:
            print(e)
        qformat = QImage.Format_Indexed8
        if len(image.shape) == 3:
            if image.shape[2] == 4:
                qformat = QImage.Format_RGBA8888
            else:
                qformat = QImage.Format_RGB888
        outImage = QImage(image, image.shape[1], image.shape[0], image.strides[0], qformat)
        outImage = outImage.rgbSwapped()

        if window == 1:
            self.imgLabel.setPixmap(QPixmap.fromImage(outImage))
            self.imgLabel.setScaledContents(True)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_OutputDialog()
    ui.show()
    sys.exit(app.exec_())

"""

0 Answers
Related