基于OpenCV的深度学习人脸识别系统开发全攻略(DNN+FaceNet核心技术选型)

核心技术选型表

技术组件版本/型号用途
OpenCV DNN4.5.5+人脸检测
FaceNet (facenet-pytorch)0.5.0+人脸特征提取
MiniConda最新版Python环境管理
PyTorch1.8.0+FaceNet运行基础
OpenVINO2021.4+模型加速(可选)
SSD Caffe模型res10_300x300高精度人脸检测

一、环境准备与项目搭建

1.1 MiniConda环境配置

首先我们需要安装MiniConda来管理我们的Python环境:

# 下载MiniConda安装包(Windows版)
# 官网地址:https://docs.conda.io/en/latest/miniconda.html# 创建专用环境
conda create -n opencv_face python=3.8
conda activate opencv_face# 安装基础依赖
pip install numpy pandas opencv-python-headless pillow facenet-pytorch openvino

注意opencv-python-headless是不带GUI功能的OpenCV版本,适合服务器部署。如果需要显示图像,可以安装完整版opencv-python

1.2 项目结构说明

我们的attendance_system目录组织如下:

attendance_system/
├── face_detection/
│   └── models/
│       └── opencv/
│           ├── deploy.prototxt.txt
│           └── res10_300x300_ssd_iter_140000.caffemodel
│   └── detector.py
│   └── recognizer.py
├── data/                  # 存储人脸数据
├── configs/               # 配置文件
├── attendance_report.py   # 考勤报表生成
├── database.py            # 数据库操作
├── main.py                # 主程序入口
├── register_employee.py   # 员工注册
├── reports/               # 出勤记录文件
└── test_face.jpg          # 测试图片

二、核心技术原理

2.1 OpenCV DNN人脸检测

我们使用OpenCV的DNN模块加载Caffe模型进行人脸检测:

人脸检测模型

  • deploy.prototxt
  • res10_300x300_ssd_iter_140000.caffemodel

这个SSD-based模型在300x300输入分辨率下表现优异,准确率高且速度较快。

2.2 FaceNet人脸特征提取

FaceNet是由Google研究团队提出的人脸识别系统,它能将人脸图像映射到128维的特征空间,在这个空间中,相同人的人脸距离近,不同人的人脸距离远。

我们使用facenet-pytorch库提供的预训练模型,它基于InceptionResnetV1架构。

FaceNet模型:

pip install facenet-pytorch

验证安装

python -c "from facenet_pytorch import InceptionResnetV1; print('安装成功!')"
  • 如果显示 安装成功! 说明一切正常

  • 如果报错,请检查网络或尝试镜像源:

    pip install facenet-pytorch -i https://pypi.tuna.tsinghua.edu.cn/simple
    

三、代码实现详解

3.1 人脸检测模块

首先在attendance_system\face_detection目录下创建detector.py

# D:\demo\attendance_system\face_detection\detector.pyimport cv2
import numpy as np
from configs.config import MODEL_PATHS, FACE_DETECTIONclass FaceDetector:def __init__(self):# 加载OpenCV的DNN人脸检测器self.net = cv2.dnn.readNetFromCaffe(MODEL_PATHS["opencv_face_detector"],MODEL_PATHS["opencv_face_weights"])self.confidence_threshold = FACE_DETECTION["confidence_threshold"]self.padding = FACE_DETECTION["padding"]def detect_faces(self, image):(h, w) = image.shape[:2]# 构建blob并输入网络blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300),(104.0, 177.0, 123.0), swapRB=False, crop=False)self.net.setInput(blob)detections = self.net.forward()faces = []for i in range(0, detections.shape[2]):confidence = detections[0, 0, i, 2]if confidence > self.confidence_threshold:box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])(startX, startY, endX, endY) = box.astype("int")# 扩展人脸区域startX = max(0, startX - self.padding)startY = max(0, startY - self.padding)endX = min(w, endX + self.padding)endY = min(h, endY + self.padding)faces.append((startX, startY, endX, endY))return faces

3.2 人脸特征提取模块

attendance_system\face_detection下创建recognizer.py

# D:\demo\attendance_system\face_detection\recognizer.pyimport torch
import numpy as np
from facenet_pytorch import InceptionResnetV1
from PIL import Image
import cv2
from configs.config import MODEL_PATHS, FACE_RECOGNITIONclass FaceRecognizer:def __init__(self):# 加载预训练的FaceNet模型self.resnet = InceptionResnetV1(pretrained='vggface2').eval()self.threshold = FACE_RECOGNITION["threshold"]self.image_size = FACE_RECOGNITION["image_size"]# 尝试使用OpenVINO加速try:from openvino.runtime import Corecore = Core()# 转换为OpenVINO格式ov_model = torch.export(self.resnet, torch.randn(1, 3, self.image_size, self.image_size))compiled_model = core.compile_model(ov_model, 'GPU')  # 使用GPU加速self.resnet = compiled_modelprint("使用OpenVINO GPU加速")except Exception as e:print(f"OpenVINO加速失败,使用原始模型: {e}")def get_embedding(self, face_image):# 转换图像为模型输入格式face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)face = Image.fromarray(face)face = face.resize((self.image_size, self.image_size))face = np.array(face).astype(np.float32)face = (face - 127.5) / 128.0  # FaceNet的标准化face = torch.from_numpy(face).permute(2, 0, 1).unsqueeze(0)# 获取特征向量with torch.no_grad():embedding = self.resnet(face)return embedding.numpy().flatten()def compare_faces(self, embedding1, embedding2):# 计算余弦相似度dot = np.dot(embedding1, embedding2)norm = np.linalg.norm(embedding1) * np.linalg.norm(embedding2)similarity = dot / normreturn similarity > self.threshold

3.3 员工注册功能

register_employee.py的主要内容:

import cv2
import numpy as np
import time
from face_detection.detector import FaceDetector
from face_detection.recognizer import FaceRecognizer
from database import EmployeeDatabase
import winsound  # Windows平台提示音使用def register_employee():detector = FaceDetector()recognizer = FaceRecognizer()db = EmployeeDatabase()# 获取员工信息employee_id = input("请输入员工ID: ")name = input("请输入员工姓名: ")department = input("请输入部门: ")position = input("请输入职位: ")cap = cv2.VideoCapture(0)if not cap.isOpened():print("无法打开摄像头")returnprint("\n========== 员工注册指引 ==========")print("1. 请保持正对摄像头")print("2. 确保光线充足,不要背光")print("3. 保持面部无遮挡(眼镜/口罩需暂时取下)")print("4. 系统将自动捕捉5张不同角度的人脸图像")print("=================================\n")captured_faces = []last_capture_time = 0CHECK_INTERVAL = 0.5CAPTURE_COUNT = 5guidance = ["请正对摄像头","请稍微向左转头","请稍微向右转头","请微微抬头","请微微低头"]while len(captured_faces) < CAPTURE_COUNT:ret, frame = cap.read()if not ret:print("错误: 无法获取视频帧")breakcurrent_time = time.time()status_text = [f"进度: {len(captured_faces)}/{CAPTURE_COUNT}","提示: " + guidance[min(len(captured_faces), 4)]]faces = detector.detect_faces(frame)if len(faces) == 1:(startX, startY, endX, endY) = faces[0]face = frame[startY:endY, startX:endX]cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2)if current_time - last_capture_time > CHECK_INTERVAL:captured_faces.append(face)last_capture_time = current_timeprint(f"✅ 已捕捉人脸 {len(captured_faces)}/{CAPTURE_COUNT} - {status_text[1]}")winsound.Beep(1000, 200)  # 播放提示音for i, text in enumerate(status_text):cv2.putText(frame, text, (10, 30 + i * 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)cv2.imshow("员工注册", frame)if cv2.waitKey(1) & 0xFF == 27:  # ESC 键退出breakcap.release()cv2.destroyAllWindows()if len(captured_faces) >= 3:embeddings = []for face in captured_faces:embedding = recognizer.get_embedding(face)embeddings.append(embedding)avg_embedding = np.mean(embeddings, axis=0)if db.add_employee(name, employee_id, department, position, avg_embedding):print(f"🎉 员工 {name} 注册成功!")else:print("⚠️ 注册失败,可能员工ID已存在")else:print("⚠️ 捕捉的人脸数量不足,注册失败")db.close()if __name__ == "__main__":register_employee()

3.4 出勤记录功能

attendance_report.py的主要内容:

import sqlite3
from datetime import datetime, timedelta
from pathlib import Path
import pandas as pd
from configs.config import DATABASEdef check_dependencies():"""检查并安装必要依赖"""try:import openpyxl, pandasexcept ImportError:import sys, subprocesssubprocess.check_call([sys.executable, "-m", "pip", "install", "openpyxl", "pandas"])def generate_report(days=7, output_dir=None):"""生成考勤报表:param days: 统计最近多少天的数据:param output_dir: 自定义输出目录"""check_dependencies()# 路径处理base_dir = Path(__file__).parentoutput_dir = Path(output_dir) if output_dir else base_dir / "reports"output_dir.mkdir(parents=True, exist_ok=True)# 日期计算end_date = datetime.now()start_date = end_date - timedelta(days=days)filename = f"attendance_{start_date.strftime('%Y%m%d')}_to_{end_date.strftime('%Y%m%d')}.xlsx"report_path = output_dir / filename# 数据库操作try:conn = sqlite3.connect(DATABASE["employees"])query = '''SELECT e.name, e.employee_id, e.department, a.check_time,CASE WHEN time(a.check_time) > '09:30:00' THEN '迟到'WHEN time(a.check_time) < '08:30:00' THEN '早到'ELSE '正常' END as statusFROM attendance aJOIN employees e ON a.employee_id = e.employee_idWHERE date(a.check_time) BETWEEN ? AND ?ORDER BY a.check_time DESC'''df = pd.read_sql_query(query, conn, params=(start_date.date(), end_date.date()))if not df.empty:# 转换日期时间格式df['check_time'] = pd.to_datetime(df['check_time'])df['date'] = df['check_time'].dt.datedf['weekday'] = df['check_time'].dt.day_name()# 创建透视表pivot = df.pivot_table(index=['name', 'employee_id'],columns='date',values='status',aggfunc='first')# 保存文件with pd.ExcelWriter(report_path, engine='openpyxl') as writer:df.to_excel(writer, sheet_name='原始数据', index=False)pivot.to_excel(writer, sheet_name='考勤汇总')print(f"报表已生成: {report_path.resolve()}")return report_pathelse:print("警告: 没有查询到考勤记录")return Noneexcept Exception as e:print(f"生成报表失败: {str(e)}")raisefinally:if 'conn' in locals():conn.close()if __name__ == "__main__":import argparseparser = argparse.ArgumentParser(description='生成考勤报表')parser.add_argument('--days', type=int, default=7, help='统计天数')parser.add_argument('--output', help='自定义输出目录')args = parser.parse_args()generate_report(days=args.days, output_dir=args.output)

3.5 数据库模块

database.py的主要内容:

# D:\demo\attendance_system\database.pyimport sqlite3
import numpy as np
import os
from configs.config import DATABASEclass EmployeeDatabase:def __init__(self):# 确保数据目录存在os.makedirs(os.path.dirname(DATABASE["employees"]), exist_ok=True)# 初始化数据库连接self.conn = sqlite3.connect(DATABASE["employees"])self.cursor = self.conn.cursor()# 创建员工表self.cursor.execute('''CREATE TABLE IF NOT EXISTS employees (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,employee_id TEXT UNIQUE NOT NULL,department TEXT,position TEXT,register_date TEXT DEFAULT CURRENT_TIMESTAMP)''')# 创建打卡记录表self.cursor.execute('''CREATE TABLE IF NOT EXISTS attendance (id INTEGER PRIMARY KEY AUTOINCREMENT,employee_id TEXT NOT NULL,check_time TEXT DEFAULT CURRENT_TIMESTAMP,status TEXT DEFAULT 'present',FOREIGN KEY (employee_id) REFERENCES employees (employee_id))''')self.conn.commit()# 加载人脸特征数据self.load_face_data()def load_face_data(self):# 加载保存的人脸特征和姓名if os.path.exists(DATABASE["embeddings"]):self.embeddings = np.load(DATABASE["embeddings"])self.names = np.load(DATABASE["names"])else:self.embeddings = np.array([])self.names = np.array([])def save_face_data(self):# 保存人脸特征和姓名np.save(DATABASE["embeddings"], self.embeddings)np.save(DATABASE["names"], self.names)def add_employee(self, name, employee_id, department, position, embedding):# 添加新员工try:self.cursor.execute('''INSERT INTO employees (name, employee_id, department, position)VALUES (?, ?, ?, ?)''', (name, employee_id, department, position))# 更新人脸特征数据if len(self.embeddings) == 0:self.embeddings = np.array([embedding])else:self.embeddings = np.vstack((self.embeddings, embedding))self.names = np.append(self.names, employee_id)self.save_face_data()self.conn.commit()return Trueexcept sqlite3.IntegrityError:return Falsedef record_attendance(self, employee_id, status='present'):# 记录考勤self.cursor.execute('''INSERT INTO attendance (employee_id, status)VALUES (?, ?)''', (employee_id, status))self.conn.commit()def get_employee_info(self, employee_id):# 获取员工信息self.cursor.execute('''SELECT name, department, position FROM employees WHERE employee_id = ?''', (employee_id,))return self.cursor.fetchone()def close(self):# 关闭数据库连接self.conn.close()

3.6 考勤识别主程序

main.py的主要内容:

# D:\demo\attendance_system\main.pyimport cv2
import numpy as np
from face_detection.detector import FaceDetector
from face_detection.recognizer import FaceRecognizer
from database import EmployeeDatabase
from configs.config import DATABASE
import os
import time
import datetimedef main():# 初始化组件detector = FaceDetector()recognizer = FaceRecognizer()db = EmployeeDatabase()# 创建数据目录os.makedirs(os.path.dirname(DATABASE["employees"]), exist_ok=True)# 初始化摄像头cap = cv2.VideoCapture(0)if not cap.isOpened():print("无法打开摄像头")returnprint("人脸识别考勤系统已启动,按'q'键退出")last_recognition_time = 0recognized_employees = set()while True:ret, frame = cap.read()if not ret:print("无法获取视频帧")break# 检测人脸faces = detector.detect_faces(frame)# 在帧上绘制人脸框for (startX, startY, endX, endY) in faces:cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2)# 提取人脸区域face = frame[startY:endY, startX:endX]# 每隔1秒尝试识别一次current_time = time.time()if current_time - last_recognition_time > 1.0:try:# 获取人脸特征embedding = recognizer.get_embedding(face)# 与数据库中的特征比较if len(db.embeddings) > 0:similarities = np.array([recognizer.compare_faces(embedding, db_emb)for db_emb in db.embeddings])if np.any(similarities):matched_idx = np.argmax(similarities)employee_id = db.names[matched_idx]# 如果之前未识别过,则记录考勤if employee_id not in recognized_employees:name, department, position = db.get_employee_info(employee_id)current_time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")print(f"{current_time_str} - 识别到员工: {name}, 部门: {department}, 职位: {position}")# 记录考勤db.record_attendance(employee_id)recognized_employees.add(employee_id)# 在图像上显示员工信息cv2.putText(frame, f"ID: {employee_id}", (startX, startY - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)cv2.putText(frame, f"Name: {name}", (startX, startY - 30),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)last_recognition_time = current_timeexcept Exception as e:print(f"人脸识别错误: {e}")# 显示结果cv2.imshow("Face Recognition Attendance System", frame)# 按'q'键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 清理资源cap.release()cv2.destroyAllWindows()db.close()if __name__ == "__main__":main()

四、性能优化技巧

4.1 使用OpenVINO加速

我们可以将模型转换为OpenVINO格式以获得更好的性能:

from openvino.inference_engine import IECoreclass OpenVINOFaceDetector:def __init__(self, model_xml, model_bin, device='CPU'):self.ie = IECore()self.net = self.ie.read_network(model=model_xml, weights=model_bin)self.exec_net = self.ie.load_network(network=self.net, device_name=device)self.input_blob = next(iter(self.net.input_info))self.out_blob = next(iter(self.net.outputs))def detect_faces(self, image):# 与之前类似的预处理blob = cv2.dnn.blobFromImage(...)# 使用OpenVINO推理res = self.exec_net.infer(inputs={self.input_blob: blob})detections = res[self.out_blob]# 后处理相同...

4.2 多线程处理

对于实时视频流,可以使用多线程来提高性能:

from threading import Thread
import queueclass VideoStream:def __init__(self, src=0):self.stream = cv2.VideoCapture(src)self.stopped = Falseself.frames = queue.Queue(maxsize=128)def start(self):Thread(target=self.update, args=()).start()return selfdef update(self):while not self.stopped:if not self.frames.full():ret, frame = self.stream.read()if not ret:self.stop()returnself.frames.put(frame)def read(self):return self.frames.get()def stop(self):self.stopped = True

五、部署运行

5.1 启动系统

conda activate opencv_face

在这里插入图片描述

5.2 初始化数据库

(opencv_face) D:\demo\attendance_system>python database.py init

5.3 注册新员工

(opencv_face) D:\demo\attendance_system>python register_employee.py
Q:退出系统

在这里插入图片描述

5.4 调用主程序

(opencv_face) D:\demo\attendance_system>python main.py

在这里插入图片描述

5.5 生成考勤报表

(opencv_face) D:\demo\attendance_system>python attendance_report.py
报表已生成: D:\demo\attendance_system\reports\attendance_20250707_to_20250714.xlsx

在这里插入图片描述

在这里插入图片描述

通过这个项目,我们学习了如何将深度学习模型应用到实际场景中,构建一个完整的人脸识别系统。这个系统可以进一步扩展为门禁系统、会员识别等多种应用。

如果你在实现过程中遇到任何问题,欢迎在评论区留言讨论!

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

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

相关文章

【AI News | 20250714】每日AI进展

AI Repos 1、All-Model-Chat All Model Chat 是一款为Google Gemini API家族设计的网页聊天应用&#xff0c;支持多模态输入&#xff08;图片、音频、PDF等&#xff09;和多种模型&#xff08;如Gemini Flash、Imagen&#xff09;。它提供了丰富的自定义功能&#xff0c;包括高…

C 语言(二)

主要包括变量与常量、数据类型、存储方式、数制转换以及字符处理等内容一、变量与常量在 C 语言中&#xff0c;变量是用来存储数据的命名空间&#xff0c;它会在内存中分配地址。例如&#xff1a;int i; i 12345; 其中 i 是变量&#xff0c;12345 是常量。常量表示在程序运行过…

原型继承(prototypal inheritance)的工作原理

这是一个非常常见的 JavaScript 问题。所有 JS 对象都有一个__proto__属性&#xff0c;指向它的原型对象。当试图访问一个对象的属性时&#xff0c;如果没有在该对象上找到&#xff0c;它还会搜寻该对象的原型&#xff0c;以及该对象的原型的原型&#xff0c;依次层层向上搜索&…

OpenCV 视频处理与摄像头操作详解

1. 引言大家都来写OpenCV&#x1f60a;&#xff0c;学的好开心&#xff01;2. 视频基础与OpenCV简介2.1 视频的定义视频&#xff08;Video&#xff09;是由一系列静态图像&#xff08;帧&#xff09;以一定速率连续播放形成的动态影像。其本质是利用人眼的视觉暂留效应&#xf…

Agentic AI 的威胁与缓解措施

原文&#xff1a;https://www.aigl.blog/content/files/2025/04/Agentic-AI—Threats-and-Mitigations.pdf AI Agent 的定义 1. 定义与基础 智能代理&#xff08;Agent&#xff09;的定义&#xff1a; 智能代理是一种能够感知环境、进行推理、做出决策并自主采取行动以实现特定…

ArrayList列表解析

ArrayList集合 ArrayList 的底层是数组队列&#xff0c;相当于动态数组。与 Java 中的数组相比&#xff0c;它的容量能动态增长。在添加大量元素前&#xff0c;应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayList 继承…

《恋与深空》中龙和蛇分别是谁的代表

在《恋与深空》宏大而神秘的世界观中&#xff0c;每一个符号都蕴含着深意。当玩家们热议“龙”和“蛇”这两种强大而古老的生物究竟代表着谁时&#xff0c;所有的线索都默契地指向了同一个名字——秦彻。 他不仅是力量与权威的象征“恶龙”&#xff0c;也是背负着宿命与纠葛的“…

gitignore添加后如何生效?

清除 Git 缓存&#xff1a; git rm -r --cached .添加文件到 Git&#xff1a;git add .使用 git commit 命令提交这些更改git commit -m "Update .gitignore"

多尺度频率辅助类 Mamba 线性注意力模块(MFM),融合频域和空域特征,提升多尺度、复杂场景下的目标检测能力

在伪装物体检测领域&#xff0c;现有方法大多依赖空间局部特征&#xff0c;难以有效捕捉全局信息&#xff0c;而 Transformer 类方法虽能建模长距离依赖关系&#xff0c;却存在计算成本高、网络结构复杂的问题。同时&#xff0c;频域特征虽具备全局建模能力&#xff0c;可频繁的…

Dify的默认端口怎么修改

1.定位配置文件 在 Dify 的安装目录中找到 .env 文件&#xff08;通常位于 docker/ 子目录下&#xff09;。此文件定义了 Docker 容器的环境变量&#xff0c;包括端口配置。 2.调整端口参数 修改以下两个关键配置项&#xff1a; # Docker 容器内部 Nginx 监听的端口&#xf…

Go内存分配

图解Go语言内存分配 - 知乎 go内置运行时&#xff0c;采用了自主管理&#xff0c;实现更好的内存使用模式&#xff0c;不需要每次内存分配都进行系统调用 采用TCMalloc算法&#xff1a;把内存分为多级管理&#xff0c;从而降低锁的粒度 将可用的堆内存采用二级分配的方式进行…

cursor使用mcp连接mysql数据库,url方式

背景。 用cursor生成后端代码。让cursor可以创建响应的表结构以及插入数据。使用的cursor版本是1.2.1 cursor 官网 mcp 说明smithery 中mysql mcp这个mcp具有建表的本领。 在cursor中是这样配置的。 以上这种配置方式是是通过在smithery 网站中配置好自己的mysql数据库连接后才…

Twisted study notes[1]

文章目录serverreferencesserver Twisted usually using subclass twisted.internet.protocol.Protocol to treat protocols .Protocol is a fundamental class in Twisted for implementing network protocols.protocol class instant don’t exists forever because of it w…

Python 数据建模与分析项目实战预备 Day 6 - 多模型对比与交叉验证验证策略

✅ 今日目标 引入多种常见分类模型&#xff08;随机森林、支持向量机、K近邻等&#xff09;比较不同模型的训练效果使用交叉验证提升评估稳定性&#x1f9fe; 一、对比模型列表模型类名&#xff08;sklearn&#xff09;适用说明逻辑回归LogisticRegression基础线、易于解释KNNK…

xss-labs 1-8关

level1打开检查&#xff0c;发现test直接放入h2标签中此时通过script绕过h2标签构造payload127.0.0.1/xss-labs/lvel1.php?name<script>alert(111)</script>直接使用script标签绕过h2,并执行alert,通过level2打开检查&#xff0c;输入的123被放在input标签里面的v…

Conda 核心命令快速查阅表

本表旨在提供一个简洁、高效的 Conda 命令参考&#xff0c;专注于最常用功能的快速查找。 1. 环境管理 (Environment Management)功能 (Function)命令 (Command)示例 (Example)创建新环境conda create -n <env_name> [packages...]conda create -n myenv python3.9 panda…

音视频学习(三十九):IDR帧和I帧

主要区分&#xff1a;I 帧 是帧内编码帧&#xff0c;IDR 帧 是一种特殊的 I 帧&#xff0c;它是“清除参考帧链的强制切断点”。H.264 视频结构 结构 H.264 视频由多个 NAL&#xff08;Network Abstraction Layer&#xff09;单元 构成&#xff0c;每一帧图像可由一个或多个 NA…

人工智能与机器学习暑期科研项目招募(可发表论文)

人工智能与机器学习暑期科研项目招募 华中科技大学博士论文指导我是计算机专业的研二学生&#xff1a;从大二开始接触科研&#xff0c;至今已发表1篇CCF-A类会议论文、1篇CCF-B类会议论文&#xff0c;以及2篇Top期刊论文。正是这段从本科开始的科研经历&#xff0c;让我在保研和…

C盘爆满?一键清理恢复极速体验!“小番茄C盘清理”彻底解放你的电脑

目录 前言 C盘变红&#xff1f;&#xff01;那么你的电脑将会出现下面糟糕的情况&#xff1a; 一、小番茄C盘清理介绍——拯救你的C盘爆红&#xff01; 二、安装登录小番茄C盘清理 2.1 安装小番茄C盘清理 2.2 登录—拥有专属自己电脑的小番茄C盘清理 三、手把手教你深度…

UI前端大数据可视化实战技巧:如何利用数据故事化提升用户参与度?

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;从 “图表堆砌” 到 “故事共鸣” 的可视化革命当企业管理者面对布满折线…