Realsense 人臉識別

一.代碼聲明

     下面的代碼是博主參考了Intel realsense官方SDK和官方例程後寫的一段較爲簡單的代碼,實現了簡單的多人臉實時檢測及跟蹤功能。官方的人臉檢測例程功能較多,但代碼量很大,閱讀起來也較困難,因此博主寫了一段較爲精簡的人臉檢測代碼。javascript

 

二.具體代碼

  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.   
  10. #define WIDTH 640    
  11. #define HEIGHT 480    
  12.   
  13. using namespace cv;  
  14. using namespace std;  
  15.   
  16. void DrawRectangle(Mat &img, Rect box)  
  17. {  
  18.     rectangle(img, box, Scalar(255, 255, 0),2);  
  19. }  
  20.   
  21. int main(int argc, char** argv)  
  22. {  
  23.     PXCSenseManager *psm = 0;  
  24.     psm = PXCSenseManager::CreateInstance();  
  25.     if (!psm)  
  26.     {  
  27.         wprintf_s(L"Unabel to create the PXCSenseManager\n");  
  28.         return 1;  
  29.     }  
  30.   
  31.     //使能人臉跟蹤  
  32.     psm->EnableFace();  
  33.   
  34.     // 初始化管道  
  35.     psm->Init();  
  36.   
  37.     //獲得一我的臉模塊的實例  
  38.     PXCFaceModule *faceModule = psm->QueryFace();  
  39.   
  40.     if (faceModule == NULL)  
  41.     {  
  42.         wprintf_s(L"Unabel to query FaceModule\n");  
  43.         return 3;  
  44.     }  
  45.   
  46.     //建立一我的臉追蹤模塊動態配置的實例  
  47.     PXCFaceConfiguration *cfg = faceModule->CreateActiveConfiguration();  
  48.   
  49.     if (cfg == NULL)  
  50.     {  
  51.         wprintf_s(L"Unabel to create FaceConfiguration\n");  
  52.         return 4;  
  53.     }  
  54.   
  55.     cfg->detection.isEnabled = TRUE; //這句也可註釋掉,不影響檢測結果  
  56.   
  57.     //使能全部警告  
  58.     cfg->EnableAllAlerts();  
  59.   
  60.     //將任何參數的改變反饋給faceModule  
  61.     cfg->ApplyChanges();  
  62.   
  63.     //建立人臉數據的實例  
  64.     PXCFaceData *facedata = faceModule->CreateOutput();  
  65.   
  66.     PXCImage *colorIm;  
  67.     PXCImage::ImageData color_data;  
  68.     PXCImage::ImageInfo color_info;  
  69.   
  70.     while (psm->AcquireFrame(true) >= PXC_STATUS_NO_ERROR)  
  71.   
  72.     {  
  73.         if (psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR) break;  
  74.   
  75.         //獲取最新的人臉追蹤配置參數  
  76.         facedata->Update();  
  77.   
  78.         PXCCapture::Sample *sample = psm->QuerySample();  
  79.         colorIm = sample->color;  
  80.   
  81.         if (colorIm->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &color_data) < PXC_STATUS_NO_ERROR)  
  82.             wprintf_s(L"未正常獲取彩色圖\n");  
  83.   
  84.         color_info = sample->color->QueryInfo();  
  85.   
  86.         Mat color(Size(color_info.width, color_info.height), CV_8UC3, (void*)color_data.planes[0], color_data.pitches[0] / sizeof(uchar));  
  87.           
  88.         //取出檢測到的人臉數目  
  89.         pxcI32 nfaces = facedata->QueryNumberOfDetectedFaces();  
  90.   
  91.         //對視野內每一張人臉追蹤處理  
  92.         for (pxcI32 i = 0; i < nfaces; i++) {  
  93.             //按序號獲取一我的臉的數據實例  
  94.             PXCFaceData::Face *trackedface = facedata->QueryFaceByIndex(i);  
  95.             PXCFaceData::DetectionData *detectiondata = trackedface->QueryDetection();  
  96.   
  97.             if (detectiondata == NULL)  
  98.             {  
  99.                 wprintf_s(L"Unabel to get detection data\n");  
  100.                 return 5;  
  101.             }  
  102.   
  103.             //將當前人臉的位置數據存在rect中  
  104.             PXCRectI32 rect;  
  105.             detectiondata->QueryBoundingRect(&rect);  
  106.   
  107.             //PXCRectI32到opencv中Rect類的轉化  
  108.             Rect cvrect = Rect(rect.x, rect.y, rect.w, rect.h);  
  109.             DrawRectangle(color, cvrect);  
  110.   
  111.             //給當前人臉加上識別序號的文字  
  112.             stringstream ss;  
  113.             ss << i;  
  114.             string id = ss.str();  
  115.             id = "ID:" + id;  
  116.             putText(color,id, Point(rect.x+rect.w/2, rect.y-rect.h/20), CV_FONT_HERSHEY_COMPLEX, 0.4, Scalar(255, 255, 0));  
  117.         }  
  118.                           
  119.         colorIm->ReleaseAccess(&color_data);  
  120.   
  121.         stringstream ss;  
  122.         ss << nfaces;  
  123.         string  num_faces= ss.str();  
  124.         num_faces =num_faces + " faces in the field of view.";  
  125.         putText(color, num_faces, Point(color.rows/20,color.cols/40), CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(153, 51, 250));  
  126.   
  127.         psm->ReleaseFrame();  
  128.         imshow("face_detection", color);  
  129.         waitKey(1);  
  130.     }  
  131.     facedata->Release();  
  132.     cfg->Release();  
  133.     psm->Close();  
  134.     psm->Release();  
  135. }  
#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();
}

 

 

運行結果和醜照:java

三.心得體會ios

說實話,研究realsense的sdk是略痛苦的,由於可參考的資料實在有限,除了官方sdk就只有一個開發者論壇了。當你上網搜索kinect的相關資料時,能夠發現大批大神的研究例程和心得。反過來看realsense,新聞不少,都是說它怎麼怎麼厲害,可是並無多少對開發者有參考價值的資料。realsense毫無疑問比kinect強悍,體積又小,但由於發佈時間較短,因此大部分人都還在研究這玩意怎麼用。windows

就像上面這個程序,博主在看完sdk關於人臉檢測的介紹以後,按照它的框架去碼代碼,碼的時候本身都有點迷糊每一步的意思。最後程序閃退,得不到任何結果,人臉都沒有,還檢測什麼。無奈之下只有看example了,天哪嚕,代碼量實在大,還有一堆寫窗口和按鈕的,只能慢慢從裏面探索出對本身有用的東西。session

看久了也就能看出一些門道了,好比ApplyChanges到底有什麼用, 原來FaceConfiguration這個接口一旦建立了,就和FaceModule獨立了,使用ApplyChanges是爲了在模塊配置參數發生變化時能經過update來將最新的配置參數傳遞給FaceModule。然而一開始,我並有理解這些,因此代碼裏連update都沒有,結果只能是gg。框架

甚至在剛開始的時候,個人enableface還有配置實例的建立代碼都是寫在while獲取每一幀裏面的,後面才理解了人臉模塊的使能以及人臉追蹤的配置應該在獲取圖片幀以前完成,而後獲取一幀圖片以後,更新人臉配置參數,對該幀圖片檢測人臉,對每個檢測到的人臉進行處理。ui

總之,路漫漫,博主繼續研究去了。spa

相關文章
相關標籤/搜索