Kinect 2.0 高帧率 同分辨率采集RGB-D图像并保存,并显示人体骨架

环境:Kinect 2.0 + Opencv 2.4.13.2

先上效果图:


我的代码是在这位大神的基础上做的,非常感谢这位大神的无私分享。

关于环境配置的问题,网上已有较多的资料,我不再赘述。

关于RGB-D图像校准的问题,我试过一些方法,结论是无法做到像素级别的完全对齐,个人认为这是深度图像本身的特性决定的。经过各种尝试,我的校准只能是图片中心基本对齐,距离中心越远偏差越大。

关于采集帧率的问题,Kinect 2.0的理论帧率为30帧/秒,但是在测试中我能够检测到的最高帧率是20帧/秒。大神以及我之前的代码只能实现3-5帧/秒的拍摄,由于我们实验需要,我现在实现了稳定的15帧/秒。缺点是只能录一分钟。因为我的写法就是爆内存的暴力写法,但是对于实验是够用了。如果哪位大神能实现更高的帧率,或者更长的录制时间,还望不吝赐教!

我的代码会检测工程目录下是否有'datasave'文件夹,如果没有则会创建该文件夹,并在其下创建四个子文件夹。会同时显示RGB与D图像,检测到人体之后会在图上画出点和线,并开始在datasave文件夹中保存一系列图片以及2D-3D骨骼坐标信息。按任意键会打断拍摄,并开始保存图像,保存完毕后会自动退出程序。最多录制1000幅图像,再多就会自动开始保存图像了。经过多次测试,确认无明显bug。

欢迎各位大神指教。

#include "opencv2/opencv.hpp"
#include <iostream>
#include <algorithm>
#include <opencv2\imgproc.hpp>
#include <opencv2\calib3d.hpp>
#include <opencv2\highgui.hpp>
#include <Kinect.h>
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include <string>
#include <strstream>
#include <stdlib.h>
#include <WinUser.h>
#include <windows.h>
#include <conio.h>
#include <time.h>

using namespace cv;
using namespace std;

# define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1 : 0)

//7.3 Added
int mapp[800][800];
//7/3 Added end

int flag_color = -1;
int flag_depth = -1;
int fps = 0;

int rgbnum = 0;
int rgbnum2 = 0;
int dnum = 0;
int threedcoordinatenum = 0;
int dcoordinatenum = 0;
int twodcoordinate[100][10];//用于暂存二维和三维坐标
double threecoordinate[100][10];
FILE *fp, *tp;
char pointsname[50][20] = { "haha", "Head ", "Neck ", "SpineShoulder ", "ShoulderRight ", "ElbowRight ", "WristRight ", "HandRight ", "ThumbRight ", "HandTipRigh ", "ShoulderLeft ", "ElbowLeft ", "WristLeft ", "HandLeft ", "ThumbLeft ", "HandTipLeft ", "SpineMid ", "HipRight ", "HipLeft ", "Spine_Base ", "KneeRight ", "AnkleRight ", "FootRight ", "KneeLeft ", "AnkleLeft ", "FootLeft " };
char *s = "./datasave", *s1 = "./datasave/rgbsave/", *s2 = "./datasave/dsave";
char *s3 = "./datasave/dpsave", *s4 = "./datasave/rgbpsave";

int CopyIndexD = 0, CopyIndexC = 0;
bool CopyIndexFlag;
Mat ColorCopy[1100], DepthCopy[1100];
Mat ColorpCopy[1100], DepthpCopy[1100];

//int d2save[10000][30][5];
//double d3save[10000][30][5];

static int flag = 1;
static int maxx = 0;

int AviColor = 1;
int AviForamt = -1;


Point Head_leftup_depth, Head_leftdown_depth, Head_rightup_depth, Head_rightdown_depth;
Point Head_leftup_color, Head_leftdown_color, Head_rightup_color, Head_rightdown_color;

Mat ConvertMat(const UINT16* pBuffer, int nWidth, int nHeight)
{
	Mat img(nHeight, nWidth, CV_16UC1);
	ushort* p_mat = (ushort *)img.data;//指向头指针
	const UINT16* pBuffer_max = pBuffer;
	const int init = (int)pBuffer_max;
	const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);//指向最后一个元素的指针

	while (pBuffer < pBufferEnd)
	{
		double a = *pBuffer++;
		*p_mat = a;
		p_mat++;
	}
	return img;
}


template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
	if (pInterfaceToRelease != NULL)
	{
		pInterfaceToRelease->Release();
		pInterfaceToRelease = NULL;
	}
}

//定义Kinect方法类
class Kinect
{
public:
	static const int        cDepthWidth = 512;   //深度图的大小
	static const int        cDepthHeight = 424;

	static const int        cColorWidth = 1920;   //彩色图的大小
	static const int        cColorHeight = 1080;

	int myBodyCount = 0;
	Mat showImageDepth;

	HRESULT					InitKinect();//初始化Kinect
	void					UpdateDepth();//更新深度数据
	void					UpdateColor();//更新深度数据
	void					ProcessDepth(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth);   //处理得到的深度图数据
	void					ProcessColor(RGBQUAD* pBuffer, int nWidth, int nHeight);   //处理得到的彩色图数据
	void					draw_color(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper, int twodcoor1, int twodcoor2);
	void					draw_depth(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper);

	Kinect();                                     //构造函数
	~Kinect();                                     //析构函数

private:

	IKinectSensor*          m_pKinectSensor;// Current Kinect
	IDepthFrameReader*      m_pDepthFrameReader;// Depth reader    在需要的时候可以再添加IColorFrameReader,进行color reader
	RGBQUAD*                m_pDepthRGBX;
	IColorFrameReader*      m_pColorFrameReader;// Color reader
	RGBQUAD*                m_pColorRGBX;
	IColorFrame * myColorFrame = nullptr;
	IFrameDescription   * myDescription = nullptr;
	IColorFrameSource   * myColorSource = nullptr;

	IBodyFrameSource    * myBodySource = nullptr;
	IBodyFrameReader    * myBodyReader = nullptr;
	IBodyFrame  * myBodyFrame = nullptr;
	ICoordinateMapper   * myMapper = nullptr;

	int colorHeight = 0, colorWidth = 0;
	Point Head_leftup_color, Head_leftdown_color, Head_rightup_color, Head_rightdown_color;
	Point Head_leftup_depth, Head_leftdown_depth, Head_rightup_depth, Head_rightdown_depth;

};

int main()
{
	Kinect kinect;
	Mat showImageColor;
	kinect.InitKinect();
	int pis = 0, flag = 0;
	char c;
	CopyIndexFlag = true;
	CreateDirectory(s, NULL);
	CreateDirectory(s1, NULL);
	CreateDirectory(s2, NULL);
	CreateDirectory(s3, NULL);
	CreateDirectory(s4, NULL);
	fp = fopen("./datasave/3dCoordinateSave.txt", "a+");
	tp = fopen("./datasave/2dCoordinateSave.txt", "a+");
	while (CopyIndexD < 2000 && CopyIndexC < 2000 && !flag)
	{
		kinect.UpdateColor();                          //程序的中心内容,获取数据并显示
		kinect.UpdateDepth();
		if (waitKey(1) >= 0)
			break;
		if (_kbhit())
		{
			flag = 1;
			//if (_getch() == '\e') flag = 1;
			//if (_getch() == '\n') CopyIndexFlag = true;
		}
		//if (KEY_DOWN(MOUSE_MOVED)) CopyIndexFlag = true; //开始
		//if (KEY_DOWN(MOUSE_EVENT)) flag = 1; //结束
		//cout << CopyIndexC << ' ' << CopyIndexD << endl;
	}

	for (int i = 0; i < CopyIndexD && i < CopyIndexC; i++)
	{
		//图片保存
		IplImage qImg;

		char xn[10];
		sprintf(xn, "%d", i);

		char address[50] = "./datasave/rgbsave/";
		strcat(address, xn);
		strcat(address, ".jpg");
		char address2[50] = "./datasave/rgbpsave/";
		strcat(address2, xn);
		strcat(address2, ".jpg");
		char address3[50] = "./datasave/dsave/";
		strcat(address3, xn);
		strcat(address3, ".jpg");
		char address4[50] = "./datasave/dpsave/";
		strcat(address4, xn);
		strcat(address4, ".jpg");

		qImg = IplImage(ColorCopy[i]);
		cvSaveImage(address, &qImg);
		qImg = IplImage(ColorpCopy[i]);
		cvSaveImage(address2, &qImg);
		qImg = IplImage(DepthCopy[i]);
		cvSaveImage(address3, &qImg);
		qImg = IplImage(DepthpCopy[i]);
		cvSaveImage(address4, &qImg);
	}
	return 0;
}

Kinect::Kinect()
{
	m_pKinectSensor = NULL;
	m_pColorFrameReader = NULL;
	m_pDepthFrameReader = NULL;

	m_pDepthRGBX = new RGBQUAD[cDepthWidth * cDepthHeight];// create heap storage for color pixel data in RGBX format  ,开辟一个动态存储区域
	m_pColorRGBX = new RGBQUAD[cColorWidth * cColorHeight];// create heap storage for color pixel data in RGBX format
}

Kinect::~Kinect()                        //定义析构函数
{
	//1.14 added end
	if (m_pDepthRGBX)
	{
		delete[] m_pDepthRGBX;            //删除动态存储区域
		m_pDepthRGBX = NULL;
	}

	SafeRelease(m_pDepthFrameReader);// done with depth frame reader

	if (m_pColorRGBX)
	{
		delete[] m_pColorRGBX;
		m_pColorRGBX = NULL;
	}

	SafeRelease(m_pColorFrameReader);// done with color frame reader

	if (m_pKinectSensor)
	{
		m_pKinectSensor->Close();// close the Kinect Sensor
	}
	SafeRelease(m_pKinectSensor);
	myBodyReader->Release();
	myBodySource->Release();
	myMapper->Release();
	//myDescription->Release();
	//myColorSource->Release();
}

HRESULT	Kinect::InitKinect()            //定义初始化kinect函数
{
	HRESULT hr;                           //typedef long HRESULT

	hr = GetDefaultKinectSensor(&m_pKinectSensor);      //获取默认的kinect,一般来说只有用一个kinect,所以默认的也就是唯一的那个
	if (FAILED(hr))                                //Failed这个函数的参数小于0的时候返回true else 返回false
	{
		return hr;
	}

	if (m_pKinectSensor)
	{
		// Initialize the Kinect and get the depth reader
		IDepthFrameSource* pDepthFrameSource = NULL;
		IColorFrameSource* pColorFrameSource = NULL;

		hr = m_pKinectSensor->Open();

		if (SUCCEEDED(hr))
		{
			hr = m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
			hr = m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
			hr = m_pKinectSensor->get_BodyFrameSource(&myBodySource);

			hr = pColorFrameSource->OpenReader(&m_pColorFrameReader);
			hr = pDepthFrameSource->OpenReader(&m_pDepthFrameReader);      //初始化Depth reader,传入该IDepthReader的地址,让该指针指向深度数据流
			hr = myBodySource->OpenReader(&myBodyReader);
		}

		SafeRelease(pColorFrameSource);
		SafeRelease(pDepthFrameSource);
	}

	if (!m_pKinectSensor || FAILED(hr))
	{
		printf("No ready Kinect found! \n");
		return E_FAIL;
	}

	myBodySource->get_BodyCount(&myBodyCount);
	m_pKinectSensor->get_CoordinateMapper(&myMapper);

	return hr;
}

void Kinect::UpdateDepth()
{
	if (!m_pDepthFrameReader)
	{
		return;
	}

	IDepthFrame* pDepthFrame = NULL;

	HRESULT hr = m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);

	if (SUCCEEDED(hr))
	{
		IFrameDescription* pFrameDescription = NULL;
		int nWidth = 0;
		int nHeight = 0;
		USHORT nDepthMinReliableDistance = 0;
		USHORT nDepthMaxDistance = 0;
		UINT nBufferSize = 0;
		UINT16 *pBuffer = NULL;
		//Mat temp(height, width, CV_16UC1);

		if (SUCCEEDED(hr))
		{
			hr = pDepthFrame->get_FrameDescription(&pFrameDescription);
			hr = pFrameDescription->get_Width(&nWidth);
			hr = pFrameDescription->get_Height(&nHeight);
			hr = pDepthFrame->get_DepthMinReliableDistance(&nDepthMinReliableDistance);
			// In order to see the full range of depth (including the less reliable far field depth)
			// we are setting nDepthMaxDistance to the extreme potential depth threshold
			nDepthMaxDistance = USHRT_MAX;

			// Note:  If you wish to filter by reliable depth distance, uncomment the following line.
			// hr = pDepthFrame->get_DepthMaxReliableDistance(&nDepthMaxDistance);
			hr = pDepthFrame->AccessUnderlyingBuffer(&nBufferSize, &pBuffer);
			ProcessDepth(pBuffer, nWidth, nHeight, nDepthMinReliableDistance, nDepthMaxDistance);
		}

		SafeRelease(pFrameDescription);
	}

	SafeRelease(pDepthFrame);
}

void Kinect::UpdateColor()
{
	if (!m_pColorFrameReader)
	{
		return;
	}

	HRESULT hr = m_pColorFrameReader->AcquireLatestFrame(&myColorFrame);

	if (SUCCEEDED(hr))
	{
		IFrameDescription* pFrameDescription = NULL;
		int nWidth = 0;
		int nHeight = 0;
		ColorImageFormat imageFormat = ColorImageFormat_None;
		UINT nBufferSize = 0;
		RGBQUAD *pBuffer = NULL;

		if (SUCCEEDED(hr))
		{
			hr = myColorFrame->get_FrameDescription(&pFrameDescription);
			hr = pFrameDescription->get_Width(&nWidth);
			hr = pFrameDescription->get_Height(&nHeight);
			hr = myColorFrame->get_RawColorImageFormat(&imageFormat);

			if (imageFormat == ColorImageFormat_Bgra)
			{
				hr = myColorFrame->AccessRawUnderlyingBuffer(&nBufferSize, reinterpret_cast<BYTE**>(&pBuffer));
			}
			else if (m_pColorRGBX)
			{
				pBuffer = m_pColorRGBX;
				nBufferSize = cColorWidth * cColorHeight * sizeof(RGBQUAD);
				hr = myColorFrame->CopyConvertedFrameDataToArray(nBufferSize, reinterpret_cast<BYTE*>(pBuffer), ColorImageFormat_Bgra);
			}
			else
			{
				hr = E_FAIL;
			}

			ProcessColor(pBuffer, nWidth, nHeight);
		}

		SafeRelease(pFrameDescription);
	}

	SafeRelease(myColorFrame);
}

void Kinect::ProcessDepth(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth)
{
	// Make sure we've received valid data
	if (m_pDepthRGBX && pBuffer && (nWidth == cDepthWidth) && (nHeight == cDepthHeight))
	{
		Mat DepthImager = ConvertMat(pBuffer, nWidth, nHeight);//转换为8位的mat

		Mat DepthImage(nHeight, nWidth, CV_8UC1);
		DepthImager.convertTo(DepthImage, CV_8UC1, 255.0 / 4500);

		while (myBodyReader->AcquireLatestFrame(&myBodyFrame) != S_OK); //读取身体图像

		IBody   **  myBodyArr = new IBody *[myBodyCount];       //为存身体数据的数组做准备

		Mat show = DepthImage.clone();
		resize(DepthImage, show, Size(nWidth*1.436, nHeight*1.436));
		Rect rect(0, 15, 702, 538);
		Mat image = show(rect);

		Mat copy = image.clone();

		for (int i = 0; i < myBodyCount; i++)
			myBodyArr[i] = nullptr;

		bool pan = false;
		if (myBodyFrame->GetAndRefreshBodyData(myBodyCount, myBodyArr) == S_OK)     //把身体数据输入数组
			for (int i = 0; i < myBodyCount; i++)
			{
				BOOLEAN     result = false;
				if (myBodyArr[i]->get_IsTracked(&result) == S_OK && result) //先判断是否侦测到
				{
					Joint   myJointArr[JointType_Count];
					pan = true;

					if (myBodyArr[i]->GetJoints(JointType_Count, myJointArr) == S_OK)   //如果侦测到就把关节数据输入到数组并画图
					{
						//draw_depth(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper);
						draw_depth(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper);
						draw_depth(copy, myJointArr[JointType_Neck], myJointArr[JointType_SpineShoulder], myMapper);

						draw_depth(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_SpineMid], myMapper);
						draw_depth(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderRight], myMapper);

						draw_depth(copy, myJointArr[JointType_ShoulderLeft], myJointArr[JointType_ElbowLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_SpineMid], myJointArr[JointType_SpineBase], myMapper);
						draw_depth(copy, myJointArr[JointType_ShoulderRight], myJointArr[JointType_ElbowRight], myMapper);

						draw_depth(copy, myJointArr[JointType_ElbowLeft], myJointArr[JointType_WristLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipRight], myMapper);
						draw_depth(copy, myJointArr[JointType_ElbowRight], myJointArr[JointType_WristRight], myMapper);

						draw_depth(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_ThumbLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_HandLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_HipLeft], myJointArr[JointType_KneeLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_HipRight], myJointArr[JointType_KneeRight], myMapper);
						draw_depth(copy, myJointArr[JointType_WristRight], myJointArr[JointType_ThumbRight], myMapper);
						draw_depth(copy, myJointArr[JointType_WristRight], myJointArr[JointType_HandRight], myMapper);

						draw_depth(copy, myJointArr[JointType_HandLeft], myJointArr[JointType_HandTipLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_KneeLeft], myJointArr[JointType_AnkleLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_AnkleLeft], myJointArr[JointType_FootLeft], myMapper);
						draw_depth(copy, myJointArr[JointType_KneeRight], myJointArr[JointType_AnkleRight], myMapper);
						draw_depth(copy, myJointArr[JointType_AnkleRight], myJointArr[JointType_FootRight], myMapper);
						draw_depth(copy, myJointArr[JointType_HandRight], myJointArr[JointType_HandTipRight], myMapper);
					}
				}
			}
		delete[]myBodyArr;
		myBodyFrame->Release();
		//myColorFrame->Release();

		// Draw the data with OpenCV

		if (pan && CopyIndexFlag)
		{
			DepthpCopy[CopyIndexD] = copy.clone();
			DepthCopy[CopyIndexD] = image.clone();
			CopyIndexD++;
		}
		imshow("Depth_Image", copy);
		//cout << copy.rows << ' ' << copy.cols << endl;
	}
}

void Kinect::ProcessColor(RGBQUAD* pBuffer, int nWidth, int nHeight)
{
	// Make sure we've received valid data
	if (pBuffer && (nWidth == cColorWidth) && (nHeight == cColorHeight))
	{
		Mat ColorImage(nHeight, nWidth, CV_8UC4, pBuffer);
		while (myBodyReader->AcquireLatestFrame(&myBodyFrame) != S_OK); //读取身体图像


		IBody   **  myBodyArr = new IBody *[myBodyCount];       //为存身体数据的数组做准备、

		Mat showImage = ColorImage.clone();
		resize(ColorImage, showImage, Size(nWidth / 2, nHeight / 2));
		Rect rect(150, 0, 702, 538);
		Mat image_roi = showImage(rect);
		Mat copy = image_roi.clone();
		Mat copy2 = image_roi.clone();

		for (int i = 0; i < myBodyCount; i++)
		{
			myBodyArr[i] = nullptr;
		}

		bool pan = false;
		if (myBodyFrame->GetAndRefreshBodyData(myBodyCount, myBodyArr) == S_OK)     //把身体数据输入数组
			for (int i = 0; i < myBodyCount; i++)
			{
				BOOLEAN result = false;

				if (myBodyArr[i]->get_IsTracked(&result) == S_OK && result) //先判断是否侦测到
				{
					Joint   myJointArr[JointType_Count];
					threedcoordinatenum++;
					pan = true;

					if (myBodyArr[i]->GetJoints(JointType_Count, myJointArr) == S_OK)   //如果侦测到就把关节数据输入到数组并画图
					{
						draw_color(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper, 1, 2);

						draw_color(copy, myJointArr[JointType_Neck], myJointArr[JointType_SpineShoulder], myMapper, 2, 3);

						draw_color(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderLeft], myMapper, 3, 10);
						draw_color(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_SpineMid], myMapper, 3, 16);
						draw_color(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderRight], myMapper, 3, 4);

						draw_color(copy, myJointArr[JointType_ShoulderLeft], myJointArr[JointType_ElbowLeft], myMapper, 10, 11);
						draw_color(copy, myJointArr[JointType_SpineMid], myJointArr[JointType_SpineBase], myMapper, 16, 19);
						draw_color(copy, myJointArr[JointType_ShoulderRight], myJointArr[JointType_ElbowRight], myMapper, 4, 5);

						draw_color(copy, myJointArr[JointType_ElbowLeft], myJointArr[JointType_WristLeft], myMapper, 11, 12);
						draw_color(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipLeft], myMapper, 19, 18);
						draw_color(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipRight], myMapper, 19, 17);
						draw_color(copy, myJointArr[JointType_ElbowRight], myJointArr[JointType_WristRight], myMapper, 5, 6);

						draw_color(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_ThumbLeft], myMapper, 12, 14);
						draw_color(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_HandLeft], myMapper, 12, 13);
						draw_color(copy, myJointArr[JointType_HipLeft], myJointArr[JointType_KneeLeft], myMapper, 18, 23);
						draw_color(copy, myJointArr[JointType_HipRight], myJointArr[JointType_KneeRight], myMapper, 17, 20);
						draw_color(copy, myJointArr[JointType_WristRight], myJointArr[JointType_ThumbRight], myMapper, 6, 8);
						draw_color(copy, myJointArr[JointType_WristRight], myJointArr[JointType_HandRight], myMapper, 6, 7);

						draw_color(copy, myJointArr[JointType_HandLeft], myJointArr[JointType_HandTipLeft], myMapper, 13, 15);
						draw_color(copy, myJointArr[JointType_KneeLeft], myJointArr[JointType_AnkleLeft], myMapper, 23, 24);
						draw_color(copy, myJointArr[JointType_AnkleLeft], myJointArr[JointType_FootLeft], myMapper, 24, 25);
						draw_color(copy, myJointArr[JointType_KneeRight], myJointArr[JointType_AnkleRight], myMapper, 20, 21);
						draw_color(copy, myJointArr[JointType_AnkleRight], myJointArr[JointType_FootRight], myMapper, 21, 22);
						draw_color(copy, myJointArr[JointType_HandRight], myJointArr[JointType_HandTipRight], myMapper, 7, 9);

						time_t rawtime;
						//timesave[CopyIndex] = time(&rawtime);

						if (pan && CopyIndexFlag)
						{
							fprintf(fp, "time %lld bodycount %d\n", time(&rawtime), i);
							for (int j = 1; j < 26; j++)
								fprintf(fp, "%s%lf %lf %lf\n", pointsname[j], threecoordinate[j][0], threecoordinate[j][1], threecoordinate[j][2]);
							fprintf(fp, "\n\n");

							fprintf(tp, "time %lld bodycount %d\n", time(&rawtime), i);
							for (int j = 1; j < 26; j++)
								fprintf(tp, "%s%d %d\n", pointsname[j], twodcoordinate[j][0], twodcoordinate[j][1]);
							fprintf(tp, "\n\n");
						}
					}
				}
			}
		delete[]myBodyArr;
		myBodyFrame->Release();

		imshow("Color_Image", copy);
		//waitKey(200);

		if (pan && CopyIndexFlag)
		{
			ColorpCopy[CopyIndexC] = copy.clone();
			ColorCopy[CopyIndexC] = image_roi.clone();
			CopyIndexC++;
		}
	}
}

void Kinect::draw_color(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper, int twodcoor1, int twodcoor2)
{
	//用两个关节点来做线段的两端,并且进行状态过滤
	if (r_1.TrackingState == TrackingState_Tracked && r_2.TrackingState == TrackingState_Tracked)
	{
		ColorSpacePoint t_point;    //要把关节点用的摄像机坐标下的点转换成彩色空间的点
		Point   p_1, p_2;
		myMapper->MapCameraPointToColorSpace(r_1.Position, &t_point);
		p_1.x = t_point.X / 2 - 150;
		p_1.y = t_point.Y / 2;
		twodcoordinate[twodcoor1][0] = p_1.x;
		twodcoordinate[twodcoor1][1] = p_1.y;
		threecoordinate[twodcoor1][0] = r_1.Position.X;
		threecoordinate[twodcoor1][1] = r_1.Position.Y;
		threecoordinate[twodcoor1][2] = r_1.Position.Z;

		myMapper->MapCameraPointToColorSpace(r_2.Position, &t_point);
		p_2.x = t_point.X / 2 - 150;
		p_2.y = t_point.Y / 2;
		twodcoordinate[twodcoor2][0] = p_2.x;
		twodcoordinate[twodcoor2][1] = p_2.y;
		threecoordinate[twodcoor2][0] = r_2.Position.X;
		threecoordinate[twodcoor2][1] = r_2.Position.Y;
		threecoordinate[twodcoor2][2] = r_2.Position.Z;

		line(img, p_1, p_2, cvScalar(255, 0, 0), 5);
		circle(img, p_1, 10, cvScalar(0, 0, 255), -1);
		circle(img, p_2, 10, cvScalar(0, 0, 255), -1);

		flag_color--;
	}
}


void Kinect::draw_depth(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper)
{
	//用两个关节点来做线段的两端,并且进行状态过滤
	if (r_1.TrackingState == TrackingState_Tracked && r_2.TrackingState == TrackingState_Tracked)
	{
		DepthSpacePoint t_point;    //要把关节点用的摄像机坐标下的点转换成彩色空间的点
		Point   p_1, p_2;
		myMapper->MapCameraPointToDepthSpace(r_1.Position, &t_point);
		p_1.x = t_point.X * 1.436;
		p_1.y = t_point.Y * 1.436 - 15;
		myMapper->MapCameraPointToDepthSpace(r_2.Position, &t_point);
		p_2.x = t_point.X * 1.436;
		p_2.y = t_point.Y * 1.436 - 15;

		line(img, p_1, p_2, cvScalar(65534), 5);
		circle(img, p_1, 10, cvScalar(0), -1);
		circle(img, p_2, 10, cvScalar(0), -1);
		flag_depth--;
	}
}


  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值