ROS人脸检测

发布于:2025-08-29 ⋅ 阅读:(13) ⋅ 点赞:(0)

在这里插入图片描述

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>

using namespace cv;

static CascadeClassifier face_cascade;

static Mat frame_gray;
static std::vector<Rect> faces;
static std::vector<cv::Rect>::const_iterator face_iter;

void callbackRGB(const sensor_msgs::Image msg)
{
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
        cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
        ROS_ERROR("cv_bridge exception: %s", e.what());
        return;
    }

    Mat imgOriginal = cv_ptr->image;

    // 转换成黑白图像
    cvtColor( imgOriginal, frame_gray, CV_BGR2GRAY );
	equalizeHist( frame_gray, frame_gray );

    // 检测人脸
	face_cascade.detectMultiScale( frame_gray, faces, 1.1, 9, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

    // 在彩色原图中标注人脸位置
    if(faces.size() > 0)
    {
        std::vector<cv::Rect>::const_iterator i;
        for (face_iter = faces.begin(); face_iter != faces.end(); ++face_iter) 
        {
            cv::rectangle(
                imgOriginal,
                cv::Point(face_iter->x , face_iter->y),
                cv::Point(face_iter->x + face_iter->width, face_iter->y + face_iter->height),
                CV_RGB(255, 0 , 255),
                2);
        }
    }
    imshow("faces", imgOriginal);
    waitKey(1);
}


int main(int argc, char **argv)
{
    cv::namedWindow("faces");
    ros::init(argc, argv, "demo_cv_face_detect");

    ROS_INFO("demo_cv_face_detect");

    std::string strLoadFile;
    char const* home = getenv("HOME");
    strLoadFile = home;
    strLoadFile += "/catkin_ws";
    strLoadFile += "/src/wpr_simulation/config/haarcascade_frontalface_alt.xml";

    bool res = face_cascade.load(strLoadFile);
	if (res == false)
	{
		ROS_ERROR("fail to load haarcascade_frontalface_alt.xml");
        return 0;
	}
    ros::NodeHandle nh;
    //ros::Subscriber rgb_sub = nh.subscribe("/kinect2/qhd/image_color_rect", 1 , callbackRGB);
    //此处修改为usb摄像头的topic,使用自己电脑进行人脸识别。
    ros::Subscriber rgb_sub = nh.subscribe("/usb_cam/image_raw", 1 , callbackRGB);
    ros::spin();
    return 0;
}


代码功能解读

这段代码是一个基于ROS(机器人操作系统)和OpenCV的人脸检测节点,主要功能如下:

  1. 整体功能:订阅ROS环境中的彩色图像话题,对图像进行人脸检测,在检测到的人脸周围绘制紫色矩形框,并实时显示处理后的图像。

  2. 核心组件解析

    • 头文件:包含ROS相关库(ros/ros.h)、ROS与OpenCV图像转换库(cv_bridge/cv_bridge.h)、OpenCV图像处理库(opencv2/*)等,实现ROS与OpenCV的协同工作。
    • 全局变量face_cascade(Haar级联分类器,用于人脸检测)、frame_gray(灰度图像,人脸检测的输入格式)、faces(存储检测到的人脸区域)。
    • 回调函数callbackRGB
      • 通过cv_bridge将ROS图像消息(sensor_msgs::Image)转换为OpenCV的Mat格式图像。
      • 将彩色图像转为灰度图并进行直方图均衡化(提升检测精度)。
      • 使用detectMultiScale方法检测人脸,返回人脸区域的矩形坐标。
      • 在原始彩色图像上用紫色矩形框标记人脸,并通过imshow显示。
    • 主函数main
      • 初始化ROS节点(节点名demo_cv_face_detect)。
      • 加载人脸检测模型(haarcascade_frontalface_alt.xml,Haar特征分类器模型文件)。
      • 创建ROS订阅者,订阅Kinect2的彩色图像话题(/kinect2/qhd/image_color_rect),并绑定回调函数。
      • 启动ROS消息循环(ros::spin()),持续接收并处理图像。

如何修改代码以使用电脑摄像头

原代码默认订阅Kinect2的图像话题,若要使用电脑摄像头,需通过ROS的usb_cam包获取摄像头图像并修改订阅话题,步骤如下:

步骤1:安装usb_cam包(获取电脑摄像头图像)

usb_cam是ROS中用于读取USB摄像头图像并发布为ROS话题的功能包,执行以下命令安装:

sudo apt-get install ros-<你的ROS版本>-usb-cam
# 例如ROS Noetic:sudo apt-get install ros-noetic-usb-cam
步骤2:修改代码中的订阅话题

原代码订阅的是Kinect2的话题,需改为usb_cam发布的电脑摄像头话题。
找到main函数中的订阅者创建代码:

ros::Subscriber rgb_sub = nh.subscribe("/kinect2/qhd/image_color_rect", 1 , callbackRGB);

修改为usb_cam的默认图像话题(通常为/usb_cam/image_raw):

ros::Subscriber rgb_sub = nh.subscribe("/usb_cam/image_raw", 1 , callbackRGB);
步骤3:确认人脸检测模型路径

原代码中模型路径为:

strLoadFile = home;
strLoadFile += "/catkin_ws/src/wpr_simulation/config/haarcascade_frontalface_alt.xml";
  • 若你的电脑中存在该路径和文件,可直接使用;
  • 若不存在,需自行下载haarcascade_frontalface_alt.xml(OpenCV官方提供的人脸检测模型),并修改路径为你的文件实际位置,例如:
    strLoadFile = "/home/你的用户名/opencv_models/haarcascade_frontalface_alt.xml";
    
步骤4:编译代码

将修改后的代码放入你的ROS工作空间(如catkin_ws/src)的功能包中,编译工作空间:

cd ~/catkin_ws
catkin_make
source devel/setup.bash
步骤5:运行程序
  1. 启动ROS核心:

    roscore
    
  2. 启动usb_cam节点(打开电脑摄像头并发布图像话题):

    rosrun usb_cam usb_cam_node
    

    (若摄像头无法启动,可能需要修改usb_cam的参数,如摄像头设备号,参考usb_cam的官方文档)

  3. 运行你的人脸检测节点:

    rosrun 你的功能包名 demo_cv_face_detect
    

此时会弹出一个名为faces的窗口,实时显示电脑摄像头的画面,并在检测到的人脸周围绘制紫色矩形框。

注意事项

  • 确保电脑摄像头已正确连接并授予权限(一般用户无需额外权限,若无法访问,可尝试sudo chmod 777 /dev/video0video0为摄像头设备号)。
  • 若检测效果不佳,可调整detectMultiScale的参数(如1.1为缩放因子,9为最小邻居数),减小缩放因子或降低最小邻居数可提高检测灵敏度(但可能增加误检)。
  • usb_cam发布的图像编码默认与原代码兼容(BGR8),无需修改图像转换部分。

网站公告

今日签到

点亮在社区的每一天
去签到