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_())
"""