github地址https://github.com/ngunauj/facedetection

熟悉ros环境。ubuntu16.04 + ros kinetic版本。使用笔记本自带摄像头,完成人脸的实时检测。代码可能会更改,具体以github上的代码为主。

camera_subscribe.cpp 订阅camera发出的图片信息,然后对Mat 类型的图片进行每一帧图片的人脸检测,人脸检测代码参考opencv的开源代码。
/* ***********************************************
Author :guanjunace@foxmail.com
Created Time :2017年07月10日 星期一 10时43分26秒
File Name :camera_subscribe.cpp
************************************************ */
#include <iostream>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
using namespace std;
using namespace cv;
const string cascadeName = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";
const string nestedCascadeName = "/usr/share/opencv/haarcascades/haarcascade_eye.xml";
const double scale = 1.3;
void detectFace(Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade) {
double t = ;
vector<Rect> faces;
const static Scalar colors[] = {
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,),
Scalar(,,)
};
Mat gray, smallImg; cvtColor( img, gray, COLOR_BGR2GRAY );
double fx = / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR);
equalizeHist(smallImg, smallImg);
t = (double)getTickCount();
cascade.detectMultiScale(smallImg, faces, 1.1, ,
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
|CASCADE_SCALE_IMAGE,
Size(, ));
t = (double)getTickCount() - t;
printf("detection time = %g ms\n", t*/getTickFrequency());
for (size_t i = ; i < faces.size(); ++i) {
Rect r = faces[i];
Mat smallImgROI;
vector<Rect> nestedObjects;
Point center;
Scalar color = colors[i%];
int radius;
double aspect_ratio = (double)r.width/r.height;
if(0.75 < aspect_ratio && aspect_ratio < 1.3) {
center.x = cvRound((r.x + r.width*0.5)*scale);
center.y = cvRound((r.y + r.height*0.5)*scale);
radius = cvRound((r.width + r.height)*0.25*scale);
circle(img, center, radius, color, , , );
} else {
rectangle(img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
cvPoint(cvRound((r.x + r.width-)*scale), cvRound((r.y + r.height-)*scale)),
color, , , );
}
smallImgROI = smallImg(r);
nestedCascade.detectMultiScale(smallImgROI, nestedObjects,
1.1, ,
|CASCADE_SCALE_IMAGE,
Size(, ) );
for (size_t j = ; j < nestedObjects.size(); ++j) {
Rect nr = nestedObjects[j];
center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
radius = cvRound((nr.width + nr.height)*0.25*scale);
circle(img, center, radius, color, , , );
} }
imshow("result", img);
waitKey(); }
void img_Callback(const sensor_msgs::ImageConstPtr& msg) {
Mat image ;
CascadeClassifier cascade, nestedCascade;
try {
image = cv_bridge::toCvShare(msg, "bgr8")->image;
//CascadeClassifier cascade, nestedCascade;
nestedCascade.load(nestedCascadeName);
cascade.load(cascadeName);
detectFace(image, cascade, nestedCascade);
//Convert an immutable sensor_msgs::Image message to an OpenCV-compatible CvImage,
//sharing the image data if possible.
//imshow("img", cv_bridge::toCvShare(msg, "bgr8")->image);//IplImage 类型的 mat
//waitKey(1);
} catch (cv_bridge::Exception &e) {
ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
}
if (!image.empty()) detectFace(image, cascade, nestedCascade);
else printf("no image!");
}
int main(int argc, char *argv[]) {
ros::init(argc, argv, "img_subscribe");
ros::NodeHandle nh;
namedWindow("webcamimg");
startWindowThread();/*
CascadeClassifier cascade, nestedCascade;
if (!nestedCascade.load(nestedCascadeName))
cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
if (!cascade.load(cascadeName)) {
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
*/
image_transport::ImageTransport it(nh);
image_transport::Subscriber img_sub = it.subscribe("/webcam/img", , &(img_Callback)); destroyWindow("webcamimg");
ros::spin();
return ;
}

camera_driver代码

/* ***********************************************
Author :guanjun guanjunace@foxmail.com
Created Time :2017/7/8 10:40:13
File Name :camera_publisher.cpp
************************************************ */
#include <bits/stdc++.h>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/highgui/highgui.hpp> using namespace std;
using namespace cv; class WebCam {
public:
WebCam (ros::NodeHandle& nh, int video_source = )
: it(nh),
cap(video_source) {
if (!cap.isOpened()) {
ROS_ERROR("Cannot open the camera!\n");
}
/*设置主题名和缓冲区*/
imgPub = it.advertise("webcam/img", );
/*初始化CvImage智能指针,CvImage为Mat与ROS图像之间转换的载体*/
frame = boost::make_shared<cv_bridge::CvImage>();
/*设置ROS图片为BGR且每个像素点用1个字节来表示类似于CV_8U*/
frame->encoding = sensor_msgs::image_encodings::BGR8;
}
/*图像发布函数*/
int publishImage(){
/*将摄像头获取到的图像存放在frame中的image*/
cap >> frame->image;
/*判断是否获取到图像,若获取到图像,将其转化为ROS图片*/
if (!(frame->image.empty())){
frame->header.stamp = ros::Time::now();
imgPub.publish(frame->toImageMsg());
}
return ;
}
private:
/*设置图片节点*/
image_transport::ImageTransport it;
/*设置图片的发布者*/
image_transport::Publisher imgPub;
/*设置存放摄像头图像的变量*/
VideoCapture cap;
/*设置cvImage的智能指针*/
cv_bridge::CvImagePtr frame;
}; int main(int argc, char *argv[]) {
/*初始化节点,并设定节点名*/
ros::init(argc, argv, "img_publiser");
/*设置节点句柄*/
ros::NodeHandle nh; /*判断输入参数是否完成*/
if (argv[] == NULL){
ROS_WARN("Please choose the camera you want to use !");
return ;
}
/*获取打开摄像机的设备号*/
int video_source = ;
int default_p = ;
istringstream default_param(argv[]);
default_param >> default_p;
nh.param<int>("video_source", video_source, default_p); /*定义摄像机对象*/
WebCam webcam(nh, video_source); /*设置主题的发布频率为10Hz*/
ros::Rate loop_rate();
/*图片节点进行主题的发布*/
while (ros::ok()) {
webcam.publishImage();
ros::spinOnce();
/*按照设定的频率来将程序挂起*/
loop_rate.sleep();
}
return ;
}

在人脸检测的过程中,随着人脸的移动,有个别帧并不能检测出人脸,考虑以后哦要加个跟踪

ROS人脸检测 使用webcam实现的更多相关文章

  1. 基于opencv的人脸检测的web应用

    参考资料 https://github.com/bsdnoobz/web-based-face-detect http://opencv-code.com/projects/web-based-int ...

  2. caffe_实战之两个简单的例子(物体分类和人脸检测)

    一.物体分类: 这里使用的是caffe官网中自带的例子,我这里主要是对代码的解释~ 首先导入一些必要的库: import caffe import numpy as np import matplot ...

  3. 利用html5、websocket和opencv实现人脸检测

    最近学习人脸识别相关的东西,在MFC下使用OpenCV做了一个简单的应用.训练需要较多的数据,windows应用程序终究还是不方便,于是想着做成CS模式:检测识别都放在服务器端,视频获取和显示都放在网 ...

  4. 基于Emgu CV的人脸检测代码

    这个提供的代码例子是Emgu CV提供的源码里面自带的例子,很好用,基本不需要改,代码做的是人脸检测不是人脸识别,这个要分清楚.再就是新版本的Emgu CV可能会遇到系统32位和64位处理方式有区别的 ...

  5. 浅谈人脸检测之Haar分类器方法

    我们要探讨的Haar分类器实际上是Boosting算法(提升算法)的一个应用,Haar分类器用到了Boosting算法中的AdaBoost算法,只是把AdaBoost算法训练出的强分类器进行了级联,并 ...

  6. 基于OpenCv的人脸检测、识别系统学习制作笔记之三

    1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...

  7. 基于MATLAB的adaboost级联形式的人脸检测实现

    很早之前就做过一些关于人脸检测和目标检测的课题,一直都没有好好总结出来,趁着这个机会,写个总结,希望所写的内容能给研究同类问题的博友一些见解和启发!!博客里面涉及的公式太繁琐了,直接截图了. 转载请注 ...

  8. 学习OpenCV——行人检测&人脸检测(总算运行出来了)

    之前运行haar特征的adaboost算法人脸检测一直出错,加上今天的HOG&SVM行人检测程序,一直报错. 今天总算发现自己犯了多么白痴的错误——是因为外部依赖项lib文件没有添加完整,想一 ...

  9. 基于OpenCv的人脸检测、识别系统学习制作笔记之二

    在网上找到了一个博客,里面有大量内容适合初学者接触和了解人脸检测的博文,正好符合我目前的学习方面,故将链接放上来,后续将分类原博客的博文并加上学习笔记. 传送门: http://blog.sina.c ...

随机推荐

  1. 【sqli-labs】 对于less34 less36的宽字节注入的一点深入

    1.AddSlashes() 首先来观察一下是如何通过构造吃掉转义字符的 先将less 34的网页编码换成gbk 加上一些输出 echo "Before addslashes(): &quo ...

  2. 6.15 分解IP地址

    问题:将一个IP地址字段分解到列中,考虑下面列出的IP地址: 111.22.3.4 要得到如下所示的查询结果: +-----+----+---+---+| a   | b  | c | d |+--- ...

  3. redis的安装和使用【2】redis的java操作

    修改redis.conf# 配置绑定ip,作者机子为192.168.100.192,请读者根据实际情况设置bind 192.168.100.192#非保护模式protected-mode no保存重启 ...

  4. 梦想CAD控件com接口扩展数据

    随着CAD应用软件的飞速发展,经常需要保存一些与图形可视性无关的数据,即非图形参数.例如在绘制化验样图中包含品位数据.MxCAD定义了一类参数——实体扩展数据.扩展数据与实体的可视性无关,而是用户根据 ...

  5. Java基础(二)--this关键字及初始化

    构造器: 构造器的名称必须和类名完全相同,所以一般方法的"首字母小写"命名规则并不适合构造器 默认构造器: 也叫无参构造器,作用就是创建一个默认对象,如果你不是手写出来,编译器默认 ...

  6. MyBatis 的基本要素—核心对象

    MyBatis 三个基本要素   ➢ 核心接口和类 ➢ MyBatis 核心配置文件(mybatis-config.xml) ➢ SQL 映射文件(mapper.xml) MyBatis 核心接口和类 ...

  7. NT9666X调试log

    1.给GSensor_open();前加上打印函数DEBUG_P;打印如下信息: ######## FILE = e:/Project_code/Philips_PanGu/Philips_PanGu ...

  8. 洛谷 1017 进制转换 (NOIp2000提高组T1)

    [题解] 纯模拟题. 我们都知道十进制数化成m进制数可以用短除法,即除m取余.逆序排列.而m进制数化为十进制数,按权展开求和即可. 但在本题中进制的基数R可能为负数,我们知道a%R的符号与R一致,也就 ...

  9. BZOJ 3747 洛谷 3582 [POI2015]Kinoman

    [题解] 扫描线+线段树. 我们记第i部电影上次出现的位置是$pre[i]$,我们从$1$到$n$扫描,每次区间$(pre[i],i]$加上第i部电影的贡献$w[f[i]]$,区间$[pre[pre[ ...

  10. 1289大鱼吃小鱼(STL中栈的应用)

    >>点击进入测试<< 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向 ...