【项目实训】基于人脸识别的课堂签到管理系统(python+qt5+sqlite3+百度智能云)

  • 一.环境介绍
  • 二.签到功能
    • 2.1 启动签到
    • 2.2 结束签到
  • 三.用户组操作
    • 3.1 添加用户组
    • 3.2 删除用户组
    • 3.3 查询用户组
  • 四.用户操作
    • 4.1 添加用户
    • 4.2 删除用户
    • 4.3 更新用户
  • 五.摄像头相关设置
  • 六.相关链接

一.环境介绍

编写工具:Pycharm,Pyqt5designer
语言:python 版本:python3.7.4
数据库:sqlite3
代码:【项目实训】 基于人脸识别的课堂签到管理系统.zip

二.签到功能

签到功能是该项目最核心的功能,将会着重介绍几个核心函数

2.1 启动签到

首先先看下启动签到,该功能所需要调用的函数。然后对重要函数进行分析,以及代码展示

    def on_actionopen(self):list = self.getlist()self.group_id, ret = QInputDialog.getText(self, "请输入所在用户组", "用户组信息\n" + str(list['result']['group_id_list']))if self.group_id == '':QMessageBox.about(self, "签到失败", "用户组不能为空\n")returngroup_status = 0for i in list['result']['group_id_list']:if i == self.group_id:group_status =1breakif group_status == 0:QMessageBox.about(self, "签到失败", "该用户组不存在\n")return#启动摄像头self.cameravideo = camera()self.camera_status = True#启动定时器,进行定时,每个多长时间进行一次获取摄像头数据进行显示,用作流畅显示画面self.timeshow = QTimer(self)self.timeshow.start(10)#10ms的定时器启动,每到10ms就会产生一个信号timeout,信号没有()self.timeshow.timeout.connect(self.show_cameradata)#self.timeshow.timeout().connect(self.show_cameradata)# self.show_cameradata()#创建检测线程self.create_thread()# self.group_id.emit(str(group_id))# self.group_id.connect(self.detectThread.get_group_id)#当开启启动签到时,创建定时器,500ms,用作获取要检测的画面# facedetecttime定时器设置检测画面获取self.facedetecttime = QTimer(self)self.facedetecttime.start(500)self.facedetecttime.timeout.connect(self.get_cameradata)self.detect_data_signal.connect(self.detectThread.get_base64)self.detectThread.transmit_data.connect(self.get_detectdata)self.detectThread.search_data.connect(self.get_search_data)

首先是调用getlist函数,该函数是用来获取学生所在的用户组(可以理解为班级),通过输入所在班级,在该班级搜寻该学生人脸,同时通过if条件语句判断是否为空,或者错误班级,防止程序卡死

接着是启动摄像头,通过设置一个定时器,来不断获取摄像头一帧画面
为了使界面显示画面流畅,这里采用多线程方式,每500ms发送一次,将学生图片发送给另一个线程
多线程类就接受学生人脸图片以及相关参数,并将其上传至百度智能云,进行人脸检测

    def detect_face(self,base64_image):'''#对话框获取图片#获取一张图片(一帧画面)#getOpenFileName通过对话框的形式获取一个图片(.JPG)路径path,ret = QFileDialog.getOpenFileName(self,"open picture",".","图片格式(*.jpg)")#把图片转换成base64编码格式fp = open(path,'rb')base64_imag = base64.b64encode(fp.read())print(base64_imag)'''# 摄像头获取画面# camera_data = self.cameravideo.read_camera()# # 把摄像头画面转换成图片,然后设置编码base64编码格式数据# _, enc = cv2.imencode('.jpg', camera_data)# base64_image = base64.b64encode(enc.tobytes())# 发送请求的地址request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"# 请求参数是一个字典,在字典中存储,百度AI要识别的图片信息,属性内容params = {"image": base64_image,  # 图片信息字符串"image_type": "BASE64",  # 图片信息格式"face_field": "gender,age,beauty,expression,face_shape,glasses,emotion,mask",  # 请求识别人脸的属性, 各个属性在字符串中用,逗号隔开"max_face_num": 1}# 访问令牌access_token = self.access_token# 把请求地址和访问令牌组成可用的网络请求request_url = request_url + "?access_token=" + access_token# 参数:设置请求的格式体headers = {'content-type': 'application/json'}# 发送网络post请求,请求百度AI进行人脸检测,返回检测结果# 发送网络请求,就会存在一定的等待时间,程序就在这里阻塞执行,所以会存在卡顿现象response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_code'] != 0:self.transmit_data.emit(data)self.search_data.emit(data['error_msg'])returnif data['result']['face_num'] > 0:#data是请求数据的结果,需要进行解析,单独拿出所需的数据内容,分开self.transmit_data.emit(dict(data))self.face_search(self.group_id)

读取百度智能云返回主线程相关的人脸信息,若人脸数大于0,则执行人脸识别功能

# 人脸识别检测,只检测一个人def face_search(self,group_id):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/search"params = {"image": self.base64_image,"image_type": "BASE64","group_id_list": group_id,}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_code'] == 0:if data['result']['user_list'][0]['score'] > 90:#存储要保存的签到数据,方便显示del(data['result']['user_list'][0]['score'])datetime = QDateTime.currentDateTime()datetime = datetime.toString()data['result']['user_list'][0]['datetime'] = datetimekey = data['result']['user_list'][0]['group_id']+data['result']['user_list'][0]['user_id']if key not in self.sign_list.keys():self.sign_list[key] = data['result']['user_list'][0]self.search_data.emit("学生签到成功\n学生信息:"+data['result']['user_list'][0]['user_info'])stu_data = data['result']['user_list'][0]['user_info']info = stu_data.split('\n')_, info_name = info[0].split(':')_, info_class = info[1].split(':')id = data['result']['user_list'][0]['user_id']# self.add_sqlite(id, info_name, info_class, datetime)self.search_sqlite(id)for i in self.values:search_id = i[0]if search_id == id:self.update_sqlite(id,info_name,info_class,datetime)else:self.add_sqlite(id,info_name,info_class,datetime)else:self.search_data.emit("学生签到失败,找不到对应学生")

当人脸匹配可信度大于90时,将学生签到信息添加到数据库,下面代码是sqlite3数据库相关操作

#创建数据库def create_sqlite(self):con = sqlite3.connect(r"stu_data.db")c = con.cursor()c.execute("create table student(id primary key ,name ,stu_class,datetime)")print("创建成功")#添加学生数据到数据库def add_sqlite(self,id,name,stu_class,datetime):con = sqlite3.connect(r"stu_data.db")c = con.cursor()value = (id,name,stu_class,datetime)sql = "insert into student(id,name,stu_class,datetime) values(?,?,?,?)"c.execute(sql,value)# 提交con.commit()#更新学生数据库信息def update_sqlite(self,id,name,stu_class,datetime):con = sqlite3.connect(r"stu_data.db")c = con.cursor()# value = (name,stu_class,datetime,id)sql = "update student set name=?,stu_class=?,datetime=? where id =?"c.execute(sql,(name,stu_class,datetime,id))con.commit()#查询学生数据库信息def search_sqlite(self,id):con = sqlite3.connect(r"stu_data.db")c = con.cursor()sql = "select * from student where id=?"self.values = c.execute(sql,(id,))

当线程完成人脸识别后,就会将学生信息和签到信息返回,这时就检测数据,并打印到主窗口

#槽函数,获取检测数据def get_detectdata(self,data):if data['error_code'] != 0:self.plainTextEdit_2.setPlainText(data['error_msg'])returnelif data['error_msg'] == 'SUCCESS':# 在data字典中,键为'result'对应的值才是返回的检查结果# data['result']才是检测结果# 人脸数目self.plainTextEdit_2.clear()face_num = data['result']['face_num']if face_num == 0:self.plainTextEdit_2.appendPlainText("未测到检人脸")returnelse:self.plainTextEdit_2.appendPlainText("测到检人脸")# 人脸信息data['result']['face_list'],是列表,每个数据就是一个人脸信息,需要取出每个列表数据# 每个人脸信息:data['result']['face_list'][0~i]人脸信息字典for i in range(face_num):# 通过for循环,分别取出列表的每一个数据# data['result']['face_list'][i],就是一个人脸信息的字典age = data['result']['face_list'][i]['age']beauty = data['result']['face_list'][i]['beauty']gender = data['result']['face_list'][i]['gender']['type']expression = data['result']['face_list'][i]['expression']['type']face_shape = data['result']['face_list'][i]['face_shape']['type']glasses = data['result']['face_list'][i]['glasses']['type']emotion = data['result']['face_list'][i]['emotion']['type']mask = data['result']['face_list'][i]['mask']['type']# 往窗口中添加文本,参数就是需要的文本信息self.plainTextEdit_2.appendPlainText("-----------------")self.plainTextEdit_2.appendPlainText("第" + str(i + 1) + "个学生信息:")self.plainTextEdit_2.appendPlainText("-----------------")self.plainTextEdit_2.appendPlainText("年龄: " + str(age))self.plainTextEdit_2.appendPlainText("颜值分数: " + str(beauty))self.plainTextEdit_2.appendPlainText("性别: " + str(gender))self.plainTextEdit_2.appendPlainText("表情: " + str(expression))self.plainTextEdit_2.appendPlainText("脸型: " + str(face_shape))self.plainTextEdit_2.appendPlainText("是否佩戴眼镜: " + str(glasses))self.plainTextEdit_2.appendPlainText("情绪: " + str(emotion))if mask == 0:mask = "否"else:mask = "是"self.plainTextEdit_2.appendPlainText("是否佩戴口罩: " + str(mask))self.plainTextEdit_2.appendPlainText("-----------------")def get_search_data(self,data):self.plainTextEdit.setPlainText(data)

这样启动签到功能就基本实现了

2.2 结束签到

接着是结束签到,该功能所需要调用的函数。然后对重要函数进行分析,以及代码展示

    def on_actionclose(self):# 清除学生人脸信息(False)# self.plainTextEdit_2.setPlainText("  ")#关闭定时器,不再设置检测画面获取self.facedetecttime.stop()#self.facedetecttime.timeout.disconnect(self.get_cameradata)#self.detect_data_signal.disconnect(self.detectThread.get_base64)#self.detectThread.transmit_data.connect(self.get_detectdata)#关闭检测线程self.detectThread.OK = Falseself.detectThread.quit()self.detectThread.wait()print(self.detectThread.isRunning())# 关闭定时器,不再去获取摄像头的数据self.timeshow.stop()self.timeshow.timeout.disconnect(self.show_cameradata)# 关闭摄像头self.cameravideo.close_camera()self.camera_status = Falseprint("1")#显示本次签到情况self.signdata = sign_data(self.detectThread.sign_list,self)self.signdata.exec_()if self.timeshow.isActive() == False and self.facedetecttime.isActive() == False:# 画面设置为初始状态self.label.setPixmap(QPixmap("1.jpg"))self.plainTextEdit.clear()self.plainTextEdit_2.clear()else:QMessageBox.about(self, "错误", "关闭签到失败\n")

关闭定时器,不再设置检测画面获取
关闭检测线程

关闭定时器,不再去获取摄像头的数据

关闭摄像头

显示本次签到情况,这里会弹出一个窗口,将学生签到情况显示在窗口,并提供两个按钮,取消和导出。导出能够将学生签到信息导出成TXT文件

        #设置窗口内容不能被修改self.signdata = signdataself.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)for i in signdata.values():info = i['user_info'].split('\n')rowcount = self.tableWidget.rowCount()self.tableWidget.insertRow(rowcount)info_name = info[0].split(':')self.tableWidget.setItem(rowcount, 0, QTableWidgetItem(info_name[1]))info_class = info[1].split(':')self.tableWidget.setItem(rowcount, 1, QTableWidgetItem(info_class[1]))self.tableWidget.setItem(rowcount, 2, QTableWidgetItem(i['user_id']))self.tableWidget.setItem(rowcount, 3, QTableWidgetItem(i['datetime']))#导出按钮self.pushButton.clicked.connect(self.save_data)#取消按钮self.pushButton_2.clicked.connect(self.close_window)def close_window(self):self.reject()def save_data(self):#打开对话框,获取要导出的数据文件名filename,ret = QFileDialog.getSaveFileName(self,"导出数据",".","TXT(*.txt)")f = open(filename,"w")for i in self.signdata.values():info = i['user_info'].split('\n')_,info_name = info[0].split(':')_,info_class = info[1].split(':')f.write(str(info_name+"  "+info_class+"  "+i['user_id']+"  "+i['datetime'] ))f.close()self.accept()

三.用户组操作

3.1 添加用户组

添加用户组实现代码

 def add_group(self):#打开对话框,进行输入用户组group,ret = QInputDialog.getText(self,"添加用户组","请输入用户组(由数字、字母、下划线组成)")request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add"params = {"group_id":group}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:message = response.json()if message['error_msg'] == 'SUCCESS':QMessageBox.about(self,"用户组创建结果","用户组创建成功")else:QMessageBox.about(self,"用户组创建结果","用户组创建失败\n"+message['error_msg'])

3.2 删除用户组

删除用户组实现代码

   def del_group(self):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/delete"list = self.getlist()group, ret = QInputDialog.getText(self, "用户组列表", "用户组信息\n" + str(list['result']['group_id_list']))# 删除,需要知道那些组params = {"group_id": group  # 要删除的用户组的id}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_msg'] == 'SUCCESS':QMessageBox.about(self, "用户组删除结果", "用户组删除成功")else:QMessageBox.about(self, "用户组删除结果", "用户组删除失败\n" + data['error_msg'])

3.3 查询用户组

查询用户组实现代码

#获取用户组def getlist(self):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist"params = {"start":0,"length":100}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_msg'] == 'SUCCESS':return dataelse:QMessageBox.about(self, "获取用户组结果", "获取用户组失败\n" + data['error_msg'])

四.用户操作

4.1 添加用户

添加用户实现代码

    def add_user(self):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"if self.camera_status:QMessageBox.about(self,"摄像头状态","摄像头已打开,正在进行人脸签到\n请关闭签到,再添加用户")returnlist = self.getlist()#创建一个窗口来选择这些内容window = adduserwindow(list['result']['group_id_list'],self)#新创建窗口,通过exec()函数一直执行,阻塞执行,窗口不进行关闭#exec()函数不会退出,关闭窗口才会结束window_status = window.exec_()#进行判断,判断是否点击确定进行关闭if window_status != 1:return#请求参数,需要获取人脸:转换人脸编码,添加的组id,添加的用户id,新用户的id信息params = {"image":window.base64_image,#人脸图片"image_type":"BASE64",#人脸图片编码"group_id":window.group_id,#组id"user_id":window.user_id,#新用户id"user_info":'姓名:'+window.msg_name+'\n'+'班级:'+window.msg_class#用户信息}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_msg'] == 'SUCCESS':QMessageBox.about(self, "人脸创建结果", "人脸创建成功")else:QMessageBox.about(self, "人脸创建结果", "用户组创建失败\n"+ data['error_msg'])

4.2 删除用户

删除用户实现代码

 def del_face_token(self,group,user,face_token):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/face/delete"params = {"user_id": user,"group_id": group,"face_token":face_token}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_msg'] == 'SUCCESS':QMessageBox.about(self, "人脸删除结果", "人脸删除成功")else:QMessageBox.about(self, "人脸删除结果", "用户组删除失败\n" + data['error_msg'])def del_user(self):#查询用户人脸信息(face_token)#获取用户组list = self.getlist()group,ret = QInputDialog.getText(self,"用户组获取","用户组信息\n"+str(list['result']['group_id_list']))group_status = 0if self.group_id == '':QMessageBox.about(self, "删除失败", "用户组不能为空\n")returnfor i in list['result']['group_id_list']:if i == group:group_status = 1breakif group_status == 0:QMessageBox.about(self, "删除失败", "该用户组不存在\n")return#获取用户userlist = self.get_userlist(group)user,ret = QInputDialog.getText(self,"用户获取","用户信息\n"+str(userlist['result']['user_id_list']))user_status = 0if user == '':QMessageBox.about(self, "删除失败", "用户不能为空\n")returnfor i in userlist['result']['user_id_list']:if i == user:user_status = 1breakif user_status == 0:QMessageBox.about(self, "删除失败", "该用户不存在\n")return#获取用户人脸列表face_list = self.user_face_list(group,user)for i in face_list['result']['face_list']:self.del_face_token(group,user,i['face_token'])

4.3 更新用户

更新用户实现代码

 #更新用户人脸def update_user(self):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/update"if self.camera_status:QMessageBox.about(self,"摄像头状态","摄像头已打开,正在进行人脸签到\n请关闭签到,再添加用户")returnlist = self.getlist()#创建一个窗口来选择这些内容window = adduserwindow(list['result']['group_id_list'],self)#新创建窗口,通过exec()函数一直执行,阻塞执行,窗口不进行关闭#exec()函数不会退出,关闭窗口才会结束window_status = window.exec_()#进行判断,判断是否点击确定进行关闭if window_status != 1:return#请求参数,需要获取人脸:转换人脸编码,添加的组id,添加的用户id,新用户的id信息params = {"image":window.base64_image,#人脸图片"image_type":"BASE64",#人脸图片编码"group_id":window.group_id,#组id"user_id":window.user_id,#新用户id"user_info":'姓名:'+window.msg_name+'\n'+'班级:'+window.msg_class#用户信息}access_token = self.access_tokenrequest_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/json'}response = requests.post(request_url, data=params, headers=headers)if response:data = response.json()if data['error_msg'] == 'SUCCESS':QMessageBox.about(self, "人脸更新结果", "人脸更新成功")else:QMessageBox.about(self, "人脸更新结果", "用户组更新失败\n" + data['error_msg'])

五.摄像头相关设置

摄像头类代码

import cv2
import numpy as np
from  PyQt5.QtGui import QPixmap,QImage
'''
摄像头操作:创建类对象完成摄像头操作,所以可以把打开摄像头与创建类对象操作合并__init__函数完成摄像头的配置打开
'''class camera():def __init__(self):#VideoCapture类对视频或调用摄像头进行读取操作#参数 filename;device#0表示默认的摄像头进行打开#self.capture表示打开的摄像头对象self.capture = cv2.VideoCapture(0)#isOpened函数返回一个布尔值,来判断是否摄像头初始化成功# if self.capture.isOpened():#     print("isOpened")#定义一个多维数组,存取画面self.currentframe = np.array([])#读取摄像头数据def read_camera(self):#ret是否成功,pic_data数据ret,data = self.capture.read()if not ret:print("获取摄像头数据失败")return Nonereturn data#数据转换成界面能显示的数据格式def camera_to_pic(self):pic = self.read_camera()#摄像头是BGR方式存储,首先要转换成RGBself.currentframe = cv2.cvtColor(pic,cv2.COLOR_BGR2RGB)#设置宽高#self.currentframe = cv2.cvtColor(self.currentframe,(640,480))#转换格式(界面能够显示的格式)#获取画面的宽度和高度height,width = self.currentframe.shape[:2]#先转换成QImage类型的图片(画面),创建QImage类对象,使用摄像头的画面#QImage (data, width, height , format)创建:数据,宽度,高度,格式qimg = QImage(self.currentframe,width,height,QImage.Format_RGB888)qpixmap = QPixmap.fromImage(qimg)return qpixmapdef close_camera(self):self.capture.release()

六.相关链接

代码下载:【项目实训】 基于人脸识别的课堂签到管理系统.zip
详细教程:
基于人脸识别的课堂签到管理系统(一)—环境设置以及简单的QT界面设计
基于人脸识别的课堂签到管理系统(二)—摄像头显示
基于人脸识别的课堂签到管理系统(三)—实时时间显示以及百度AI人脸识别
基于人脸识别的课堂签到管理系统(四)—摄像头上传实时数据,百度AI读取并返回信息以及多线程操作
基于人脸识别的课堂签到管理系统(五)—启动/结束签到,以及在百度智能云创建用户组
基于人脸识别的课堂签到管理系统(六)—删除,查询用户组以及人脸的添加,删除,更新
基于人脸识别的课堂签到管理系统(七)—实现人脸搜索,完善签到功能

【项目实训】基于人脸识别的课堂签到管理系统(python+qt5+sqlite3+百度智能云)相关推荐

  1. 基于人脸识别的课堂签到管理系统(一)---环境设置以及简单的QT界面设计

    基于人脸识别的课堂签到管理系统(一)---环境设置以及简单的QT界面设计 一.前言 二.Pycharm安装与环境配置 2.1 Pycharm安装配置 2.2 Pycharm环境配置 三.QT界面设计 ...

  2. 基于人脸识别的课堂签到管理系统(六)---删除,查询用户组以及人脸的添加,删除,更新

    基于人脸识别的课堂签到管理系统(六)---删除,查询用户组以及人脸的添加,删除 一.用户组操作 1.1 查询用户组 1.2 删除用户组 二.人脸操作 2.1 人脸添加 2.2 人脸更新 2.3 人脸删 ...

  3. 基于人脸识别的课堂签到管理系统(五)---启动/结束签到,以及在百度智能云创建用户组

    基于人脸识别的课堂签到管理系统(五)---启动/结束签到,以及在百度智能云创建用户组 一.前言概述 二.签到功能 2.1 启动签到 2.2 结束签到 三.创建用户 四.程序展示 五.相关下载 一.前言 ...

  4. 基于人脸识别的课堂签到管理系统(四)---摄像头上传实时数据,百度AI读取并返回信息以及多线程操作

    基于人脸识别的课堂签到管理系统(四)---摄像头上传实时数据,百度AI读取并返回以及多线程操作 一. 前言概述 二.摄像头上传数据,读取百度AI返回信息 三.多线程操作 四.程序展示 五.相关下载 一 ...

  5. 基于人脸识别的课堂签到管理系统(三)---实时时间显示以及百度AI人脸识别

    基于人脸识别的课堂签到管理系统(三)---实时时间显示以及百度AI人脸识别 一.前言概述 二.实时时间显示 三.百度AI人脸识别 3.1 获取access_token 3.2 发送请求,通过网络请求方 ...

  6. 基于人脸识别的课堂签到管理系统【学习一】

    写在前面:需要搭建的环境 (我使用的环境情况如下) pycharm python opencv-python pysqlit3 pyqt5-tools 具体情况如图所示 基于人脸识别的课堂签到管理系统 ...

  7. 基于人脸识别的课堂签到管理系统【学习三】

    实习第三天,上午练习实现ui界面的日期和时间与系统时间保持一致,人脸识别能够把摄像头采集的画面进行人脸识别,能识别人脸,且判断到是谁.之后进行人脸分析识别判断,实现方式有很多种,但是考虑到诸多原因我们 ...

  8. 基于人脸识别的课堂签到管理系统(七)---实现人脸搜索,完善签到功能

    一.人脸搜索 首先还是参考百度的技术文档,可以看到想要进行人脸搜索操作就需要提供图片信息,格式,用户组id三个必需的参数 这些参数在之前就已经获取好了,只需要直接调用即可 # 人脸识别检测,只检测一个 ...

  9. 基于人脸识别的课堂签到管理系统(二)---摄像头显示

    一.前言概述 摄像头显示 创建摄像头操作类:完成摄像头的采集功能 当需要摄像头完成一个功能时,就调用摄像头对象的一个函数去完成 实现一个摄像头类: 添加 打开摄像头 获取摄像头的实时数据 数据进行转换 ...

最新文章

  1. 简单两步,spring aop上手即用即会
  2. IHttpHandler的妙用之防盗链
  3. 怀孕参加计算机考试有辐射吗,电脑辐射对孕妇的影响大不大 会对胎儿造成什么影响...
  4. matlab人脸和非人脸分割,人脸检测与分割
  5. fckeditor配置
  6. ipython下怎么运行py文件_在IPython中执行Python程序文件的示例
  7. VB WindowsMediaPlayer 播放
  8. elasticSearch创建索引库、映射、文档
  9. visio流程图的叉号_【转】Visio绘制WEB流程图的心得
  10. flutter全局状态管理Provider
  11. STM32时钟简介及系统时钟频率的更改方式
  12. 机械臂速成小指南(六):步进电机驱动器
  13. libcurl smtp发送邮件附件大小限制问题
  14. 前端培训-javascript 的垃圾回收机制
  15. 轻量级网络模型MobileNet发展脉络(V1-V2-V3)
  16. Java 操作数据库插入失败原因
  17. 2012最值得收购的6家互联网科技公司
  18. 修复克米3.5改密破解模板搜索框不显示问题
  19. 【VIS】Classifying,Segmenting,and Tracking Object Instances in Video with Mask Propagation
  20. forEach遍历数组

热门文章

  1. mysql 绿色安装 ubuntu_Ubuntu免安装配置MySQL
  2. 串灯控制盒去掉怎么接_暖通小兵设计系列16-集线盒(中央控制器)简介(余小其转载版本)...
  3. php获取微信uninoid_微信小程序获取openid和unionid方法
  4. Ant Design Pro引入Echarts 报错Unexpected token
  5. 搭建第一个Docker
  6. java this 方法,使用“this”用方法(用Java)
  7. 哪种语言更适合做自动化测试?
  8. 接口测试实战总结,绝对值得收藏
  9. MATLAB 生成exe 的几种方法
  10. 计算机组成原理尾数的求法,计算机组成原理第八讲(运算办法).ppt