✨作者主页 :IT研究室✨
个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。
☑文末获取源码☑
文章目录
一、前言
系统介绍
本系统名为《基于深度学习的面部关键特征识别与检测》,面向计算机专业本科毕业设计场景,围绕面部关键特征的自动识别与检测需求展开设计与实现。系统采用深度学习技术路线,以卷积神经网络作为核心模型结构,依托PyTorch完成模型的构建、训练与推理,借助OpenCV完成图像与视频流的读取、预处理及人脸区域定位,后端采用Django框架组织业务逻辑与接口服务。功能层面涵盖首页、用户管理、识别检测、图片识别、视频识别、摄像头识别、历史管理与统计大屏八个模块,用户登录后可通过图片上传、视频文件导入、摄像头实时采集三种方式发起识别任务,系统对输入画面进行人脸检测与关键特征点定位,输出特征坐标与检测结果,并将每次识别记录写入历史管理模块,统计大屏则对识别次数、识别方式分布、识别成功率等指标进行汇总展示,形成从数据输入、模型推理、结果呈现到记录追溯的完整业务闭环,为面部关键特征识别相关课题的研究与演示提供了一套结构清晰、功能完整的实现方案。
选题背景
人脸作为人体最具辨识度的生物特征载体,长期以来都是计算机视觉领域的重要研究对象。从早期基于几何特征与模板匹配的方法,到后来基于统计学习的人脸检测思路,再到如今深度神经网络在大规模数据支撑下展现出更强的特征表达能力,面部关键特征的识别与检测技术已经走过了一条不断迭代的道路。在实际生活中,人脸检测与关键点定位是许多上层应用的基础环节,刷脸支付、门禁通行、照片美颜、疲劳驾驶监测等场景背后都离不开对五官位置的准确判断。不过,对于刚接触这一方向的本科生来说,理论教材往往偏重公式推导,开源项目又常常工程化程度较高,中间缺少一个既能体现深度学习核心流程、又具备完整业务功能的过渡性案例。本课题正是在这样的情况下提出的,希望把卷积神经网络、图像预处理、人脸检测与关键点回归这些知识点落到一个具体可运行的系统里,让抽象的概念有可操作的载体。
选题意义
从学习角度看,本课题把深度学习中模型构建、数据预处理、训练推理这几块内容串成了一条线,做下来能对卷积神经网络的工作方式有更直观的认识,而不只是停留在看懂公式的层面。从工程实践角度看,系统把图片、视频、摄像头三种输入方式统一到同一套识别流程中,再配合历史记录与统计展示,涉及前后端交互、数据存储、结果可视化等多个环节,对综合运用所学知识有一定帮助。从应用参考角度看,面部关键特征识别本身是很多人脸相关应用的前置步骤,本系统虽然规模有限、模型精度也谈不上多高,但流程相对完整,可以为后续想在此基础上做表情识别、疲劳检测等方向的同学提供一个可以改动的起点。当然,受个人能力和时间所限,系统在模型选型、识别精度和并发处理上都还有明显不足,更多是作为一个教学性质的实践案例存在,谈不上什么实际产品价值,只是希望能在毕设这个阶段把学到的东西认真走一遍。
二、系统界面展示
- 基于深度学习的面部关键特征识别与检测界面展示:








三、代码参考
- 项目实战代码参考:
java(贴上部分代码)
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("FaceKeyFeatureRecognition").master("local[*]").getOrCreate()
import os, cv2, torch, numpy as np
from datetime import datetime
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import RecognizeHistory, UserInfo
from .face_model import FaceKeyPointNet
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = FaceKeyPointNet().to(device)
model.load_state_dict(torch.load("weights/face_keypoint.pth", map_location=device))
model.eval()
def preprocess_face(image_bgr):
gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60))
if len(faces) == 0:
return None, None
x, y, w, h = max(faces, key=lambda r: r[2] * r[3])
roi = image_bgr[y:y + h, x:x + w]
roi = cv2.resize(roi, (112, 112))
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
tensor = torch.from_numpy(roi).float().permute(2, 0, 1).unsqueeze(0) / 255.0
mean = torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1)
std = torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1)
tensor = (tensor - mean) / std
return tensor.to(device), (x, y, w, h)
@csrf_exempt
def recognize_image(request):
if request.method != "POST":
return JsonResponse({"code": 400, "msg": "请求方式错误"})
user_id = request.POST.get("user_id")
upload_file = request.FILES.get("image")
if not upload_file or not user_id:
return JsonResponse({"code": 401, "msg": "参数缺失"})
user = UserInfo.objects.filter(id=user_id).first()
if user is None:
return JsonResponse({"code": 402, "msg": "用户不存在"})
file_bytes = np.frombuffer(upload_file.read(), np.uint8)
image_bgr = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
if image_bgr is None:
return JsonResponse({"code": 403, "msg": "图片解析失败"})
tensor, box = preprocess_face(image_bgr)
if tensor is None:
return JsonResponse({"code": 404, "msg": "未检测到人脸区域"})
with torch.no_grad():
output = model(tensor).cpu().numpy().reshape(-1, 2)
x, y, w, h = box
key_points = []
for px, py in output:
abs_x = int(x + px * w)
abs_y = int(y + py * h)
key_points.append({"x": abs_x, "y": abs_y})
cv2.circle(image_bgr, (abs_x, abs_y), 2, (0, 255, 0), -1)
save_name = "result_" + datetime.now().strftime("%Y%m%d%H%M%S") + ".jpg"
save_path = os.path.join("media/results", save_name)
cv2.imwrite(save_path, image_bgr)
history = RecognizeHistory.objects.create(
user=user, recog_type="image", source_name=upload_file.name,
result_path="results/" + save_name, point_count=len(key_points),
status="success", create_time=datetime.now())
spark.createDataFrame([(history.id, user.id, "image", len(key_points), 1)],
["history_id", "user_id", "recog_type", "point_count", "success_flag"]).write.mode("append").format("parquet").save("data/recog_log")
return JsonResponse({"code": 200, "msg": "识别成功", "points": key_points, "result": "results/" + save_name})
@csrf_exempt
def recognize_video(request):
if request.method != "POST":
return JsonResponse({"code": 400, "msg": "请求方式错误"})
user_id = request.POST.get("user_id")
upload_file = request.FILES.get("video")
if not upload_file or not user_id:
return JsonResponse({"code": 401, "msg": "参数缺失"})
user = UserInfo.objects.filter(id=user_id).first()
if user is None:
return JsonResponse({"code": 402, "msg": "用户不存在"})
tmp_path = os.path.join("media/tmp", upload_file.name)
with open(tmp_path, "wb") as f:
for chunk in upload_file.chunks():
f.write(chunk)
cap = cv2.VideoCapture(tmp_path)
if not cap.isOpened():
return JsonResponse({"code": 403, "msg": "视频打开失败"})
frame_total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
frame_index = 0
detect_frames = 0
total_points = 0
result_frames = []
while True:
ret, frame = cap.read()
if not ret:
break
frame_index += 1
if frame_index % 5 != 0:
continue
tensor, box = preprocess_face(frame)
if tensor is None:
continue
with torch.no_grad():
output = model(tensor).cpu().numpy().reshape(-1, 2)
detect_frames += 1
total_points += output.shape[0]
if len(result_frames) < 3:
result_frames.append(frame_index)
cap.release()
os.remove(tmp_path)
if detect_frames == 0:
return JsonResponse({"code": 404, "msg": "视频中未检测到有效人脸"})
history = RecognizeHistory.objects.create(
user=user, recog_type="video", source_name=upload_file.name,
result_path="", point_count=total_points, status="success",
create_time=datetime.now())
spark.createDataFrame([(history.id, user.id, "video", total_points, detect_frames, frame_total)],
["history_id", "user_id", "recog_type", "point_count", "detect_frames", "frame_total"]).write.mode("append").format("parquet").save("data/recog_log")
return JsonResponse({"code": 200, "msg": "视频识别完成", "detect_frames": detect_frames,
"total_frames": frame_total, "total_points": total_points})
@csrf_exempt
def recognize_camera(request):
if request.method != "POST":
return JsonResponse({"code": 400, "msg": "请求方式错误"})
user_id = request.POST.get("user_id")
if not user_id:
return JsonResponse({"code": 401, "msg": "参数缺失"})
user = UserInfo.objects.filter(id=user_id).first()
if user is None:
return JsonResponse({"code": 402, "msg": "用户不存在"})
cap = cv2.VideoCapture(0)
if not cap.isOpened():
return JsonResponse({"code": 403, "msg": "摄像头不可用"})
detect_count = 0
point_total = 0
for _ in range(30):
ret, frame = cap.read()
if not ret:
continue
tensor, box = preprocess_face(frame)
if tensor is None:
continue
with torch.no_grad():
output = model(tensor).cpu().numpy().reshape(-1, 2)
detect_count += 1
point_total += output.shape[0]
cap.release()
if detect_count == 0:
return JsonResponse({"code": 404, "msg": "摄像头画面中未检测到人脸"})
history = RecognizeHistory.objects.create(
user=user, recog_type="camera", source_name="camera_0",
result_path="", point_count=point_total, status="success",
create_time=datetime.now())
spark.createDataFrame([(history.id, user.id, "camera", point_total, detect_count)],
["history_id", "user_id", "recog_type", "point_count", "detect_count"]).write.mode("append").format("parquet").save("data/recog_log")
return JsonResponse({"code": 200, "msg": "摄像头识别完成", "detect_count": detect_count, "total_points": point_total})
四、系统视频
基于深度学习的面部关键特征识别与检测项目视频:
结语
最新计算机毕业设计选题推荐-基于深度学习的面部关键特征识别与检测-运行部署-文档指导-深度学习-YOLO
想看其他类型的计算机毕业设计作品也可以和我说都有 谢谢大家!
有技术这一块问题大家可以评论区交流或者私我~
大家可以帮忙点赞、收藏、关注、评论啦~
源码获取:⬇⬇⬇