服务机器人访客视觉感知与人体特征分析系统开发
服务机器人访客视觉感知与人体特征分析系统开发
人体、人脸视觉感知是接待导购、陪护服务机器人的核心业务能力,属于服务机器人应用技术员核心考核技能;岗位工作包含机器人视觉相机标定部署人体/人脸目标检测、访客距离测算、访客身份特征识别、访客图像信息归档等开发调试内容,支撑机器人主动迎宾、分人群差异化服务、访客到访记录留存等商用服务场景。本任务依托服务机器人云台视觉相机,开发访客人体感知与性别识别分析程序,完成商用机器人视觉交互全流程功能开发。
任务三:机器人访客AI视觉感知处理系统开发
创建名为03.py的文件,编写程序实现“AI视觉性别识别与人体分析系统”功能,并将文件存储至任务一第1条构建的文件夹中,具体功能要求如
1.调用人工智能试验箱外接摄像头,在窗口内显示实时画面。
2.同时识别人脸和人体轮廓:人脸用黄色(BGR值:0,255,255)矩形框标记,人体轮廓用蓝色(BGR值:255,0,0)多边形(基于轮廓点连接)标记。
3.实时计算人脸与摄像头的距离:基于人脸像素宽度估算,假设人脸实际宽度为15cm,当人脸在图像中占据100像素时,距离为100cm,每增加10像素距离减少10cm(公式:距离=(100*15)/人脸像素宽度),在窗口左上角显示“Face Distance:XXcm”(XX为计算出的距离值,保留1位小数)。
4.性别识别:基于预训练Caffe模型识别人脸性别(Male/Female),在人脸矩形框下方显示性别结果(字体大小20,颜色绿色(BGR:0,255,0))。
5.数据留存:按下“q”键退出程序时,自动保存检测到的所有人脸截图(截图仅包含人脸区域,命名格式:face_时间.jpg,如face_20250520143000.jpg)到face_captures 子文件夹(需自动创建,与03.py同目录)。
程序如下:
导入必要的库
from exboard import RGB # 试验箱RGB灯环控制库
import cv2 # OpenCV计算机视觉库
import numpy as np # 数值计算库
import os # 文件系统操作
import time # 时间处理
from datetime import datetime # 日期时间处理
====================== 1. 初始化配置 ======================
摄像头设备ID(根据实际连接情况调整)
CAMERA_ID = 2
人脸实际宽度(cm)
KNOWN_FACE_WIDTH = 15.0
参考距离100cm时的人脸像素宽度
REFERENCE_PIXEL_WIDTH = 100
计算参考焦距(基于用户提供的公式推导)
FOCAL_LENGTH = (REFERENCE_PIXEL_WIDTH * 100) / KNOWN_FACE_WIDTH
颜色定义(BGR格式,OpenCV默认使用BGR)
YELLOW = (0, 255, 255) # 人脸框颜色
BLUE = (255, 0, 0) # 人体轮廓颜色
GREEN = (0, 255, 0) # 性别文字颜色
性别识别模型配置(Caffe预训练模型)
GENDER_MODEL = “gender_net.caffemodel”
GENDER_PROTO = “gender_deploy.prototxt”
GENDER_LABELS = [‘Male’, ‘Female’]
模型输入参数
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
INPUT_SIZE = (227, 227)
初始化RGB灯环(试验箱硬件)
rgb = RGB()
初始关闭所有灯珠
rgb.set([(0, 0, 0)] * 24)
====================== 2. 加载模型与初始化 ======================
def init_system():
“”“系统初始化:加载模型、创建文件夹、初始化摄像头”“”
# 1. 自动创建人脸截图保存目录
if not os.path.exists(“face_captures”):
os.makedirs(“face_captures”)
print(“创建人脸截图目录: face_captures”)
# 2. 加载人脸检测器(Haar级联分类器)
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
if face_cascade.empty():
raise Exception("无法加载人脸检测器,请确保haarcascade_frontalface_default.xml文件存在")
# 3. 加载性别识别Caffe模型
gender_net = cv2.dnn.readNetFromCaffe(GENDER_PROTO, GENDER_MODEL)
if gender_net.empty():
raise Exception("无法加载性别识别模型,请确保gender_net.caffemodel和gender_deploy.prototxt文件存在")
# 4. 初始化摄像头
cap = cv2.VideoCapture(CAMERA_ID)
if not cap.isOpened():
raise Exception(f"无法打开摄像头(ID: {CAMERA_ID}),请检查设备连接")
# 设置摄像头分辨率(可选,根据实际情况调整)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
return face_cascade, gender_net, cap
====================== 3. 核心功能函数 ======================
def calculate_face_distance(face_width):
“”"
计算人脸与摄像头的距离
公式:距离 = (实际宽度 × 参考焦距) / 人脸像素宽度
“”"
if face_width <= 0:
return 0.0
distance = (KNOWN_FACE_WIDTH * FOCAL_LENGTH) / face_width
return round(distance, 1) # 保留1位小数
def detect_human_contour(frame):
“”“检测人体轮廓:基于背景减除和轮廓分析”“”
# 转换为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# 二值化(自适应阈值)
_, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 形态学操作:去除噪点
kernel = np.ones((3, 3), np.uint8)
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
# 查找轮廓
contours, _ = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 筛选人体轮廓(基于面积大小)
human_contours = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 2000: # 过滤小轮廓(可根据实际情况调整)
human_contours.append(cnt)
return human_contours
def predict_gender(net, face_roi):
“”“基于Caffe模型预测人脸性别”“”
# 预处理:调整大小、归一化、创建blob
blob = cv2.dnn.blobFromImage(
face_roi, 1.0, INPUT_SIZE,
MODEL_MEAN_VALUES, swapRB=False
)
# 输入模型并前向传播
net.setInput(blob)
predictions = net.forward()
# 获取性别结果
gender_idx = np.argmax(predictions[0])
gender = GENDER_LABELS[gender_idx]
confidence = predictions[0][gender_idx]
return gender, confidence
def save_face_snapshot(face_roi, timestamp):
“”“保存人脸截图到face_captures文件夹”“”
# 生成文件名:face_时间戳.jpg
filename = f"face_captures/face_{timestamp}.jpg"
# 保存图像
cv2.imwrite(filename, face_roi)
print(f"保存人脸截图: {filename}")
====================== 4. 主程序 ======================
def main():
try:
# 系统初始化
face_cascade, gender_net, cap = init_system()
print(“系统初始化完成,开始运行…”)
# 存储检测到的人脸(用于退出时保存)
detected_faces = []
while True:
# 读取摄像头帧
ret, frame = cap.read()
if not ret:
print("无法读取摄像头画面,跳过帧")
time.sleep(0.1)
continue
# 复制原始帧用于显示
display_frame = frame.copy()
# ====================== 任务2:识别人脸和人体轮廓 ======================
# 1. 人脸检测
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.3,
minNeighbors=5,
minSize=(30, 30)
)
# 存储当前帧检测到的人脸ROI
current_faces = []
# 处理每个人脸
for (x, y, w, h) in faces:
# 绘制黄色人脸矩形框
cv2.rectangle(display_frame, (x, y), (x+w, y+h), YELLOW, 2)
# ====================== 任务3:计算人脸距离 ======================
face_distance = calculate_face_distance(w)
# 在窗口左上角显示距离
cv2.putText(
display_frame,
f"Face Distance: {face_distance} cm",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
YELLOW,
2
)
# ====================== 任务4:性别识别 ======================
# 提取人脸ROI
face_roi = frame[y:y+h, x:x+w]
current_faces.append(face_roi) # 保存人脸ROI
# 性别预测
gender, confidence = predict_gender(gender_net, face_roi)
# 在人脸框下方显示性别结果
cv2.putText(
display_frame,
f"{gender} ({confidence:.2f})",
(x, y+h+30),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
GREEN,
2
)
# 2. 人体轮廓检测
human_contours = detect_human_contour(frame)
# 绘制蓝色多边形轮廓
cv2.drawContours(display_frame, human_contours, -1, BLUE, 2)
# 更新检测到的人脸列表(去重)
detected_faces.extend(current_faces)
# 显示实时画面
cv2.imshow("AI Test Box - Face & Human Detection", display_frame)
# 控制灯环:检测到人脸时亮绿灯,否则熄灭
if len(faces) > 0:
rgb.set([(0, 255, 0)] * 24) # 绿灯常亮
else:
rgb.set([(0, 0, 0)] * 24) # 关闭灯环
# 按键处理
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
# ====================== 任务5:数据留存 ======================
print("接收到退出指令,保存人脸截图...")
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
# 保存所有检测到的人脸
for i, face in enumerate(detected_faces):
if face.size > 0: # 确保人脸有效
save_face_snapshot(face, f"{timestamp}_{i}")
print("退出程序,感谢使用!")
break
except Exception as e:
print(f"程序运行出错: {str(e)}")
finally:
# 资源释放
if 'cap' in locals() and cap.isOpened():
cap.release()
cv2.destroyAllWindows()
rgb.set([(0, 0, 0)] * 24) # 关闭灯环
程序入口
if name == “main”:
main()
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)