计算机设计大赛 疲劳驾驶检测系统 python

文章目录

  • 0 前言
  • 1 课题背景
  • 2 Dlib人脸识别
    • 2.1 简介
    • 2.2 Dlib优点
    • 2.3 相关代码
    • 2.4 人脸数据库
    • 2.5 人脸录入加识别效果
  • 3 疲劳检测算法
    • 3.1 眼睛检测算法
    • 3.2 打哈欠检测算法
    • 3.3 点头检测算法
  • 4 PyQt5
    • 4.1 简介
    • 4.2相关界面代码
  • 5 最后

0 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

为了有效监测驾驶员是否疲劳驾驶、避免交通事故的发⽣,本项目利⽤⼈脸特征点进⾏实时疲劳驾驶检测的新⽅法。对驾驶员驾驶时的⾯部图像进⾏实时监控,⾸先检测⼈脸,并利⽤ERT算法定位⼈脸特征点;然后根据⼈脸眼睛区域的特征点坐标信息计算眼睛纵横⽐EAR来描述眼睛张开程度,根据合适的EAR阈值可判断睁眼或闭眼状态;最后基于EAR实测值和EAR阈值对监控视频计算闭眼时间⽐例(PERCLOS)值度量驾驶员主观疲劳程度,将其与设定的疲劳度阈值进⾏⽐较即可判定是否疲劳驾驶。

2 Dlib人脸识别

2.1 简介

Dlib是一个基于c++开发的开源数据工具库,其中包含了不少的机器学习的成熟算法与模型,相对于tensorflow和PyTorch,它用于图像处理以及人脸面部特征提取、分类及对比这几个方面比较具有通用性和优越性,因此,Dlib正在越来越广泛地应用在人脸识别技术领域。
Dlib具有独立使用的可移植代码。Dlib中的代码使用c++语言进行开发而成,使用独立封装,在不借助第三方数据库的情况下,可以直接移植到自己所需要设计的项目中进行使用。

2.2 Dlib优点

  • Dlib拥有全面的文档说明。作为一个开源的人脸数据库训练集,Dlib中有很多功能齐全的程序和文件,从人性化的角度而言的,Dlib在这一点上做的是非常不错的,因为它为每一个程序文档和文件都做了相对应的注释,这样开发者就可以迅速准确的调集程序文档来完成自己所需要的项目功能。

  • Dlib涵盖了支持功能完备的深度学习以及图像处理的各类算法。Dlib为开发者提供了机器深度学习的各类成熟的完备算法,并且在图像处理方面也为开发者带来了能够解决大多数实质问题的优良算法。例如基于SVM的递归和分类算法,以及专门用于面对大规模分类和递归的降维算法。当然还有能够对未知函数进行预分类和预测的相关向量机,其分类和预测训练是基于贝叶斯框架。

2.3 相关代码

import` `matplotlib.pyplot as plt
import` `dlib
import` `numpy as np
import` `glob
import` `re
 
#正脸检测器
detector``=``dlib.get_frontal_face_detector()
#脸部关键形态检测器
sp``=``dlib.shape_predictor(r``"D:LBJAVAscriptshape_predictor_68_face_landmarks.dat"``)
#人脸识别模型
facerec ``=` `dlib.face_recognition_model_v1(r``"D:LBJAVAscriptdlib_face_recognition_resnet_model_v1.dat"``)
 
#候选人脸部描述向量集
descriptors``=``[]
 
photo_locations``=``[]
 
for` `photo ``in` `glob.glob(r``'D:LBJAVAscriptfaces*.jpg'``):
 ``photo_locations.append(photo)
 ``img``=``plt.imread(photo)
 ``img``=``np.array(img)
 
 ``#开始检测人脸
 ``dets``=``detector(img,``1``)
 
 ``for` `k,d ``in` `enumerate``(dets):
  ``#检测每张照片中人脸的特征
  ``shape``=``sp(img,d)
  ``face_descriptor``=``facerec.compute_face_descriptor(img,shape)
  ``v``=``np.array(face_descriptor)
  ``descriptors.append(v)
    
#输入的待识别的人脸处理方法相同
img``=``plt.imread(r``'D:test_photo10.jpg'``)
img``=``np.array(img)
dets``=``detector(img,``1``)
#计算输入人脸和已有人脸之间的差异程度(比如用欧式距离来衡量)
differences``=``[]
for` `k,d ``in` `enumerate``(dets):
 ``shape``=``sp(img,d)
 ``face_descriptor``=``facerec.compute_face_descriptor(img,shape)
 ``d_test``=``np.array(face_descriptor)
 
 ``#计算输入人脸和所有已有人脸描述向量的欧氏距离
 ``for` `i ``in` `descriptors:
  ``distance``=``np.linalg.norm(i``-``d_test)
  ``differences.append(distance)
 
#按欧式距离排序 欧式距离最小的就是匹配的人脸
candidate_count``=``len``(photo_locations)
candidates_dict``=``dict``(``zip``(photo_locations,differences))
candidates_dict_sorted``=``sorted``(candidates_dict.items(),key``=``lambda` `x:x[``1``])
 
#matplotlib要正确显示中文需要设置
plt.rcParams[``'font.family'``] ``=` `[``'sans-serif'``]
plt.rcParams[``'font.sans-serif'``] ``=` `[``'SimHei'``]
 
plt.rcParams[``'figure.figsize'``] ``=` `(``20.0``, ``70.0``)
 
ax``=``plt.subplot(candidate_count``+``1``,``4``,``1``)
ax.set_title(``"输入的人脸"``)
ax.imshow(img)
 
for` `i,(photo,distance) ``in` `enumerate``(candidates_dict_sorted):
 ``img``=``plt.imread(photo)
 
 ``face_name``=``""
 ``photo_name``=``re.search(r``'([^\]*).jpg$'``,photo)
 ``if` `photo_name:
  ``face_name``=``photo_name[``1``]
  
 ``ax``=``plt.subplot(candidate_count``+``1``,``4``,i``+``2``)
 ``ax.set_xticks([])
 ``ax.set_yticks([])
 ``ax.spines[``'top'``].set_visible(``False``)
 ``ax.spines[``'right'``].set_visible(``False``)
 ``ax.spines[``'bottom'``].set_visible(``False``)
 ``ax.spines[``'left'``].set_visible(``False``)
 
 ``if` `i``=``=``0``:
  ``ax.set_title(``"最匹配的人脸nn"``+``face_name``+``"nn差异度:"``+``str``(distance))
 ``else``:
  ``ax.set_title(face_name``+``"nn差异度:"``+``str``(distance))
 ``ax.imshow(img)
 
plt.show()

2.4 人脸数据库

本项目中将识别到的人脸保存的.db文件中,相关代码如下:



    class CoreUI(QMainWindow):
        database = './FaceBase.db'
        trainingData = './recognizer/trainingData.yml'
        cap = cv2.VideoCapture()
        captureQueue = queue.Queue()  # 图像队列
        alarmQueue = queue.LifoQueue()  # 报警队列,后进先出
        logQueue = multiprocessing.Queue()  # 日志队列
        receiveLogSignal = pyqtSignal(str)  # LOG信号
    
        def __init__(self):
    
            super(CoreUI, self).__init__()


            loadUi('./ui/Core.ui', self)
            self.setWindowIcon(QIcon('./icons/icon.png'))
            #self.setFixedSize(1161, 620)


            '''self.pushButton = QPushButton('rush', self)
            layout = QVBoxLayout()
            layout.addWidget(self.pushButton)
            self.setLayout(layout)'''
            #self.pushButton.clicked.connect(self.open)=

            # 图像捕获
            self.isExternalCameraUsed = False
            self.useExternalCameraCheckBox.stateChanged.connect(
                lambda: self.useExternalCamera(self.useExternalCameraCheckBox))
            self.faceProcessingThread = FaceProcessingThread()
            self.startWebcamButton.clicked.connect(self.startWebcam)
    
            #A\B功能开关
    
            # 数据库
            self.initDbButton.setIcon(QIcon('./icons/warning.png'))
            self.initDbButton.clicked.connect(self.initDb)
    
            self.timer = QTimer(self)  # 初始化一个定时器
            self.timer.timeout.connect(self.updateFrame)



2.5 人脸录入加识别效果

录入过程
在这里插入图片描述

识别效果
在这里插入图片描述

3 疲劳检测算法

该系统采用Dlib库中人脸68个关键点检测shape_predictor_68_face_landmarks.dat的dat模型库及视频中的人脸,之后返回人脸特征点坐标、人脸框及人脸角度等。本系统利用这68个关键点对驾驶员的疲劳状态进行检测,算法如下:

  1. 初始化Dlib的人脸检测器(HOG),然后创建面部标志物预测;
  2. 使用dlib.get_frontal_face_detector() 获得脸部位置检测器;
  3. 使用dlib.shape_predictor获得脸部特征位置检测器;
  4. 分别获取左、右眼面部标志的索引;
  5. 打开cv2本地摄像头。

Dlib库68个特征点模型如图所示:
在这里插入图片描述

3.1 眼睛检测算法

基于EAR算法的眨眼检测,当人眼睁开时,EAR在某个值域范围内波动,当人眼闭合时,EAR迅速下降,理论上接近于0。当EAR低于某个阈值时,眼睛处于闭合状态;当EAR由某个值迅速下降至小于该阈值,再迅速上升至大于该阈值,则判断为一次眨眼。为检测眨眼次数,需要设置同一次眨眼的连续帧数。眨眼速度较快,一般1~3帧即可完成眨眼动作。眼部特征点如图:

在这里插入图片描述

EAR计算公式如下:
在这里插入图片描述
当后帧眼睛宽高比与前一帧差值的绝对值(EAR)大于0.2时,认为驾驶员在疲劳驾驶。(68点landmark中可以看到37-42为左眼,43-48为右眼)
在这里插入图片描述
右眼开合度可以通过以下公式:
在这里插入图片描述
眼睛睁开度从大到小为进入闭眼期,从小到大为进入睁眼期,计算最长闭眼时间(可用帧数来代替)。闭眼次数为进入闭眼、进入睁眼的次数。通过设定单位时间内闭眼次数、闭眼时间的阈值判断人是否已经疲劳了。

相关代码:

# 疲劳检测,检测眼睛和嘴巴的开合程度

from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np  # 数据处理的库 numpy
import argparse
import imutils
import time
import dlib
import cv2
import math
import time
from threading import Thread

def eye_aspect_ratio(eye):
    # 垂直眼标志(X,Y)坐标
    A = dist.euclidean(eye[1], eye[5])  # 计算两个集合之间的欧式距离
    B = dist.euclidean(eye[2], eye[4])
    # 计算水平之间的欧几里得距离
    # 水平眼标志(X,Y)坐标
    C = dist.euclidean(eye[0], eye[3])
    # 眼睛长宽比的计算
    ear = (A + B) / (2.0 * C)
    # 返回眼睛的长宽比
    return ear

3.2 打哈欠检测算法

基于MAR算法的哈欠检测,利用Dlib提取嘴部的6个特征点,通过这6个特征点的坐标(51、59、53、57的纵坐标和49、55的横坐标)来计算打哈欠时嘴巴的张开程度。当一个人说话时,点51、59、53、57的纵坐标差值增大,从而使MAR值迅速增大,反之,当一个人闭上嘴巴时,MAR值迅速减小。

嘴部主要取六个参考点,如下图:
在这里插入图片描述
计算公式:
在这里插入图片描述
通过公式计算MAR来判断是否张嘴及张嘴时间,从而确定驾驶员是否在打哈欠。阈值应经过大量实验,能够与正常说话或哼歌区分开来。为提高判断的准确度,采用双阈值法进行哈欠检测,即对内轮廓进行检测:结合张口度与张口时间进行判断。Yawn为打哈欠的帧数,N为1
min内总帧数,设双阈值法哈欠检测的阈值为10%,当打哈欠频率Freq>10%时,则认为驾驶员打了1个深度哈欠或者至少连续2个浅哈欠,此时系统进行疲劳提醒。

相关代码:

# 疲劳检测,检测眼睛和嘴巴的开合程度

from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np  # 数据处理的库 numpy
import argparse
import imutils
import time
import dlib
import cv2
import math
import time
from threading import Thread

def mouth_aspect_ratio(mouth):  # 嘴部
    A = np.linalg.norm(mouth[2] - mouth[10])  # 51, 59
    B = np.linalg.norm(mouth[4] - mouth[8])  # 53, 57
    C = np.linalg.norm(mouth[0] - mouth[6])  # 49, 55
    mar = (A + B) / (2.0 * C)
    return mar

相应的演示效果如下:

在这里插入图片描述

3.3 点头检测算法

基于HPE算法的点头检测

HPE(Head Pose
Estimation,HPE)算法步骤:2D人脸关键点检测,3D人脸模型匹配,求解3D点和对应2D点的转换关系,根据旋转矩阵求解欧拉角。检测过程中需要使用世界坐标系(UVW)、相机坐标系(XYZ)、图像中心坐标系(uv)和像素坐标系(xy)。一个物体相对于相机的姿态可以使用旋转矩阵和平移矩阵来表示。

  • 平移矩阵:物体相对于相机的空间位置关系矩阵,用T表示;
  • 旋转矩阵:物体相对于相机的空间姿态关系矩阵,用R表示。

因此必然少不了坐标系转换。如图所示:
在这里插入图片描述
于是世界坐标系(UVW)、相机坐标系(XYZ)、图像中心坐标系(uv)和像素坐标系(xy)四兄弟闪亮登场。相对关系如下:
世界坐标系转换到相机坐标:
在这里插入图片描述
相机坐标系转换到像素坐标系:
在这里插入图片描述
像素坐标系与世界坐标系的关系为:
在这里插入图片描述
图像中心坐标系转换到像素坐标系:
在这里插入图片描述
得到旋转矩阵后,求欧拉角:
在这里插入图片描述
设定参数阈值为0.3,在一个时间段,如10
s内,当低头欧拉角|Pitch|≥20°或者头部倾斜欧拉角|Roll|≥20°的时间比例超过0.3时,则认为驾驶员处于瞌睡状态,发出预警。
在这里插入图片描述
相关效果展示:
在这里插入图片描述

4 PyQt5

4.1 简介

Qt是一个跨平台的 C++ 开发库,主要用来开发图形用户界面程序(GUI),当然也可以开发不带界面的命令行程序。
但Qt 是纯 C++ 开发的,PyQt5是基于图形程序框架Qt5的Python语言实现,由一组Python模块构成。

  • QLabel控件:用来显示文本或图像。

  • QLineEdit窗口控件:提供了一个单页面的单行文本编辑器。

  • QTextEdit窗口控件:提供了一个单页面的多行文本编辑器。

  • QPushButton窗口控件:提供了一个命令按钮。

  • QRadioButton控件:提供了一个单选钮和一个文本或像素映射标签。

  • QCheckBox窗口控件:提供了一个带文本标签的复选框。

  • QspinBox控件:允许用户选择一个值,要么通过按向上/向下键增加/减少当前显示值,要么直接将值输入到输入框中。

  • QScrollBar窗口控件:提供了一个水平的或垂直的滚动条。

  • QSlider控件:提供了一个垂直的或水平的滑动条。

  • QComboBox控件:一个组合按钮,用于弹出列表。

  • QMenuBar控件:提供了一个横向菜单栏。

  • QStatusBar控件:提供了一个适合呈现状态信息的水平条,通常放在QMainWindow的底部。

  • QToolBar控件:提供了一个工具栏,可以包含多个命令按钮,通常放在QMainWindow的顶部。

  • QListView控件:可以显示和控制可选的多选列表,可以设置ListMode或IconMode。

  • QPixmap控件:可以在绘图设备上显示图像,通常放在QLabel或QPushButton类中。

  • Qdialog控件:对话框窗口的基类。

  • QWidget是所有用户界面类的基类,它能接收所有的鼠标、键盘和其他系统窗口事件。没有被嵌入到父窗口中的Widget会被当作一个窗口来调用,当然,它也可以使用setWindowFlags(Qt.WindowFlags)函数来设置窗口的显示效果。QWidget的构造函数可以接收两个参数,其中第一个参数是该窗口的父窗口;第二个参数是该窗口的Flag,也就是- Qt.WindowFlags。根据父窗口来决定Widget是嵌入到父窗口中还是被当作一个独立的窗口来调用,根据Flag来设置Widget窗口的一些属性。

  • QMainWindow(主窗口)一般是应用程序的框架,在主窗口中可以添加所需要的Widget,比如添加菜单栏、工具栏、状态栏等。主窗口通常用于提供一个大的中央窗口控件(如文本编辑或者绘制画布)以及周围的菜单栏、工具栏和状态栏。QMainWindow常常被继承,这使得封装中央控件、菜单栏,工具栏以及窗口状态变得更容易,也可以使用Qt Designer来创建主窗口。

4.2相关界面代码

#部分代码
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, QRegExp, Qt
from PyQt5.QtGui import QImage, QPixmap, QIcon, QTextCursor, QRegExpValidator,QPainter
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
from ui.untitled import Ui_Form
from core2 import CoreUI
from dataRecord import DataRecordUI
from dataManage import DataManageUI

from ui.pic import Ui_Form1
from PyQt5 import QtCore
import sys
import os
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
class Main(CoreUI,QMainWindow):
	def __init__(self):
		super(Main, self).__init__()
		qssStyle = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle)

		self.setWindowFlag(QtCore.Qt.FramelessWindowHint)#设置无边框  但是按键得重新设置了
		#self.startWebcamButton()
		self.startWebcamButton.setStyleSheet(
			"startWebcamButton{color:black}"
			"startWebcamButton:hover{color:red}"
			"startWebcamButton{background-color:rgb(180,180,180)}"
			"startWebcamButton{border:2px}"
			"startWebcamButton{border-radius:10px}"
			"startWebcamButton{padding:2px 4px}"
			"startWebcamButton{font-size:14pt}")
		self.pushButton.setStyleSheet(
			"#pushButton {color:rgb(255,255,255);border-image:url(sip/anniu.png);text-aligh:left;font-size:18px;font-weight:bold;};"
		)
		self.pushButton_2.setStyleSheet(
			"#pushButton_2 {color:rgb(255,255,255);border-image:url(sip/anniu.png);text-aligh:left;font-size:18px;font-weight:bold;};"
		)
		self.pushButton_3.setStyleSheet(
			"#pushButton_3 {color:rgb(255,255,255);border-image:url(sip/anniu.png);text-aligh:left;font-size:18px;font-weight:bold;};"
		)
		self.pushButton_4.setStyleSheet(
			"#pushButton_4 {color:rgb(255,255,255);border-image:url(sip/anniu.png);text-aligh:left;font-size:18px;font-weight:bold;};"
		)
		#self.setStyleSheet("color:white")#颜色全变
		self.pushButton_4.clicked.connect(QCoreApplication.instance().quit)
	def closewin(self):
		self.close()

	def mouseMoveEvent(self, e: QMouseEvent):  # 重写移动事件
		self._endPos = e.pos() - self._startPos
		self.move(self.pos() + self._endPos)

	def mousePressEvent(self, e: QMouseEvent):
		if e.button() == Qt.LeftButton:
			self._isTracking = True
			self._startPos = QPoint(e.x(), e.y())

	def mouseReleaseEvent(self, e: QMouseEvent):
		if e.button() == Qt.LeftButton:
			self._isTracking = False
			self._startPos = None
			self._endPos = None

	def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
		painter = QPainter(self)
		pixmap = QPixmap("sip/5.jfif")
		painter.drawPixmap(self.rect(), pixmap)
		#self.setupUi(self)
	'''def open(self):
		path = r"sip/new"
		QDesktopServices.openUrl(QUrl.fromLocalFile(path))'''
class Child(DataRecordUI,QMainWindow):
	def __init__(self):
		super(Child, self).__init__()
		self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
		qssStyle = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle)
		#self.setupUi(self)
	def OPEN(self):
			self.show()
	def closewin(self):
		self.close()
	def returnmain(self):

		self.pushButton.clicked.connect(main.show)
		self.pushButton.clicked.connect(ch.hide)
	def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
		painter = QPainter(self)
		pixmap = QPixmap("sip/5.jfif")
		painter.drawPixmap(self.rect(), pixmap)

class Child1(DataManageUI,QMainWindow):
	def __init__(self):
		super(Child1,self).__init__()
		self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
		qssStyle = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle)
	def OPEN(self):
		self.show()
	def closewin(self):
		self.close()
	def returnmain(self):

		self.pushButton.clicked.connect(main.show)
		self.pushButton.clicked.connect(ch1.hide)
	def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
		painter = QPainter(self)
		pixmap = QPixmap("sip/5.jfif")
		painter.drawPixmap(self.rect(), pixmap)

class help(Ui_Form,QWidget):
	def __init__(self):
		super(help,self).__init__()
		self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
		self.setupUi(self)
		qssStyle = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle)
		'''qssStyle1 = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle1)'''
	def OPEN(self):
		self.show()
	def returnmain(self):
		self.pushButton.clicked.connect(main.show)
		self.pushButton.clicked.connect(Help.hide)
	def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
		painter = QPainter(self)
		pixmap = QPixmap("sip/5.jfif")
		painter.drawPixmap(self.rect(), pixmap)

class add(Ui_Form1,QWidget):
	def __init__(self):
		super(add,self).__init__()
		#self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
		self.setupUi(self)
		self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
		qssStyle = open(os.path.join('sip/123.qss')).read()
		self.setStyleSheet(qssStyle)
		#qssStyle = open(os.path.join('123.qss')).read()
		self.pushButton.clicked.connect(self.close)
		#self.setStyleSheet(qssStyle)
	def OPEN(self):
		self.show()
	def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
		painter = QPainter(self)
		pixmap = QPixmap("./sip/5.jfif")
		painter.drawPixmap(self.rect(), pixmap)

if __name__ =="__main__":
	#QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
	app = QApplication(sys.argv)
	main = Main()
	ch = Child()
	ch1 = Child1()
	Help = help()
	ADD=add()
	main.show()
	#main.setStyleSheet("{border-image:url(sip/background.jpg)}")
	main.pushButton.clicked.connect(main.hide)
	main.pushButton.clicked.connect(ch.OPEN)
	main.pushButton_2.clicked.connect(main.hide)
	main.pushButton_2.clicked.connect(ch1.OPEN)
	main.pushButton_3.clicked.connect(main.hide)
	main.pushButton_3.clicked.connect(Help.OPEN)
	main.pushButton_11.clicked.connect(ADD.OPEN)
	ch.pushButton.clicked.connect(ch.returnmain)
	ch1.pushButton.clicked.connect(ch1.returnmain)
	Help.pushButton.clicked.connect(Help.returnmain)
	#ADD.pushButton.clicked.connect(ADD.close)
	sys.exit(app.exec_())

5 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/444181.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图|dfs bfs|最小生成树|最短路|一篇搞定图的所有知识点

文章目录 图前言项目代码仓库图的基本概念图的表示方法邻接矩阵邻接表图的一些相关概念 图的遍历bfsdfs如果给的图不是连通图? 最小生成树Kruskal算法Prim算法 最短路径单源最短路径--Dijkstra算法单源最短路径--Bellman-Ford算法多源最短路径--Floyd-Warshall算法 …

数据治理实践——YY 直播业务指标治理实践

目录 一、问题背景 1.1 问题场景 1.2 问题小结 二、治理方案 2.1 治理目标 2.2 团队协同,共建规范 2.3 指标管理的定位 2.4 指标管理的目标及思路 2.5 指标管理,规范内容落地 2.6 数仓设计-关联指标维度 2.7 数据报表开发-配置口径说明 2.8 …

MongoDB在Linux环境下的安装与配置

目录 1. 准备工作 2. 安装MongoDB 2.1 传输MongoDB安装包 2.2 解压安装包 2.3 创建MongoDB安装目录 2.4 创建数据目录和日志目录 3. 启动MongoDB服务 3.1 启动MongoDB 3.2 连接MongoDB 3.3 退出MongoDB 1. 准备工作 在安装MongoDB之前,请确保您已具备以下…

Solidity Uniswap V2 价格预言机

预言机是连接区块链与链下服务的桥梁,这样就可以从智能合约中查询现实世界的数据。Chainlink 是最大的oracle网络之一,创建于 2017 年,如今已成为许多 DeFi 应用的重要组成部分。https://github.com/XuHugo/solidityproject Uniswap 虽然是链…

【leetcode热题】寻找旋转排序数组中的最小值 II

难度: 困难通过率: 38.7%题目链接:. - 力扣(LeetCode) 题目描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请找出其中最小的…

【react框架】跟我一起速读Next.js官方入门教学课程文档

文章目录 前言目录结构样式方案正常引入样式文件Tailwind方案CSS Modules方案clsx方案 文字和图片优化文字图片 Pages和Layout的机制PagesLayout 通过Link组件改变路由并且拆分打包提供Hooks通过Vercel创建数据未完待续... 前言 对于那些对Next.js一无所知的前端伙伴来说&…

鸿蒙开发(二)-项目结构

鸿蒙开发(二)-项目结构 上篇文章我们讲了如何配置鸿蒙开发的基础环境,以及创建了第一个鸿蒙程序。 这篇我们讲述了鸿蒙应用的项目目录结构。 如图所示:我们切换项目project可以看到。 另一种则是Ohos模式: AppScope->app.json5 应用的全局配置 {&q…

华为新发布磁电存储“王炸”,到底是什么?

最近,在巴塞罗那举行的2024年世界移动通信大会(MWC24)上,华为数据存储产品线总裁周彼得博士介绍了这款即将面世的产品。他向听众表示,与磁带存储相比,该设备可以降低20%的总连接成本,而与硬盘相…

DHCP中继实验(华为)

思科设备参考: 一,技术简介 DHCP中继,可以实现在不同子网和物理网段之间处理和转发DHCP信息的功能。如果DHCP客户机与DHCP服务器在同一个物理网段,则客户机可以正确地获得动态分配的IP地址。如果不在同一个物理网段,…

Web渗透测试流程

什么是渗透测试 渗透测试 (penetration test),是通过模拟恶意黑客的攻击方法,来评估计算机网络系统安全的一种评估方法。这个过程包括对系统的任何弱点、技术缺陷或漏洞的主动分析,这个分析是从一个攻击者可能存在的位置来进行的,并且从这个…

机器学习第29周周报 Beyond Dropout

文章目录 week29 Beyond Dropout摘要Abstract一、泛化理论二、文献阅读1. 题目2. abstract3. 网络架构3.1 特征图失真3.2 失真优化 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1 全连接层实验4.3.2 卷积网络上的实验 4.4 结论 小结参考文献 week29 Beyond Dropout …

国产硅片膜厚检测仪

硅片膜厚检测仪是半导体行业中一种至关重要的设备,用于精确测量硅片上薄膜的厚度。在半导体制造工艺中,薄膜厚度的控制对于保证器件性能和可靠性具有决定性的作用。因此,硅片膜厚检测仪的研发和应用对于推动半导体技术的发展具有重要意义。 一…

SSM框架,MyBatis-Plus的学习(下)

条件构造器 使用MyBatis-Plus的条件构造器,可以构建灵活高效的查询条件,可以通过链式调用来组合多个条件。 条件构造器的继承结构 Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装&#xf…

苍穹外卖-day01

苍穹外卖-day01 目录 苍穹外卖-day01课程内容1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 产品原型2.3 技术选型 3. 开发环境搭建3.1 前端环境搭建3.2 后端环境搭建3.2.1 熟悉项目结构3.2.2 Git版本控制3.2.3 数据库环境…

一篇搞懂什么是LRU缓存|一篇搞懂LRU缓存的实现|LRUCache详解和实现

LRUCache 文章目录 LRUCache前言项目代码仓库什么时候会用到缓存(Cache)缓存满了,怎么办?什么是LRUCacheLRUCache的实现LRUCache对应的OJ题实现LRUCache对应的STL风格实现 前言 这里分享我的一些博客专栏,都是干货满满的。 手撕数据结构专栏…

账号管理支持批量测试资产可连接性,资产管理支持通过标签方式选择资产,JumpServer堡垒机v3.10.4 LTS版本发布

2024年3月4日,JumpServer开源堡垒机正式发布v3.10.4 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和优化,并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS最新版本,以获得更佳的使用体验。 在v3.10.4 LTS版本中&a…

Chrome中如何导出和导入书签

导出书签 如下图所示: 右上角三点->书签和清单->书签管理器->右上角三点->导出书签 然后你选择保存地址即可。打开后如下: 导入书签 如下图所示: 右上角三点->书签和清单->导入书签和设置->选择以前导出的书签&…

基于Vue移动端电影票务服务APP设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术 3 1.1 Vue框架 3 1.2 数据库MongoDB 3 1.3 Axios请求 3 1.4 H5、CSS3和JavaScript 4 1.5 本章小结 4 2 系统分析 5 2.1 功能需求 5 2.2 用例分析 5 2.3 用户功能 6 2.4本章小结 6 3 基于Vue电影票务服务APP设计 7 3.1 页面设计 …

DFS和BFS以及练习题目(未完待续)

DFS和BFS 温馨提示:学习dfs之前最好先了解一下递归的思想。 递归思想 斐波那契 题目分析 题目代码 import java.util.Scanner; public class Main{static long dp[]; public static void main(String[] args) {Scanner scanner new Scanner(System.in);int t…

手机号验证码重新发送

前文叙述 很久以前做的一个 demo ,纯 HTML 、CSS、js 制作,一定时间段之后才可以重新发送验证码,如 60s 后再次发送验证码,在该时间段内发送验证码按钮为禁用状态,实战开发过程也亦是同理,因此记录一手。 一…
最新文章