OpenNI1.5获取华硕XtionProLive深度图和彩色图并用OpenCV显示

华硕XtionPro类似Kinect,都是体感摄像机,可捕捉深度图和彩色图,

详细参数见:http://www.asus.com.cn/Multimedia/Xtion_PRO_LIVE/specifications/


实验设定的深度图和彩色图大小都是640*480,规格上说彩色图支持更大分辨率,实测如果将彩色图设定为更大分辨率则会自动改为320*240



彩色图



未配准时的深度图



配准到彩色图后的深度图



深度图配准到彩色图后的1:1融合图



彩色图配准到深度图后的1:1融合图


OpenNI中提供4中数据流异步机制:

(1) WaitNoneUpdateAll():不等待流的更新,这样有可能读出来的和上次是同一帧
(2) WaitAndUpdateAll():等待深度和彩色流都更新
(3) WaitAnyUpdateAll():任意流有更新则返回

(4) WaitOneUpdateAll(ProductionNode &node):等待参数指定的流更新


代码:

#include <stdlib.h>
#include <iostream>
#include <string>

//OpenCV c函数头文件
#include "opencv/cv.h"
#include "opencv/highgui.h"

//OpenCV c++函数头文件
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <XnCppWrapper.h>  //OpenNI的头文件

using namespace std;
using namespace cv;
using namespace xn; // OpenNI的命名空间


int main()
{
	XnStatus result = XN_STATUS_OK;  //OpenNI函数的返回结果
	DepthMetaData depthMD; //OpenNI深度数据
	ImageMetaData imageMD; //OpenNI彩色数据

	//c版本OpenCV
	//IplImage*  imgDepth16u=cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
	//IplImage* imgRGB8u=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//IplImage*  depthShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
	//IplImage* imageShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
	//cvNamedWindow("depth",1);
	//cvNamedWindow("image",1);

	//c++版本OpenCV
	Mat cvDepthImg, cvBGRImg, cvFusionImg;
	namedWindow("depth");
	namedWindow("RGB");
	namedWindow("fusion");

	// 创建并初始化设备上下文
	Context context; 
	result = context.Init(); 
	if (XN_STATUS_OK != result)
		cerr<<"设备上下文初始化错误"<<endl;
	

	// 创建深度生成器和彩色生成器
	DepthGenerator depthGenerator;  
	result = depthGenerator.Create( context ); 
	if (XN_STATUS_OK != result)
		cerr<<"创建深度生成器错误"<<endl;
	ImageGenerator imageGenerator;
	result = imageGenerator.Create( context ); 
	if (XN_STATUS_OK != result)
		cerr<<"创建彩色生成器错误"<<endl;

	//通过映射模式来设置生成器参数,如分辨率、帧率
	XnMapOutputMode mapMode; 
	mapMode.nXRes = 640;  
	mapMode.nYRes = 480; 
	mapMode.nFPS = 30; 
	result = depthGenerator.SetMapOutputMode( mapMode );  
	result = imageGenerator.SetMapOutputMode( mapMode );  

	// 将深度生成器的视角对齐到彩色生成器,将深度数据配准到彩色数据
	depthGenerator.GetAlternativeViewPointCap().SetViewPoint( imageGenerator ); 
	//imageGenerator.GetAlternativeViewPointCap().SetViewPoint(depthGenerator); //彩色图配准到深度图

	// 启动所有生成器,即启动数据流
	result = context.StartGeneratingAll();  
	while( true)
	{
		// 更新数据
		result = context.WaitNoneUpdateAll(); 
		if (XN_STATUS_OK == result)
		{
			//获取一帧深度图并转换为OpenCV中的图像格式
			depthGenerator.GetMetaData(depthMD); 
			Mat cvRawImg16U(depthMD.FullYRes(), depthMD.FullXRes(), CV_16UC1, (char *)depthMD.Data() );
			cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0/(depthMD.ZRes()));
			imshow("depth", cvDepthImg);

			//获取一帧彩色图并转换为OpenCV中的图像格式
			imageGenerator.GetMetaData(imageMD);
			Mat cvRGBImg(imageMD.FullYRes(), imageMD.FullXRes(), CV_8UC3, (char *)imageMD.Data());
			cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR);
			imshow("RGB", cvBGRImg);

			//融合图
			cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
			addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg);
			imshow("fusion", cvFusionImg);
			waitKey(30); //没有waitKey不显示图像

			// c函数形式
			//memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);
			//cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);
			//memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);
			//cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);
			//cvShowImage("depth", depthShow);
			//cvShowImage("image",imageShow);
		}
	}

	context.StopGeneratingAll(); //停止数据流
	context.Shutdown(); //关闭设备上下文
	destroyWindow("depth");
	destroyWindow("RGB");
	destroyWindow("fusion");

	//cvDestroyWindow("depth");
	//cvDestroyWindow("image");
	//cvReleaseImage(&imgDepth16u);
	//cvReleaseImage(&imgRGB8u);
	//cvReleaseImage(&depthShow);
	//cvReleaseImage(&imageShow);

	return 0;
}


环境配置:

华硕XtionProLive,Win7 32位系统,VS2010,OpenCV2.4.4,OpenNI1.5.2.23


源码下载:

http://download.csdn.net/detail/masikkk/7581283


OpenNI1.5 + NITE + Sensor下载:

http://download.csdn.net/detail/masikkk/7581339


参考:

Kinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像)

Kinect+OpenNI学习笔记之4(OpenNI获取的图像结合OpenCV显示)

Kinect开发教程二:OpenNI读取深度图像与彩色图像并显示

OpenNI1.5获取华硕XtionProLive深度图和彩色图并用OpenCV显示


可以使用OpenNI库中的深度图获取函数,通过遍历深度图像中的像素点,找到红色球体的像素点,然后计算这些像素点的重心坐标即可得到红色球体的重心坐标。具体实现方法可以参考以下代码: ```python import cv2 import numpy as np from primesense import openni2 # 初始化OpenNI openni2.initialize() # 打开设备 dev = openni2.Device.open_any() # 创建深度流 depth_stream = dev.create_depth_stream() # 启动深度流 depth_stream.start() # 获取深度图像 depth_frame = depth_stream.read_frame() depth_data = depth_frame.get_buffer_as_uint16() # 将深度图像转换为numpy数组 depth_array = np.ndarray((depth_frame.height, depth_frame.width), dtype=np.uint16, buffer=depth_data) # 读取RGB像 rgb_image = cv2.imread('rgb_image.jpg') # 将RGB像转换为HSV像 hsv_image = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV) # 定义红色范围 lower_red = np.array([0, 100, 100]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv_image, lower_red, upper_red) lower_red = np.array([160, 100, 100]) upper_red = np.array([179, 255, 255]) mask2 = cv2.inRange(hsv_image, lower_red, upper_red) # 合并两个掩膜 mask = mask1 + mask2 # 使用形态学操作去除噪点 kernel = np.ones((5, 5), np.uint8) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) # 找到红色球体的轮廓 contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 计算红色球体的重心坐标 if len(contours) > 0: cnt = contours[0] M = cv2.moments(cnt) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) print('红色球体的重心坐标为:(%d, %d)' % (cx, cy)) else: print('未找到红色球体!') # 停止深度流 depth_stream.stop() # 关闭设备 dev.close() # 反初始化OpenNI openni2.unload() ``` 注意:以上代码中的rgb_image.jpg是RGB像的文件名,需要根据实际情况修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值