一.代码声明

下面的代码是博主参考了Intel realsense官方SDK和官方例程后写的一段较为简单的代码,实现了简单的多人脸实时检测及跟踪功能。官方的人脸检测例程功能较多,但代码量很大,阅读起来也较困难,所以博主写了一段较为精简的人脸检测代码。

二.具体代码

  1. #include <pxcsensemanager.h>
  2. #include <pxcsession.h>
  3. #include "util_render.h"
  4. #include <iostream>
  5. #include <string>
  6. #include <stdio.h>
  7. #include <opencv2\opencv.hpp>
  8. #include <windows.h>
  9. #define WIDTH 640
  10. #define HEIGHT 480
  11. using namespace cv;
  12. using namespace std;
  13. void DrawRectangle(Mat &img, Rect box)
  14. {
  15. rectangle(img, box, Scalar(255, 255, 0),2);
  16. }
  17. int main(int argc, char** argv)
  18. {
  19. PXCSenseManager *psm = 0;
  20. psm = PXCSenseManager::CreateInstance();
  21. if (!psm)
  22. {
  23. wprintf_s(L"Unabel to create the PXCSenseManager\n");
  24. return 1;
  25. }
  26. //使能人脸跟踪
  27. psm->EnableFace();
  28. // 初始化管道
  29. psm->Init();
  30. //得到一个人脸模块的实例
  31. PXCFaceModule *faceModule = psm->QueryFace();
  32. if (faceModule == NULL)
  33. {
  34. wprintf_s(L"Unabel to query FaceModule\n");
  35. return 3;
  36. }
  37. //创建一个人脸追踪模块动态配置的实例
  38. PXCFaceConfiguration *cfg = faceModule->CreateActiveConfiguration();
  39. if (cfg == NULL)
  40. {
  41. wprintf_s(L"Unabel to create FaceConfiguration\n");
  42. return 4;
  43. }
  44. cfg->detection.isEnabled = TRUE; //这句也可注释掉,不影响检测结果
  45. //使能所有警告
  46. cfg->EnableAllAlerts();
  47. //将任何参数的改变反馈给faceModule
  48. cfg->ApplyChanges();
  49. //创建人脸数据的实例
  50. PXCFaceData *facedata = faceModule->CreateOutput();
  51. PXCImage *colorIm;
  52. PXCImage::ImageData color_data;
  53. PXCImage::ImageInfo color_info;
  54. while (psm->AcquireFrame(true) >= PXC_STATUS_NO_ERROR)
  55. {
  56. if (psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR) break;
  57. //获取最新的人脸追踪配置参数
  58. facedata->Update();
  59. PXCCapture::Sample *sample = psm->QuerySample();
  60. colorIm = sample->color;
  61. if (colorIm->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &color_data) < PXC_STATUS_NO_ERROR)
  62. wprintf_s(L"未正常获取彩色图\n");
  63. color_info = sample->color->QueryInfo();
  64. Mat color(Size(color_info.width, color_info.height), CV_8UC3, (void*)color_data.planes[0], color_data.pitches[0] / sizeof(uchar));
  65. //取出检测到的人脸数目
  66. pxcI32 nfaces = facedata->QueryNumberOfDetectedFaces();
  67. //对视野内每一张人脸追踪处理
  68. for (pxcI32 i = 0; i < nfaces; i++) {
  69. //按序号获取一个人脸的数据实例
  70. PXCFaceData::Face *trackedface = facedata->QueryFaceByIndex(i);
  71. PXCFaceData::DetectionData *detectiondata = trackedface->QueryDetection();
  72. if (detectiondata == NULL)
  73. {
  74. wprintf_s(L"Unabel to get detection data\n");
  75. return 5;
  76. }
  77. //将当前人脸的位置数据存在rect中
  78. PXCRectI32 rect;
  79. detectiondata->QueryBoundingRect(&rect);
  80. //PXCRectI32到opencv中Rect类的转化
  81. Rect cvrect = Rect(rect.x, rect.y, rect.w, rect.h);
  82. DrawRectangle(color, cvrect);
  83. //给当前人脸加上识别序号的文字
  84. stringstream ss;
  85. ss << i;
  86. string id = ss.str();
  87. id = "ID:" + id;
  88. putText(color,id, Point(rect.x+rect.w/2, rect.y-rect.h/20), CV_FONT_HERSHEY_COMPLEX, 0.4, Scalar(255, 255, 0));
  89. }
  90. colorIm->ReleaseAccess(&color_data);
  91. stringstream ss;
  92. ss << nfaces;
  93. string  num_faces= ss.str();
  94. num_faces =num_faces + " faces in the field of view.";
  95. putText(color, num_faces, Point(color.rows/20,color.cols/40), CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(153, 51, 250));
  96. psm->ReleaseFrame();
  97. imshow("face_detection", color);
  98. waitKey(1);
  99. }
  100. facedata->Release();
  101. cfg->Release();
  102. psm->Close();
  103. psm->Release();
  104. }
#include <pxcsensemanager.h>
#include <pxcsession.h>
#include "util_render.h"
#include <iostream>
#include <string>
#include <stdio.h>
#include <opencv2\opencv.hpp>
#include <windows.h> #define WIDTH 640
#define HEIGHT 480 using namespace cv;
using namespace std; void DrawRectangle(Mat &img, Rect box)
{
rectangle(img, box, Scalar(255, 255, 0),2);
} int main(int argc, char** argv)
{
PXCSenseManager *psm = 0;
psm = PXCSenseManager::CreateInstance();
if (!psm)
{
wprintf_s(L"Unabel to create the PXCSenseManager\n");
return 1;
} //使能人脸跟踪
psm->EnableFace(); // 初始化管道
psm->Init(); //得到一个人脸模块的实例
PXCFaceModule *faceModule = psm->QueryFace(); if (faceModule == NULL)
{
wprintf_s(L"Unabel to query FaceModule\n");
return 3;
} //创建一个人脸追踪模块动态配置的实例
PXCFaceConfiguration *cfg = faceModule->CreateActiveConfiguration(); if (cfg == NULL)
{
wprintf_s(L"Unabel to create FaceConfiguration\n");
return 4;
} cfg->detection.isEnabled = TRUE; //这句也可注释掉,不影响检测结果 //使能所有警告
cfg->EnableAllAlerts(); //将任何参数的改变反馈给faceModule
cfg->ApplyChanges(); //创建人脸数据的实例
PXCFaceData *facedata = faceModule->CreateOutput(); PXCImage *colorIm;
PXCImage::ImageData color_data;
PXCImage::ImageInfo color_info; while (psm->AcquireFrame(true) >= PXC_STATUS_NO_ERROR) {
if (psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR) break; //获取最新的人脸追踪配置参数
facedata->Update(); PXCCapture::Sample *sample = psm->QuerySample();
colorIm = sample->color; if (colorIm->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &color_data) < PXC_STATUS_NO_ERROR)
wprintf_s(L"未正常获取彩色图\n"); color_info = sample->color->QueryInfo(); Mat color(Size(color_info.width, color_info.height), CV_8UC3, (void*)color_data.planes[0], color_data.pitches[0] / sizeof(uchar)); //取出检测到的人脸数目
pxcI32 nfaces = facedata->QueryNumberOfDetectedFaces(); //对视野内每一张人脸追踪处理
for (pxcI32 i = 0; i < nfaces; i++) {
//按序号获取一个人脸的数据实例
PXCFaceData::Face *trackedface = facedata->QueryFaceByIndex(i);
PXCFaceData::DetectionData *detectiondata = trackedface->QueryDetection(); if (detectiondata == NULL)
{
wprintf_s(L"Unabel to get detection data\n");
return 5;
} //将当前人脸的位置数据存在rect中
PXCRectI32 rect;
detectiondata->QueryBoundingRect(&rect); //PXCRectI32到opencv中Rect类的转化
Rect cvrect = Rect(rect.x, rect.y, rect.w, rect.h);
DrawRectangle(color, cvrect); //给当前人脸加上识别序号的文字
stringstream ss;
ss << i;
string id = ss.str();
id = "ID:" + id;
putText(color,id, Point(rect.x+rect.w/2, rect.y-rect.h/20), CV_FONT_HERSHEY_COMPLEX, 0.4, Scalar(255, 255, 0));
} colorIm->ReleaseAccess(&color_data); stringstream ss;
ss << nfaces;
string num_faces= ss.str();
num_faces =num_faces + " faces in the field of view.";
putText(color, num_faces, Point(color.rows/20,color.cols/40), CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(153, 51, 250)); psm->ReleaseFrame();
imshow("face_detection", color);
waitKey(1);
}
facedata->Release();
cfg->Release();
psm->Close();
psm->Release();
}

运行结果和丑照:

三.心得体会

说实话,研究realsense的sdk是略痛苦的,因为可参考的资料实在有限,除了官方sdk就只有一个开发者论坛了。当你上网搜索kinect的相关资料时,可以发现大批大神的研究例程和心得。反过来看realsense,新闻很多,都是说它怎么怎么厉害,但是并没有多少对开发者有参考价值的资料。realsense毫无疑问比kinect强悍,体积又小,但因为发布时间较短,所以大部分人都还在研究这玩意怎么用。

就像上面这个程序,博主在看完sdk关于人脸检测的介绍之后,按照它的框架去码代码,码的时候自己都有点迷糊每一步的意思。最后程序闪退,得不到任何结果,人脸都没有,还检测什么。无奈之下只有看example了,天哪噜,代码量实在大,还有一堆写窗口和按钮的,只能慢慢从里面探索出对自己有用的东西。

看久了也就能看出一些门道了,比如ApplyChanges到底有什么用, 原来FaceConfiguration这个接口一旦创建了,就和FaceModule独立了,使用ApplyChanges是为了在模块配置参数发生变化时能通过update来将最新的配置参数传递给FaceModule。然而一开始,我并有理解这些,所以代码里连update都没有,结果只能是gg。

甚至在刚开始的时候,我的enableface还有配置实例的创建代码都是写在while获取每一帧里面的,后面才理解了人脸模块的使能以及人脸追踪的配置应该在获取图片帧之前完成,然后获取一帧图片之后,更新人脸配置参数,对该帧图片检测人脸,对每一个检测到的人脸进行处理。

总之,路漫漫,博主继续研究去了。

最新文章

  1. Android手机相册的布局
  2. java 堆栈的区别(转百度)
  3. Python中的参数
  4. 摸索js的3d全景
  5. Python—I/O多路复用
  6. 12个JavaScript技巧
  7. 偶然发现的一个地图网站mapbox
  8. VTK三维重建(2)-根据脚部骨骼CT的三维重建和显示
  9. JSP EL表达式详细介绍
  10. 挂载磁盘的问题(/dev/sdb1 is apparently in use by the system; will not make a 文件系统 here!)
  11. JS选择checkbox
  12. 在C#中internal关键字是什么意思?
  13. 【转】在Eclipse环境下配置Servlet开发环境
  14. django学习笔记二:一个项目多个App项目搭建
  15. C++外观设计模式模式(三)
  16. Collection、List、Set集合概括
  17. AndroidStudio 快捷键(最实用的20个)(转)
  18. 【linux】之日志查看
  19. 姿态角(Euler角):yaw pitch roll
  20. PSP(3.23——3.29)以及周记录

热门文章

  1. 笨笨-歌词伴侣V1.2(酷狗KRC转LRC,LRC歌词批量下载)
  2. javascript实现继承的一种方式
  3. Java [Leetcode 205]Isomorphic Strings
  4. IO负载高的来源定位
  5. bjfu1238 卡特兰数取余
  6. PHP中我经常容易混淆的三组函数
  7. cxf 动态创建客户端,局域网能正常调用服务端,外网不能访问
  8. 数往知来C#面向对象准备〈二〉
  9. 分析特定类的python脚本
  10. Windows 8.1及Windows8 JDK环境变量配置