openCV实战项目--人脸考勤

news2024/10/6 2:25:10

人脸任务在计算机视觉领域中十分重要,本项目主要使用了两类技术:人脸检测+人脸识别

代码分为两部分内容:人脸注册人脸识别

  • 人脸注册:将人脸特征存储进数据库,这里用feature.csv代替
  • 人脸识别:将人脸特征与CSV文件中人脸特征进行比较,如果成功匹配则写入考勤文件attendance.csv

文章前半部分为一步步实现流程介绍,最后会有整理过后的完整项目代码。

一、项目实现

A. 注册: 

导入相关包

import cv2
import numpy as np
import dlib
import time
import csv
# from argparse import ArgumentParser
from PIL import Image, ImageDraw, ImageFont

设计注册功能

注册过程我们需要完成的事:

  • 打开摄像头获取画面图片
  • 在图片中检测并获取人脸位置
  • 根据人脸位置获取68个关键点
  • 根据68个关键点生成特征描述符
  • 保存
  • (优化)展示界面,加入注册时成功提示等

1、基本步骤

我们首先进行前三步

# 检测人脸,获取68个关键点,获取特征描述符
def faceRegister(faceId=1, userName='default', interval=3, faceCount=3, resize_w=700, resize_h=400):
    '''
    faceId:人脸ID
    userName: 人脸姓名
    faceCount: 采集该人脸图片的数量
    interval: 采集间隔
    '''

    cap = cv2.VideoCapture(0)
    # 人脸检测模型
    hog_face_detector = dlib.get_frontal_face_detector()
    # 关键点 检测模型
    shape_detector = dlib.shape_predictor('./weights/shape_predictor_68_face_landmarks.dat')
    # resnet模型
    face_descriptor_extractor = dlib.face_recognition_model_v1('./weights/dlib_face_recognition_resnet_model_v1.dat')
    
    while True:
        ret, frame = cap.read()

        # 镜像
        frame = cv2.flip(frame,1)

        # 转为灰度图
        frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        
        # 检测人脸
        detections = hog_face_detector(frame,1)

        for face in detections:
            # 人脸框坐标 左上和右下
            l, t, r, b = face.left(), face.top(), face.right(), face.bottom()

            # 获取68个关键点
            points = shape_detector(frame,face)
            
            # 绘制关键点
            for point in points.parts():
                cv2.circle(frame,(point.x,point.y),2,(0,255,0),1)

            # 绘制矩形框
            cv2.rectangle(frame,(l,t),(r,b),(0,255,0),2)
                   
        cv2.imshow("face",frame)
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
                 
    cap.release()
    cv2.destroyAllWindows
                    
            
faceRegister()      

此时一张帅脸如下:

2、描述符的采集

之后,我们根据参数,即faceCount 和 Interval 进行描述符的生成和采集

(这里我默认是faceCount=3,Interval=3,即每3秒采集一次,共3次)

def faceRegister(faceId=1, userName='default', interval=3, faceCount=3, resize_w=700, resize_h=400):
    '''
    faceId:人脸ID
    userName: 人脸姓名
    faceCount: 采集该人脸图片的数量
    interval: 采集间隔
    '''

    cap = cv2.VideoCapture(0)
    # 人脸检测模型
    hog_face_detector = dlib.get_frontal_face_detector()
    # 关键点 检测模型
    shape_detector = dlib.shape_predictor('./weights/shape_predictor_68_face_landmarks.dat')
    # resnet模型
    face_descriptor_extractor = dlib.face_recognition_model_v1('./weights/dlib_face_recognition_resnet_model_v1.dat')
    
    
    # 开始时间
    start_time = time.time()
    # 执行次数
    collect_times = 0
    

    while True:
        ret, frame = cap.read()
        
        # 镜像
        frame = cv2.flip(frame,1)

        # 转为灰度图
        frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        
        # 检测人脸
        detections = hog_face_detector(frame,1)

        for face in detections:
            # 人脸框坐标 左上和右下
            l, t, r, b = face.left(), face.top(), face.right(), face.bottom()

            # 获取68个关键点
            points = shape_detector(frame,face)

            # 绘制人脸关键点
            for point in points.parts():
                cv2.circle(frame, (point.x, point.y), 2, (0, 255, 0), 1)
            # 绘制矩形框
            cv2.rectangle(frame, (l, t), (r, b), (0, 255, 0), 2)
            
            # 采集:
            if collect_times < faceCount:
                # 获取当前时间
                now = time.time()
                # 时间限制
                if now - start_time > interval:
                    # 获取特征描述符
                    face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame,points)
                    # dlib格式转为数组
                    face_descriptor = [f for f in face_descriptor]

                    collect_times += 1
                    start_time = now
                    print("成功采集{}次".format(collect_times))
                else:
                    # 时间间隔不到interval
                    print("等待进行下一次采集")
                    pass
            else:
                # 已经成功采集完3次了
                print("采集完毕")
                cap.release()
                cv2.destroyAllWindows()
                return
              
        cv2.imshow("face",frame)
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
                  
    cap.release()
    cv2.destroyAllWindows()
                    
            
faceRegister()  
等待进行下一次采集
...
成功采集1次
等待进行下一次采集
...
成功采集2次
等待进行下一次采集
...
成功采集3次
采集完毕

3、完整的注册

最后就是写入csv文件

这里加入了注册成功等的提示,且把一些变量放到了全局,因为后面人脸识别打卡时也会用到。

# 加载人脸检测器
hog_face_detector = dlib.get_frontal_face_detector()
cnn_detector = dlib.cnn_face_detection_model_v1('./weights/mmod_human_face_detector.dat')
haar_face_detector = cv2.CascadeClassifier('./weights/haarcascade_frontalface_default.xml')

# 加载关键点检测器
points_detector = dlib.shape_predictor('./weights/shape_predictor_68_face_landmarks.dat')
# 加载resnet模型
face_descriptor_extractor = dlib.face_recognition_model_v1('./weights/dlib_face_recognition_resnet_model_v1.dat')
# 绘制中文
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(img)
    # 字体的格式
    fontStyle = ImageFont.truetype(
        "./fonts/songti.ttc", textSize, encoding="utf-8")
    # 绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
# 绘制左侧信息
def drawLeftInfo(frame, fpsText, mode="Reg", detector='haar', person=1, count=1):
    # 帧率
    cv2.putText(frame, "FPS:  " + str(round(fpsText, 2)), (30, 50), cv2.FONT_ITALIC, 0.8, (0, 255, 0), 2)

    # 模式:注册、识别
    cv2.putText(frame, "Mode:  " + str(mode), (30, 80), cv2.FONT_ITALIC, 0.8, (0, 255, 0), 2)

    if mode == 'Recog':
        # 检测器
        cv2.putText(frame, "Detector:  " + detector, (30, 110), cv2.FONT_ITALIC, 0.8, (0, 255, 0), 2)

        # 人数
        cv2.putText(frame, "Person:  " + str(person), (30, 140), cv2.FONT_ITALIC, 0.8, (0, 255, 0), 2)

        # 总人数
        cv2.putText(frame, "Count:  " + str(count), (30, 170), cv2.FONT_ITALIC, 0.8, (0, 255, 0), 2)
# 注册人脸
def faceRegiser(faceId=1, userName='default', interval=3, faceCount=3, resize_w=700, resize_h=400):
    # 计数
    count = 0
    # 开始注册时间
    startTime = time.time()

    # 视频时间
    frameTime = startTime

    # 控制显示打卡成功的时长
    show_time = (startTime - 10)

    # 打开文件
    f = open('./data/feature.csv', 'a', newline='')
    csv_writer = csv.writer(f)

    cap = cv2.VideoCapture(0)

    while True:
        ret, frame = cap.read()
        frame = cv2.resize(frame, (resize_w, resize_h))
        frame = cv2.flip(frame, 1)

        # 检测
        face_detetion = hog_face_detector(frame, 1)

        for face in face_detetion:
            # 识别68个关键点
            points = points_detector(frame, face)
            # 绘制人脸关键点
            for point in points.parts():
                cv2.circle(frame, (point.x, point.y), 2, (0, 255, 0), 1)
            # 绘制框框
            l, t, r, b = face.left(), face.top(), face.right(), face.bottom()
            cv2.rectangle(frame, (l, t), (r, b), (0, 255, 0), 2)

            now = time.time()

            if (now - show_time) < 0.5:
                frame = cv2AddChineseText(frame,
                                          "注册成功 {count}/{faceCount}".format(count=(count + 1), faceCount=faceCount),
                                          (l, b + 30), textColor=(255, 0, 255), textSize=30)

            # 检查次数

            if count < faceCount:

                # 检查时间
                if now - startTime > interval:
                    # 特征描述符
                    face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame, points)

                    face_descriptor = [f for f in face_descriptor]

                    # 描述符增加进data文件
                    line = [faceId, userName, face_descriptor]
                    # 写入
                    csv_writer.writerow(line)

                    # 保存照片样本

                    print('人脸注册成功 {count}/{faceCount},faceId:{faceId},userName:{userName}'.format(count=(count + 1),
                                                                                                  faceCount=faceCount,
                                                                                                  faceId=faceId,
                                                                                                  userName=userName))

                    frame = cv2AddChineseText(frame,
                                              "注册成功 {count}/{faceCount}".format(count=(count + 1), faceCount=faceCount),
                                              (l, b + 30), textColor=(255, 0, 255), textSize=30)
                    show_time = time.time()

                    # 时间重置
                    startTime = now
                    # 次数加一
                    count += 1


            else:
                print('人脸注册完毕')
                f.close()
                cap.release()
                cv2.destroyAllWindows()
                return

        now = time.time()
        fpsText = 1 / (now - frameTime)
        frameTime = now
        # 绘制
        drawLeftInfo(frame, fpsText, 'Register')

        cv2.imshow('Face Attendance Demo: Register', frame)
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    f.close()
    cap.release()
    cv2.destroyAllWindows()

此时执行:

faceRegiser(3,"用户B")

人脸注册成功 1/3,faceId:3,userName:用户B
人脸注册成功 2/3,faceId:3,userName:用户B
人脸注册成功 3/3,faceId:3,userName:用户B
人脸注册完毕

其features文件:

B. 识别、打卡

识别步骤如下:

  • 打开摄像头获取画面
  • 根据画面中的图片获取里面的人脸特征描述符
  • 根据特征描述符将其与feature.csv文件里特征做距离判断
  • 获取ID、NAME
  • 考勤记录写入attendance.csv里

这里与上面流程相似,不过是加了一个对比功能,距离小于阈值,则表示匹配成功。就加快速度不一步步来了,代码如下:

# 刷新右侧考勤信息
def updateRightInfo(frame, face_info_list, face_img_list):
    # 重新绘制逻辑:从列表中每隔3个取一批显示,新增人脸放在最前面

    # 如果有更新,重新绘制

    # 如果没有,定时往后移动

    left_x = 30
    left_y = 20
    resize_w = 80

    offset_y = 120
    index = 0

    frame_h = frame.shape[0]
    frame_w = frame.shape[1]

    for face in face_info_list[:3]:
        name = face[0]
        time = face[1]
        face_img = face_img_list[index]

        # print(face_img.shape)

        face_img = cv2.resize(face_img, (resize_w, resize_w))

        offset_y_value = offset_y * index
        frame[(left_y + offset_y_value):(left_y + resize_w + offset_y_value), -(left_x + resize_w):-left_x] = face_img

        cv2.putText(frame, name, ((frame_w - (left_x + resize_w)), (left_y + resize_w) + 15 + offset_y_value),
                    cv2.FONT_ITALIC, 0.5, (0, 255, 0), 1)
        cv2.putText(frame, time, ((frame_w - (left_x + resize_w)), (left_y + resize_w) + 30 + offset_y_value),
                    cv2.FONT_ITALIC, 0.5, (0, 255, 0), 1)

        index += 1

    return frame
# 返回DLIB格式的face
def getDlibRect(detector='hog', face=None):
    l, t, r, b = None, None, None, None

    if detector == 'hog':
        l, t, r, b = face.left(), face.top(), face.right(), face.bottom()

    if detector == 'cnn':
        l = face.rect.left()
        t = face.rect.top()
        r = face.rect.right()
        b = face.rect.bottom()

    if detector == 'haar':
        l = face[0]
        t = face[1]
        r = face[0] + face[2]
        b = face[1] + face[3]

    nonnegative = lambda x: x if x >= 0 else 0
    return map(nonnegative, (l, t, r, b))
# 获取CSV中信息
def getFeatList():
    print('加载注册的人脸特征')

    feature_list = None
    label_list = []
    name_list = []

    # 加载保存的特征样本
    with open('./data/feature.csv', 'r') as f:
        csv_reader = csv.reader(f)
        for line in csv_reader:
            # 重新加载数据
            faceId = line[0]
            userName = line[1]
            face_descriptor = eval(line[2])

            label_list.append(faceId)
            name_list.append(userName)

            # 转为numpy格式
            face_descriptor = np.asarray(face_descriptor, dtype=np.float64)
            # 转为二维矩阵,拼接
            face_descriptor = np.reshape(face_descriptor, (1, -1))
            # 初始化
            if feature_list is None:
                feature_list = face_descriptor
            else:
                # 拼接
                feature_list = np.concatenate((feature_list, face_descriptor), axis=0)
    print("特征加载完毕")
    return feature_list, label_list, name_list
# 人脸识别
def faceRecognize(detector='haar', threshold=0.5, write_video=False, resize_w=700, resize_h=400):
    # 视频时间
    frameTime = time.time()

    # 加载特征
    feature_list, label_list, name_list = getFeatList()

    face_time_dict = {}
    # 保存name,time人脸信息
    face_info_list = []
    # numpy格式人脸图像数据
    face_img_list = []

    # 侦测人数
    person_detect = 0

    # 统计人脸数
    face_count = 0

    # 控制显示打卡成功的时长
    show_time = (frameTime - 10)

    # 考勤记录
    f = open('./data/attendance.csv', 'a')
    csv_writer = csv.writer(f)

    cap = cv2.VideoCapture(0)
    # resize_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))//2
    # resize_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) //2

    videoWriter = cv2.VideoWriter('./record_video/out' + str(time.time()) + '.mp4', cv2.VideoWriter_fourcc(*'MP4V'), 15,
                                  (resize_w, resize_h))

    while True:
        ret, frame = cap.read()
        frame = cv2.resize(frame, (resize_w, resize_h))
        frame = cv2.flip(frame, 1)

        # 切换人脸检测器
        if detector == 'hog':
            face_detetion = hog_face_detector(frame, 1)
        if detector == 'cnn':
            face_detetion = cnn_detector(frame, 1)
        if detector == 'haar':
            frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            face_detetion = haar_face_detector.detectMultiScale(frame_gray, minNeighbors=7, minSize=(100, 100))

        person_detect = len(face_detetion)

        for face in face_detetion:

            l, t, r, b = getDlibRect(detector, face)

            face = dlib.rectangle(l, t, r, b)

            # 识别68个关键点
            points = points_detector(frame, face)

            cv2.rectangle(frame, (l, t), (r, b), (0, 255, 0), 2)

            # 人脸区域
            face_crop = frame[t:b, l:r]

            # 特征
            face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame, points)
            face_descriptor = [f for f in face_descriptor]
            face_descriptor = np.asarray(face_descriptor, dtype=np.float64)

            # 计算距离
            distance = np.linalg.norm((face_descriptor - feature_list), axis=1)
            # 最小距离索引
            min_index = np.argmin(distance)
            # 最小距离
            min_distance = distance[min_index]

            predict_name = "Not recog"

            if min_distance < threshold:
                # 距离小于阈值,表示匹配
                predict_id = label_list[min_index]
                predict_name = name_list[min_index]

                # 判断是否新增记录:如果一个人距上次检测时间>3秒,或者换了一个人,将这条记录插入
                need_insert = False
                now = time.time()
                if predict_name in face_time_dict:
                    if (now - face_time_dict[predict_name]) > 3:
                        # 刷新时间
                        face_time_dict[predict_name] = now
                        need_insert = True
                    else:
                        # 还是上次人脸
                        need_insert = False

                else:
                    # 新增数据记录
                    face_time_dict[predict_name] = now
                    need_insert = True

                if (now - show_time) < 1:
                    frame = cv2AddChineseText(frame, "打卡成功", (l, b + 30), textColor=(0, 255, 0), textSize=40)

                if need_insert:
                    # 连续显示打卡成功1s
                    frame = cv2AddChineseText(frame, "打卡成功", (l, b + 30), textColor=(0, 255, 0), textSize=40)
                    show_time = time.time()

                    time_local = time.localtime(face_time_dict[predict_name])
                    # 转换成新的时间格式(2016-05-05 20:28:54)
                    face_time = time.strftime("%H:%M:%S", time_local)
                    face_time_full = time.strftime("%Y-%m-%d %H:%M:%S", time_local)

                    # 开始位置增加

                    face_info_list.insert(0, [predict_name, face_time])
                    face_img_list.insert(0, face_crop)

                    # 写入考勤表
                    line = [predict_id, predict_name, min_distance, face_time_full]
                    csv_writer.writerow(line)

                    face_count += 1

            # 绘制人脸点
            cv2.putText(frame, predict_name + " " + str(round(min_distance, 2)), (l, b + 30), cv2.FONT_ITALIC, 0.8,
                        (0, 255, 0), 2)

            # 处理下一张脸

        now = time.time()
        fpsText = 1 / (now - frameTime)
        frameTime = now
        # 绘制
        drawLeftInfo(frame, fpsText, 'Recog', detector=detector, person=person_detect, count=face_count)

        # 舍弃face_img_list、face_info_list后部分,节约内存
        if len(face_info_list) > 10:
            face_info_list = face_info_list[:9]
            face_img_list = face_img_list[:9]

        frame = updateRightInfo(frame, face_info_list, face_img_list)

        if write_video:
            videoWriter.write(frame)

        cv2.imshow('Face Attendance Demo: Recognition', frame)
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

    f.close()
    videoWriter.release()
    cap.release()
    cv2.destroyAllWindows()

然后效果就和我们宿舍楼下差不多了~ 

我年轻的时候,我大概比现在帅个几百倍吧,哎。

二、总代码

上文其实把登录和注册最后一部分代码放在一起就是了,这里就不再复制粘贴了,相关权重文件下载链接:opencv/data at master · opencv/opencv · GitHub

当然本项目还有很多需要优化的地方,比如设置用户不能重复、考勤打卡每天只能一次、把csv改为链接成数据库等等,后续代码优化完成后就可以部署然后和室友**了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云计算与大数据技术】数据编码LZSS算法、Snappy压缩库及分布式通信系统的讲解(图文解释 超详细)

一、数据编码概述 数据编码概述 - 在分布式系统中需要处理大量的网络数据,为了加快网络数据的传输速度,通常需 要对传输数据进行编码压缩 数据压缩是以尽可能少的数码来表示信源所发出的信号&#xff0c;减少容纳给定的消息集合或数据采样集合的信号空间&#xff0c;这里讲的…

Linux安装Maven

目录 1.下载安装包 2.解压Maven 3.添加环境变量 4.检测Maven是否搭建成功 5. 编辑 Maven的settings.xml文件 5.1设置本地仓库 5.2添加阿里云镜像 1.下载安装包 访问查看需要的版本&#xff1a;Index of /dist/maven (apache.org) 安装包统一存放到/opt/software目录下…

Java基于springboot校园德育活动预约和评分管理系统+vue+elementUI

本系统结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用JAVA语言&#xff0c;结合SpringBoot框架与Vue框架以及MYSQL数据库设计并实现的。本校园德育活动预约和评分管理系统主要包括个人中心、学生管理、活动信息管理、活动…

使用Docker实现容器之间的互通

目录 怎样实现容器之间的相互通信&#xff1f; 情况1&#xff1a;两个容器在同一网段上 情况2&#xff1a;两个容器在不同网段上 怎样实现容器之间的相互通信&#xff1f; 情况1&#xff1a;两个容器在同一网段上 命令拓展&#xff1a; 删除所有容器&#xff1a;docker rm …

NuSences 数据集解析以及 nuScenes devkit 的使用

文章目录一、官网介绍1.1 总览(Overview)1.1.1 数据搜集(Data collection)1.1.2 传感器同步&#xff08;Sensor synchronization&#xff09;1.2 数据格式&#xff08;Data format&#xff09;attributecalibrated_sensorcategoryego_poseinstancelidarseglogmapsamplesample_a…

安装包UI美化之路-升级安装与静默安装一键打包

在实际应用中&#xff0c;除了产品安装外&#xff0c;还需要能够持续升级到新的版本&#xff0c;这时候升级方案就显得比较重要&#xff1b;而还有一些使用场景&#xff0c;需要咱们的安装包在安装时&#xff0c;不要显示安装界面&#xff0c;直接在后台进行安装&#xff01; …

测试开发之前端篇-Web前端简介

自从九十年代初&#xff0c;人类创造出网页和浏览器后&#xff0c;Web取得了长足的发展&#xff0c;如今越来越多的企业级应用也选择使用Web技术来构建。 前面给大家介绍网络协议时讲到&#xff0c;您在阅读这篇文章时&#xff0c;浏览器是通过HTTP/HTTPS协议向服务器发送请求…

Python+Django的高考志愿填报辅助系统 计算机毕业设计

在各学校的教学过程中&#xff0c;学生的高考志愿填报辅助是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及&#xff0c;“基于网络的学习模式”正悄无声息的改变着传统的教室学习模式&#xff0c;“基于网络的教学平台”的研究和设计也成为教育技术领域的热点课…

音频转文字怎么转?三个方法教你音频转文字

昨天&#xff0c;朋友给我发了一条信息&#xff0c;大概的内容是“今天上班的时候&#xff0c;领导突然发了一段音频&#xff0c;说是会议的录音&#xff0c;让我朋友在下班之前整理成会议纪要发给他。无奈&#xff0c;我的朋友只能打开录音开始整理”。听到他还在听录音手动整…

Stata中的治疗效果:RA:回归调整、 IPW:逆概率加权、 IPWRA、 AIPW

今天的主题是Stata中的治疗效果。最近我们被客户要求撰写关于治疗效果的研究报告&#xff0c;包括一些图形和统计输出。 治疗效果估算器根据观察数据估算治疗对结果的因果关系。 我们将讨论四种治疗效果估计量&#xff1a; RA&#xff1a;回归调整IPW&#xff1a;逆概率加权I…

【卡尔曼滤波器】递归算法

大家好&#xff0c;我是小政。最近在学习卡尔曼滤波&#xff0c;本篇文章记录一下我学习的卡尔曼滤波器中的递归算法&#xff0c;通过举例子让大家更加清晰理解递归到底是什么&#xff1f;希望与同是卡尔曼滤波研究方向的同学进行一些交流。 递归算法1.为什么要用卡尔曼滤波器&…

zookeeper3.6.3升级jetty9.4.47解决安全漏洞CVE-2022-2048和CVE-2021-28169

客户扫描到zookeeper有CVE-2022-2048和CVE-2021-28169安全漏洞要求修复。 漏洞和官方解决办法如下&#xff1a; 一、# CVE-2022-2048 Jetty升级到这几个修复版本9.4.47. 10.0.10, 11.0.10 Eclipse Jetty 存在安全漏洞&#xff0c;该漏洞源于无效的 HTTP/2 请求可能占用连接导致…

视频配音怎么制作?手把手教你配音视频制作

相信很多短视频的创作者都知道&#xff0c;每个视频的好坏大多数取决于配音的效果&#xff0c;好的配音才能给观众留下一个深刻的印象&#xff0c;如果你想要制作一个好的视频&#xff0c;那肯定是离不开配音制作的。那你们知道视频配音怎么制作吗&#xff1f;不知道也没关系&a…

java计算机毕业设计ssm在线实验室器材设备借用管理系统42c93(附源码、数据库)

java计算机毕业设计ssm在线实验室器材设备借用管理系统42c93&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都…

“为什么同样是跳槽,有些人薪资就能翻2倍?“是我在软件测试路上走错了方向?

“为什么同样是跳槽&#xff0c;有些人薪资能翻两三倍&#xff1f;” 最近遇到一个朋友跟我吐槽如上&#xff0c;其实类似这样的问题我也听到过很多次&#xff0c;身边也不乏有认识的同事、朋友们通过跳槽拿下高薪&#xff0c;这里我先说一个我身边真实的例子&#xff1a; 学…

Java基于springboot高考填报志愿综合参考系统 vue+elementUI

高考填报志愿综合参考系统是针对目前高考填报志愿管理的实际需求&#xff0c;从实际工作出发&#xff0c;对过去的高考填报志愿综合参考系统存在的问题进行分析&#xff0c;完善用户的使用体会。采用计算机系统来管理信息&#xff0c;取代人工管理模式&#xff0c;查询便利&…

(十一)数据归一化方法BN/LN/GN/IN

文章目录0. Introduction1.Batch Normalization3.Layer Normalization4.Group Normalization6.Instance Normalization参考资料欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; 0. Introduction 在神经网络的训练过程中&#xff0c;网络的…

机器学习分类算法之逻辑回归

1、基础知识&#xff1a; 逻辑回归&#xff1a;logistic regression二分类&#xff1a;binary classification 类别一类别二noysefalsetrue01negative classpositive class 线性回归模型用于分类&#xff0c;效果一般&#xff1b;逻辑回归是最广泛使用的分类算法&#xff1b;…

main入口函数分析

在开始讲解之前&#xff0c;分享一些阅读 项目代码的经验。无论学习哪方面的知识&#xff0c;都是需要正反馈才能继续学下去。在学习开源项目的时候&#xff0c;如果不掌握一些比较好的方法&#xff0c;会比较难拿到正反馈&#xff0c;或者要坚持学习很久才能拿到正反馈。 我个…

JAVA毕业设计——基于Springboot的动漫论坛系统(源代码+数据库+ppt文档)

github代码地址 https://github.com/ynwynw/cartoonForum-public 毕业设计所有选题地址 https://github.com/ynwynw/allProject #动漫论坛系统 #java web #java #毕业设计 #课程设计 #JPa #Springboot #mysql #源代码 基于Springboot的动漫论坛系统(源代码数据库ppt文档)040 …