ROS中进行OpenCV物体识别

ROS驱动摄像头,发布图像消息
将ROS图像消息转换成OpenCV图像数据
OpenCV图像处理
OpenCV图像转换成ROS消息

头文件

#ifndef FACE_DETECTOR_HPP_
#define FACE_DETECTOR_HPP_

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include "opencv2/highgui/highgui.hpp"

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <image_transport/image_transport.h>

定义7种颜色,用于标记人脸
cv::Scalar colors[] =
{
    // 红橙黄绿青蓝紫
   CV_RGB(255,0,0),
   CV_RGB(255, 97, 0),
   CV_RGB(255, 255, 0),
   CV_RGB(0, 255, 0),
   CV_RGB(255, 97, 0),
   CV_RGB(0, 0, 255),
   CV_RGB(160, 32, 240),
};

class FaceDetector
{
public:
    FaceDetector(ros::NodeHandle& nh);

    ~FaceDetector();

private:
    void detectFace(const sensor_msgs::ImageConstPtr &msg);
    void drawFace(cv::Mat &image, const std::vector<cv::Rect> &rect);
    void imageCb(const sensor_msgs::ImageConstPtr &msg);

    image_transport::ImageTransport it_;
    image_transport::Subscriber image_sub_;
    image_transport::Publisher image_pub_;
    cv_bridge::CvImagePtr cv_ptr_;
    cv::Mat gray_img_;
    cv::Mat process_img_;
    cv::CascadeClassifier cascade_;
    std::vector<cv::Rect> rect_;
};

#endif /* FACE_DETECTOR_HPP_ */

cpp文件

#include "face_detector.hpp"

FaceDetector::FaceDetector(ros::NodeHandle& nh) : it_(nh)
{
    // 加载人脸分类器
    cascade_.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");
    image_sub_ = it_.subscribe("/usb_cam/image_raw", 1, &FaceDetector::imageCb, this);
    image_pub_ = it_.advertise("/face_detect", 1);
}

FaceDetector::~FaceDetector()
{
    ROS_INFO("Bye bye\n");
}

void FaceDetector::drawFace(cv::Mat &image, const std::vector<cv::Rect> &rect)
{
    cv::Point center;
    int radius;
    for(int i = 0; i < rect.size(); i++)
    {
        center.x = cvRound((rect[i].x + rect[i].width * 0.5));
        center.y = cvRound((rect[i].y + rect[i].height * 0.5));
        radius = cvRound((rect[i].width + rect[i].height) *0.25);
        cv::circle(image, center, radius, colors[i % 7], 2);
    }
}

void FaceDetector::detectFace(const sensor_msgs::ImageConstPtr &msg)
{
    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;
    }
    cv::Mat &image = cv_ptr_->image;
    process_img_ = image.clone();
    cv::cvtColor(image, gray_img_, CV_BGR2GRAY);
    cascade_.detectMultiScale(gray_img_, rect_, 1.3, 4, 0);
    ROS_INFO("%d face detected\n", static_cast<int>(rect_.size()));
    drawFace(process_img_, rect_);
    cv_bridge::CvImage out_image;
    out_image.encoding = cv_ptr_->encoding;
    out_image.header = cv_ptr_->header;
    out_image.image = process_img_;
    image_pub_.publish(out_image.toImageMsg());
}

void FaceDetector::imageCb(const sensor_msgs::ImageConstPtr &msg)
{
    detectFace(msg);
}

int main(int argc, char** argv )
{
    ros::init(argc, argv, "simple_face_vision_detection");
    ros::NodeHandle n_;

    ros::WallDuration(0.1).sleep();

    FaceDetector fd(n_);

    while (ros::ok())
    {
        // Process image callback
        ros::spinOnce();

        ros::WallDuration(0.1).sleep();
    }
    return 0;
}

launch文件

<launch>
    <include file="$(find ur5_vision)/launch/usb_cam.launch" />
    <node name="face_detector" pkg="ur5_vision" type="face_detector" output="screen" />
    <node name="image_viewer" pkg="rqt_image_view" type="rqt_image_view" output="screen" >
        <param name="image" value="/face_detect" />
    </node>
</launch>

启动后将看到标注人脸(如果有)的视频流,终端会打印检测到人脸的数目
在这里插入图片描述

根据引用,在使用ROSOpenCV进行颜色识别时,需要借助于cv_bridge将ROS的图像数据格式转换为OpenCV可以使用的数据格式。cv_bridge是一个提供ROSOpenCV库之间接口的开发包。接着,可以使用OpenCV的函数对图像进行处理,如轮廓检测等。然后再将处理好的图像转换回ROS的数据格式。 具体来说,可以使用try...catch函数将ROS的图像数据通过cv_bridge转化成OpenCV格式的数据。转化的关键步骤是使用cv_bridge::toCvCopy函数,将ROS的图像消息(msg)转换成OpenCV的图像格式。转换后,可以使用OpenCV的函数进行颜色识别等操作。 因此,ROSOpenCV的结合可以实现对图像的颜色识别功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【OpenCV】C++红绿灯轮廓识别+ROS话题实现](https://blog.csdn.net/Roy_Yuan_/article/details/130728047)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [在ROS基于颜色做简单的物体识别](https://blog.csdn.net/zzu_seu/article/details/91320455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值