基于前两篇博客的基础上,可以对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格式的部分代码,不懂得可以博客联系博主。