服务机器人访客视觉感知与人体特征分析系统开发
人体、人脸视觉感知是接待导购、陪护服务机器人的核心业务能力,属于服务机器人应用技术员核心考核技能;岗位工作包含机器人视觉相机标定部署人体/人脸目标检测、访客距离测算、访客身份特征识别、访客图像信息归档等开发调试内容,支撑机器人主动迎宾、分人群差异化服务、访客到访记录留存等商用服务场景。本任务依托服务机器人云台视觉相机,开发访客人体感知与性别识别分析程序,完成商用机器人视觉交互全流程功能开发。
任务三:机器人访客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()

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐