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

使用OpenNI2打开XtionProLive时有个问题,彩色图分辨率无论如何设置始终是320*240,深度图倒是可以设成640*480,而OpenNI1.x是可以获取640*480的彩色图的。



彩色图



配准到彩色图后的深度图



1:1融合图



代码:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

#include "OpenNI.h"

using namespace openni;
using namespace cv;
using namespace std;


int main()
{
	Status rc = STATUS_OK; // OpenNI函数执行结果

	//OpenNI2图
	VideoFrameRef oniDepthImg, oniColorImg;

	//OpenCV图
	Mat cvDepthImg, cvBGRImg, cvFusionImg;

	//初始化OpenNI2
	rc = OpenNI::initialize();

	//打开Kinect或Xtion设备
	Device device;
	const char * deviceURL = openni::ANY_DEVICE;  //设备名
	rc = device.open(deviceURL);

	//创建并打开深度数据流
	VideoStream oniDepthStream; //深度数据流
	rc = oniDepthStream.create(device, SENSOR_DEPTH); //创建深度数据流
	if( STATUS_OK == rc )
	{
		//设置深度视频模式
		VideoMode modeDepth;
		modeDepth.setResolution(320,240/*640,480*/); //分辨率
		modeDepth.setFps(30); //帧率
		modeDepth.setPixelFormat(PIXEL_FORMAT_DEPTH_1_MM); //深度像素格式
		oniDepthStream.setVideoMode(modeDepth);

		oniDepthStream.start(); // 打开深度数据流
		if(STATUS_OK !=  rc)
		{
			cerr << "无法打开深度数据流:"<<OpenNI::getExtendedError()<<endl;
			oniDepthStream.destroy();
		}
	}
	else
	{
		cerr << "无法创建深度数据流:"<<OpenNI::getExtendedError()<<endl;
	}

	//创建并打开彩色数据流
	VideoStream oniColorStream;  //RGB数据流
	rc = oniColorStream.create(device, SENSOR_COLOR);
	if(STATUS_OK == rc)
	{
		//设置彩色视频模式
		VideoMode modeColor;
		//不知道为什么,彩色图的分辨率无论如何设置始终都是320*240
		modeColor.setResolution(320,240/*1280,1040*/);//分辨率
		modeColor.setFps(30);//帧率
		modeColor.setPixelFormat(PIXEL_FORMAT_RGB888);

		//设置深度图和彩色图的配准模式
		if(device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR))
		{
			device.setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR); //深度到彩色图配准
		}

		rc = oniColorStream.start(); //打开彩色数据流
		if( STATUS_OK != rc )
		{
			cerr<< "无法打开彩色数据流:"<<OpenNI::getExtendedError()<<endl;
			oniColorStream.destroy();
		}
	}
	else
	{
		cerr << "无法创建彩色数据流:"<<OpenNI::getExtendedError()<<endl;
	}

	if (!oniDepthStream.isValid() || !oniColorStream.isValid())
	{
		cerr << "彩色或深度数据流不合法"<<endl;
		OpenNI::shutdown();
		return 1;
	}

	namedWindow("depth");
	namedWindow("RGB");
	namedWindow("fusion");


	while(true)
	{
		//读取一帧深度图
		if( STATUS_OK == oniDepthStream.readFrame(&oniDepthImg) )
		{
			Mat cvRawImg16U(oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData());
			cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
			flip(cvDepthImg,cvDepthImg,1);//水平翻转
			imshow("depth", cvDepthImg);
		}

		//读取一帧彩色图
		if( STATUS_OK == oniColorStream.readFrame(&oniColorImg) )
		{
			Mat cvRGBImg(oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData());
			cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR);
			flip(cvBGRImg,cvBGRImg,1);//水平翻转
			imshow("RGB", cvBGRImg);
		}

		//融合图
		cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
		addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg);
		flip(cvFusionImg,cvFusionImg,1);//水平翻转
		imshow("fusion", cvFusionImg);

		waitKey(30);//没有waitKey不显示图像
	}

	destroyWindow("depth");
	destroyWindow("RGB");
	destroyWindow("fusion");

	oniDepthStream.destroy();
	oniColorStream.destroy();
	device.close();
	OpenNI::shutdown();

	return 0;
}


环境:

XtionProLive,Win7 32位,VS2010,OpenNI2.1.0,OpenCV2.4.4


源码下载:

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


OpenNI2.1下载:

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



参考:

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

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

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

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


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用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、付费专栏及课程。

余额充值