当前位置: 首页 > 工具软件 > ONI > 使用案例 >

使用OPENNI2来对Kinect2.0进行.ONI格式视频采集

戚建华
2023-12-01

基于前两篇博客的基础上,可以对Kinect2.0进行ONI格式的视频采集了。

采集程序如下

Status CCaptrueThread::gr_init_kinect(CString videoPath)
{
	Status xResult = STATUS_OK;
	Device device;
	const char* deviceURI = ANY_DEVICE;
	do
	{
		OpenNI::shutdown();
		xResult = OpenNI::initialize();
		if (STATUS_OK != xResult)
		{
			strLogMsg = _T("初始化环境失败,请检查环境是否安装正确");
			gr_send_log_message_to_dialog(strLogMsg);
			OpenNI::shutdown();
			return xResult;
		}
	} while (device.open(deviceURI) != STATUS_OK);
	strLogMsg = _T("初始化Kinect环境成功");
	gr_send_log_message_to_dialog(strLogMsg);
	xResult = depth.create(device, SENSOR_DEPTH);
	if (xResult != STATUS_OK)
	{
		strLogMsg = _T("创建深度生成器失败");
		gr_send_log_message_to_dialog(strLogMsg);
		depth.destroy();
		return xResult;
	}
	else
	{
		strLogMsg = _T("创建深度生成器成功");
		gr_send_log_message_to_dialog(strLogMsg);
	}

	xResult = color.create(device, SENSOR_COLOR);
	if (xResult != STATUS_OK)
	{
		strLogMsg = _T("创建RGB生成器失败");
		gr_send_log_message_to_dialog(strLogMsg);
		color.destroy();
		return xResult;
	}
	else
	{
		strLogMsg = _T("创建RGB生成器成功");
		gr_send_log_message_to_dialog(strLogMsg);
	}
	//产生数据
	gr_create_image_and_depth_data(device, videoPath);
	return xResult;
}

日志函数为

void CCaptrueThread::gr_send_log_message_to_dialog(CString& strLogMsg)
{
	::PostMessage(m_FatherHwnd, WM_WRITE_LOG, (WPARAM)strLogMsg.AllocSysString(), (LPARAM)0);
}

保存深度信息和RGB信息视频流控制程序为

void CCaptrueThread::gr_create_image_and_depth_data(Device& device, CString videoPath)
{
	xResult = color.start();
	xResult = depth.start();
	if (!depth.isValid() || !color.isValid())
	{
		strLogMsg = _T("创建RGB和深度生成器失败");
		gr_send_log_message_to_dialog(strLogMsg);
		OpenNI::shutdown();
	}
	int nFrames = 0;
	int initFrame = 0;
	BOOL bFlag = FALSE;
	BOOL bFlagDestory = TRUE;
	while (1)
	{
		if (g_bSaveBackGround)
		{

			CTime tm = CTime::GetCurrentTime();
			CString strBKNum;
			strBKNum.Format(_T("%u"), tm.GetTime());
			CString BKIMGPATH = videoPath + _T("BK\\") + strBKNum + _T(".jpg");
			BKDEPTHPATH = videoPath + _T("BK\\") + strBKNum + _T(".bmp");
			CString BKDEPTHIMGPATH = videoPath + _T("BK\\depthimg") + _T(".bmp");
			gr_save_image(BKIMGPATH, BGRImg);
			gr_save_image(BKDEPTHPATH, DepthImg);
			gr_save_image(BKDEPTHIMGPATH, DepthImg);
			g_bSaveBackGround = FALSE;
		}
		if (g_bSaveVideo)
		{
			gr_record_video(FilePath);//记录视频
			bFlag = TRUE;

			g_Section.Lock();
			g_bSaveVideo = FALSE;
			g_Section.Unlock();
			nFrames = 0;
		}
		if (bFlag)
		{
			if (nFrames < 150)
			{
				::PostMessage(m_FatherHwnd, WM_UPDATE_PROGRESSBAR, (WPARAM)nFrames, (LPARAM)0);
				nFrames++;
			}
			else
			{
				m_record.stop();
				::PostMessage(m_FatherHwnd, WM_UPDATE_PROGRESSBAR, (WPARAM)0, (LPARAM)0);
				//break;
				bFlag = FALSE;
				bFlagDestory = FALSE;
			}

		}
		if (color.readFrame(&oniColorImg) == STATUS_OK)
		{
			Mat cvRGBImg(oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData());
			cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR);
			resize(cvBGRImg, cvBGRImg, Size(512, 424));
		}
		if (depth.readFrame(&oniDepthImg) == STATUS_OK)
		{
			Mat cvRawImg16U(oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData());
			cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0 / (float(depth.getMaxPixelValue())));
		}
		//cvtColor(cvDepthImg,DepthTemp,CV_GRAY2BGR);
		BGRImg = &IplImage(cvBGRImg);
		DepthImg = &IplImage(cvDepthImg);
		if (initFrame < 100)
		{
			initFrame++;
		}
		else
		{
			if (initFrame==100)
			{
			::PostMessage(m_FatherHwnd, WM_CLICKBK, NULL, NULL);
			initFrame++;
			}
			::PostMessage(m_FatherHwnd, WM_SHOW_RGBIMG, (WPARAM)BGRImg, (LPARAM)0);
			::PostMessage(m_FatherHwnd, WM_SHOW_DEPTHIMG, (WPARAM)DepthImg, (LPARAM)1);
			Sleep(20);
		}
		if (bFlagDestory == FALSE)
		{
			m_record.destroy();
			bFlagDestory = TRUE;
			::PostMessage(m_FatherHwnd, WM_FINISH_CAPTURE, NULL, NULL);
		}
	}

	depth.destroy();
	color.destroy();
	m_record.destroy();
	device.close();
	OpenNI::shutdown();
	cvReleaseImage(&BGRImg);
	cvReleaseImage(&DepthImg);
}

定制ONI的格式的程序如下

void CCaptrueThread::gr_record_video(CString VideoName)
{
	//CString 转换为char*
	TRACE(VideoName + _T("\n"));
	CStringA VideoPathONI(VideoName);
	char* tempVideo = new char[MAX_PATH];
	memset(tempVideo, 0, MAX_PATH);
	memcpy(tempVideo, VideoPathONI.GetBuffer(0), strlen(VideoPathONI));
	m_record.create(tempVideo);
	m_record.attach(depth, TRUE);
	m_record.attach(color, TRUE);
	m_record.start();
	delete tempVideo;
	tempVideo = NULL;
}



以上代码是基于MFC的用OPENNI2驱动Kinect2.0的采集ONI格式的部分代码,不懂得可以博客联系博主。


 类似资料: