Kinect V2深度数据用OpenCV显示

20 篇文章 0 订阅
18 篇文章 3 订阅

持续维护地址:http://guoming.me/kinect2-depth-opencv

这次带来Kinect for windows v2深度数据的显示~

总感觉微软的Kinect API越来越复杂了呢,为什么获取深度数据后,不能直接返回一个结构体啊。每次要调这么多函数获取一个一个小参数变量,难过


代码在前,运行截图在后:

// DepthBasic-OpenCV.cpp : 定义控制台应用程序的入口点。
/****************************************************
程序功能:Kinect V2深度数据用OpenCV显示
开发环境:win32控制台应用程序 x86程序 (程序类型)
		VisualStudio 2012 (开发工具)
		OpenCV2.4.10 (显示界面库 vc11库, http://guoming.me/opencv)
		KinectSDK-v2.0-PublicPreview1409-Setup (Kinect SDK驱动版本, http://guoming.me/kinect2)
		Windows 8.1 (操作系统)
博客文章:http://guoming.me/kinect2-depth-opencv
代码地址:https://github.com/guoming0000/KinectV2/tree/master/DepthBasic-OpenCV

开发人员:小明
开发时间:2014-10-20~ 2014-10-21
联系方式:	i@guoming.me (邮箱,推荐联系方式)
		http://guoming.me (网站,体感资讯和知识汇总)
		http://weibo.com/guoming0000 (新浪微博,用于发布体感等科技资讯,请勿私信)
******************************************************/
#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <windows.h>
#include <Kinect.h>// Kinect Header files
using namespace cv;
// Safe release for interfaces
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;
	Kinect();
	~Kinect();
	HRESULT					InitKinect();//初始化Kinect
	void					Update();//更新数据
	void					ProcessDepth(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth);//处理得到的数据
private:
	
	IKinectSensor*          m_pKinectSensor;// Current Kinect
	IDepthFrameReader*      m_pDepthFrameReader;// Color reader
	RGBQUAD*                m_pDepthRGBX;

};

//主函数
int main()
{
	Kinect kinect;
	kinect.InitKinect();
	while(1)
	{
		kinect.Update();
		if(waitKey(1) >= 0)//按下任意键退出
		{
			break;
		}
	}

	return 0;
}

Kinect::Kinect()
{
	m_pKinectSensor = NULL;
	m_pDepthFrameReader = NULL;
	
	m_pDepthRGBX = new RGBQUAD[cDepthWidth * cDepthHeight];// create heap storage for color pixel data in RGBX format
}

Kinect::~Kinect()
{
	if (m_pDepthRGBX)
	{
		delete [] m_pDepthRGBX;
		m_pDepthRGBX = NULL;
	}

	SafeRelease(m_pDepthFrameReader);// done with color frame reader
	
	if (m_pKinectSensor)
	{
		m_pKinectSensor->Close();// close the Kinect Sensor
	}
	SafeRelease(m_pKinectSensor);
}

HRESULT	Kinect::InitKinect()
{
	HRESULT hr;

	hr = GetDefaultKinectSensor(&m_pKinectSensor);
	if (FAILED(hr))
	{
		return hr;
	}

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

		hr = m_pKinectSensor->Open();

		if (SUCCEEDED(hr))
		{
			hr = m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
		}

		if (SUCCEEDED(hr))
		{
			hr = pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
		}

		SafeRelease(pDepthFrameSource);
	}

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

	return hr;
}

void Kinect::Update()
{
	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;

		if (SUCCEEDED(hr))
		{
			hr = pDepthFrame->get_FrameDescription(&pFrameDescription);
		}

		if (SUCCEEDED(hr))
		{
			hr = pFrameDescription->get_Width(&nWidth);
		}

		if (SUCCEEDED(hr))
		{
			hr = pFrameDescription->get_Height(&nHeight);
		}

		if (SUCCEEDED(hr))
		{
			hr = pDepthFrame->get_DepthMinReliableDistance(&nDepthMinReliableDistance);
		}

		if (SUCCEEDED(hr))
		{
			// 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);
		}

		if (SUCCEEDED(hr))
		{
			hr = pDepthFrame->AccessUnderlyingBuffer(&nBufferSize, &pBuffer);            
		}

		if (SUCCEEDED(hr))
		{
			ProcessDepth( pBuffer, nWidth, nHeight, nDepthMinReliableDistance, nDepthMaxDistance);
		}

		SafeRelease(pFrameDescription);
	}

	SafeRelease(pDepthFrame);
}

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))
	{
		RGBQUAD* pRGBX = m_pDepthRGBX;

		// end pixel is start + width*height - 1
		const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);

		while (pBuffer < pBufferEnd)
		{
			USHORT depth = *pBuffer;

			// To convert to a byte, we're discarding the most-significant
			// rather than least-significant bits.
			// We're preserving detail, although the intensity will "wrap."
			// Values outside the reliable depth range are mapped to 0 (black).

			// Note: Using conditionals in this loop could degrade performance.
			// Consider using a lookup table instead when writing production code.
			BYTE intensity = static_cast<BYTE>((depth >= nMinDepth) && (depth <= nMaxDepth) ? (depth % 256) : 0);

			pRGBX->rgbRed   = intensity;
			pRGBX->rgbGreen = intensity;
			pRGBX->rgbBlue  = intensity;

			++pRGBX;
			++pBuffer;
		}
			
		// Draw the data with OpenCV
		Mat DepthImage(nHeight, nWidth, CV_8UC4, m_pDepthRGBX);
		Mat show = DepthImage.clone();
		imshow("DepthImage", show);
	}
}


要在Python中调用Kinect v2,你可以使用Microsoft提供的官方软件开发包(SDK)。以下是使用Kinect v2的一些基本步骤: 1. 安装Kinect v2 SDK:从Microsoft官方网站下载并安装Kinect v2 SDK。确保选择与您的操作系统兼容的版本。 2. 连接Kinect v2设备:将Kinect v2传感器通过USB连接到计算机。 3. 导入必要的库:在Python脚本中导入必要的库,包括`pykinect2`和`PyQt5`等。 4. 初始化Kinect v2:使用SDK提供的方法初始化Kinect v2,并获取传感器对象。 5. 获取数据:使用传感器对象获取所需的数据,例如深度图像、彩色图像或骨骼跟踪数据。 6. 处理数据:根据您的需求,对获取的数据进行处理和分析。例如,您可以使用OpenCV库来处理图像,或者使用其他库来分析骨骼跟踪数据。 以下是一个简单的Python示例代码,用于初始化Kinect v2并获取彩色图像: ```python import ctypes import _ctypes import sys import os import numpy as np from pykinect2 import PyKinectV2 from pykinect2.PyKinectV2 import * from pykinect2 import PyKinectRuntime if sys.hexversion >= 0x03000000: import _thread as thread else: import thread class KinectRuntime(object): def __init__(self): self.kinect = None def close(self): if self.kinect is not None: self.kinect.close() self.kinect = None def run(self): self.kinect = PyKinectRuntime.PyKinectRuntime(PyKinectV2.FrameSourceTypes_Color) while not self.kinect.has_new_color_frame(): continue # 获取彩色图像帧 frame = self.kinect.get_last_color_frame() # 将帧数据转换为numpy数组 frame_data = np.array(frame.reshape((self.kinect.color_frame_desc.Height, self.kinect.color_frame_desc.Width, 4)), dtype=np.uint8) # 处理图像数据,例如显示或保存图像 # 释放帧数据 self.kinect.release_frame(frame) if __name__ == '__main__': kinect = KinectRuntime() kinect.run() ``` 这只是一个简单的示例,您可以根据您的需求进行更复杂的处理和分析。请注意,此示例仅获取并处理彩色图像。要获取其他类型的数据(如深度图像或骨骼跟踪数据),您需要修改代码。 希望这对您有所帮助!
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值