class EmailUI(QtWidgets.QMainWindow, Ui_Form): def __init__(self): super(EmailUI, self).__init__() self.setupUi(self) self.logger = Logging() self.read_email_conf() # 保存邮箱配置 def save_email_conf(self): receiver_email = self.lineEdit.text() sender = self.lineEdit_2.text() receiver = self.lineEdit_3.text() if not (receiver_email and sender and receiver): QMessageBox.warning(self, '警告', '有字段为空') self.logger.log_error('email info save filed') return conf = { 'receiver_email': receiver_email, 'sender': sender, 'receiver': receiver } with open('email_conf/conf.yaml', 'w', encoding='utf-8') as f: f.write(str(conf)) QMessageBox.about(self, 'info', '保存成功') self.logger.log_info('email info save success') # 读取邮箱配置 def read_email_conf(self): if os.path.exists('email_conf/conf.yaml'): with open('email_conf/conf.yaml', 'r', encoding='utf-8') as f: conf = eval(f.read()) if conf: self.lineEdit.setText(conf['receiver_email']) self.lineEdit_2.setText(conf['sender']) self.lineEdit_3.setText(conf['receiver']) else: return else: return
class Mail: def __init__(self): self.mail_host = 'smtp.qq.com' self.mail_pass = '' # 授权码 self.sender = '' # 发送人 self.receiver, self.sender_name, self.receiver_name = self.read_conf() self.logger = Logging() # 读取配置 def read_conf(self): with open('E:/Opencv/FaceRecognition_demo/email_conf/conf.yaml', 'r', encoding='utf-8') as f: conf = eval(f.read()) return [conf['receiver_email']], conf['sender'], conf['receiver'] # 发邮件 def send(self, text): # 邮件内容 content = text message = MIMEText(content, 'plain', 'utf-8') # 寄件人和收件人 message['From'] = Header(self.sender_name, 'utf-8') message['To'] = Header(self.receiver_name, 'utf-8') subject = 'python_test' # 发送的主题,可自由填写 message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP_SSL(self.mail_host, 465) smtpObj.login(self.sender, self.mail_pass) smtpObj.sendmail(self.sender, self.receiver, message.as_string()) smtpObj.quit() self.logger.log_info('send mail success') except smtplib.SMTPException as e: self.logger.log_error('send mail failed')
class DataCollectUI(QtWidgets.QMainWindow, Ui_Form): def __init__(self): super(DataCollectUI, self).__init__() self.setupUi(self) # sqlite self.sqlite = SqlLiteManage() # 日志 self.logger = Logging() # 摄像头 self.capture = cv2.VideoCapture() # 定时器 self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_frame) # 当前人脸ID self.faceID = 0 # 是否进行人脸采集 self.isCollect = False self.isContinueCollect = False # 是否打开摄像头 self.isOpenCapture = False # 自定义参数 self.count = 0 # 人脸采集计数 self.MaxCount = 50 # 采集人脸数量 self.scale_factor = 1.1 # 数值越大计算越快,太快会丢失人脸 self.minNeighbors = 3 # 控制着误检测 # 预处理选择 self.isGaussianBlur = False # 高斯 self.isBlur = False # 均值 self.isMedianBlur = False # 中值 self.isEqualizeHist = False # 直方图均衡 # 级联分类器 self.face_detector = cv2.CascadeClassifier( "E:\Opencv\opencv-master\data\haarcascades\haarcascade_frontalface_default.xml" ) # 人脸数量 self.max_face_count = 1 # 初始化 def root(self): isSelected = QMessageBox.question(self, '确认', '初始化会清空表中所有数据,确定要这么做吗?', QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if isSelected == QMessageBox.Ok: self.sqlite.create_table() self.sqlite.root_db() for file in os.listdir('./dataset'): os.remove('./dataset/' + file) for file in os.listdir('./trainer'): os.remove('./trainer/' + file) self.logger.log_info('root database success') elif isSelected == QMessageBox.Cancel: self.logger.log_info('usr not select "root database"') else: return # 打开摄像头 # 管理外接摄像头 def open_capture(self): self.logger.log_info('open capture') self.isOpenCapture = True capture_dev_id = 0 if self.checkBox.isChecked(): capture_dev_id = 1 self.capture.open(capture_dev_id) self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 721) self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 511) ret, frame = self.capture.read() self.timer.start(5) # 关闭摄像头 def close_capture(self): self.logger.log_info('close capture') self.capture.release() self.timer.stop() self.label_3.setText("摄像头识别区") self.isOpenCapture = False # 人脸检测 def face_detection(self, frame): min_width = 0.1 * self.capture.get(3) min_height = 0.1 * self.capture.get(4) # 灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = self.face_detector.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=3, minSize=(int(min_width), int(min_height)), ) # 有多张人脸时暂停采集,一张人脸继续采集 if len(faces) > self.max_face_count: self.isContinueCollect = False else: self.isContinueCollect = True # 用矩形画出脸的位置 for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) return frame # 人脸采集 # 录入后,只给最后一条ID录人脸 def face_collect(self): if not self.isOpenCapture: QMessageBox.warning(self, '警告', '未打开摄像头') self.logger.log_warning('capture not open') return if self.sqlite.count_data() == 0: QMessageBox.warning(self, '警告', '数据库为空') self.logger.log_warning('database is null') return isSelected = QMessageBox.question(self, '确认', '人脸采集只会给最新录入的数据采集,是否继续?', QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if isSelected == QMessageBox.Ok: self.logger.log_info('start collect face...') # 自定义初始化 self.MaxCount = int(self.label_8.text()) self.scale_factor = float(self.doubleSpinBox.value()) self.minNeighbors = int(self.label_10.text()) self.isGaussianBlur = self.radioButton.isChecked() self.isBlur = self.radioButton_2.isChecked() self.isMedianBlur = self.radioButton_3.isChecked() self.isEqualizeHist = self.checkBox_5.isChecked() self.count = 0 self.faceID = self.sqlite.iter_search()[-1][0] self.isCollect = True elif isSelected == QMessageBox.Cancel: self.logger.log_info('usr not select "face_collect"') else: return # 定时刷新界面 def update_frame(self): start = time.time() ret, frame = self.capture.read() img = self.face_detection(frame) if ret and self.isCollect and self.isContinueCollect: end = time.time() img = cv2.putText(img, 'FPS: %.1f' % (1 / (end - start)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1) img = cv2.putText( img, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), (210, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1) self.frame_dispose(img) self.collect_face_data(frame) else: end = time.time() img = cv2.putText(img, 'FPS: %.1f' % (1 / (end - start)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1) img = cv2.putText( img, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), (210, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1) self.frame_dispose(img) if self.count >= self.MaxCount: self.isCollect = False self.logger.log_info('face data collect finish') self.close_capture() # 人脸采集 def collect_face_data(self, frame): # 灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 三种滤波只能选择一种 if self.isGaussianBlur: gray = cv2.GaussianBlur(gray, (5, 5), 1) if self.isMedianBlur: gray = cv2.medianBlur(gray, 5) if self.isBlur: gray = cv2.blur(gray, (3, 3)) # 直方图均衡 if self.isEqualizeHist: gray = cv2.equalizeHist(gray) # 第一个参数img # 第二个参数scale_factor,数值越大计算越快,太快会丢失人脸 # 第三个参数minNeighbors,控制着误检测,默认值为3。表明至少有3次重叠检测,我们才认为人脸确实存在 faces = self.face_detector.detectMultiScale(gray, self.scale_factor, self.minNeighbors) # 图像中人脸大于1就跳过 if len(faces) > self.max_face_count: pass for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) self.count += 1 self.lcdNumber.display(self.count) # 将照片存入指定文件夹./dataset cv2.imwrite( "./dataset/User." + str(self.faceID) + '.' + str(self.count) + ".jpg", gray[y:y + h, x:x + w]) # 对每一帧进行处理 def frame_dispose(self, frame): img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) qformat = QImage.Format_Indexed8 if len(img.shape) == 3: # rows[0], cols[1], channels[2] if img.shape[2] == 4: # The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8) # A: alpha channel,不透明度参数。如果一个像素的alpha通道数值为0%,那它就是完全透明的 qformat = QImage.Format_RGBA8888 else: qformat = QImage.Format_RGB888 output_img = QImage(img, img.shape[1], img.shape[0], img.strides[0], qformat) self.label_3.setPixmap(QPixmap.fromImage((output_img))) self.label_3.setScaledContents(True) # 添加新数据 def add_item(self): if not (self.lineEdit.text() and self.lineEdit_2.text() and self.lineEdit_3.text()): QMessageBox.warning(self, '警告', '部分字段为空,请填写合适数据,否则这段数据不会被插入') self.logger.log_warning('some fields are null') self.logger.log_error('insert data failed') else: values = (int(self.lineEdit_2.text()), self.lineEdit.text(), self.lineEdit_3.text(), 0) try: self.sqlite.insert(values) self.log(1, 'insert data success') except: QMessageBox.warning(self, '警告', '数据库中已经有ID相同字段,请重试') self.logger.log_warning('already have the same data') self.logger.log_error('insert data failed')