1. kinect2 深度图与彩色图对齐
IDepthFrame*frame1;
hResult = depthreader->AcquireLatestFrame(&frame1);
Mat depth_16bit(424, 512, CV_16UC1);
Mat color(height, width, CV_8UC4);
Mat coordinateMapperMat(height_d, width_d, CV_8UC4);
if (SUCCEEDED(hResult))
{
ICoordinateMapper* pCoordinateMapper;
kinect->get_CoordinateMapper(&pCoordinateMapper);
hResult = pCoordinateMapper->MapDepthFrameToColorSpace(width_d * height_d, reinterpret_cast(depth_16bit.data), width_d * height_d, &MappingMatrix[0]);
}
if (SUCCEEDED(hResult))
{
coordinateMapperMat = cv::Scalar(0, 0, 0, 0);
for (int y = 0; y < height_d; y++)
{
for (int x = 0; x < width_d; x++)
{
unsigned int index = y * width_d + x;
ColorSpacePoint point = MappingMatrix[index];
int colorX = static_cast<int>(std::floor(point.X + 0.5));
int colorY = static_cast<int>(std::floor(point.Y + 0.5));
if ((colorX >= 0) && (colorX < width) && (colorY >= 0) && (colorY < height))
{
coordinateMapperMat.at(y, x) = color.at(colorY, colorX);
}
}
}
}
2. 根据深度图计算框选区域三维坐标
vector<double> getxyz(int u, int v, Mat depth_16bit, vector<double> params)
{
int camera_factor = params[0];
double cx = params[1];
double cy = params[2];
double fx = params[3];
double fy = params[4];
double z = depth_16bit.at<short>(u, v)/camera_factor;
double x = (u - cx) * z / fx;
double y = (v - cy) * z / fy;
vector<double> xyz;
xyz.push_back(x);
xyz.push_back(y);
xyz.push_back(z);
return xyz;
}
3. 交互功能如下
操作 |
功能 |
“s” |
保存当前帧彩色图 |
鼠标 |
框选区域(左上角按鼠标左键,拖到右下角松开) |
4. 完整代码
#include "stdafx.h"
#include
#include
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include
#pragma comment ( lib, "kinect20.lib" )
using namespace cv;
using namespace std;
Rect select1 = Rect(0,0,0,0);
bool tracking = false;
vector<double> params(5);
Mat depth_16bit(424, 512, CV_16UC1);
Mat depth(424, 512, CV_8UC1);
vector<double> getxyz(int u, int v, Mat depth_16bit, vector<double> params)
{
int camera_factor = params[0];
double cx = params[1];
double cy = params[2];
double fx = params[3];
double fy = params[4];
double z = depth_16bit.at<short>(u, v)/camera_factor;
double x = (u - cx) * z / fx;
double y = (v - cy) * z / fy;
vector<double> xyz;
xyz.push_back(x);
xyz.push_back(y);
xyz.push_back(z);
return xyz;
}
void onMouse(int event,int x,int y,int,void*)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
select1.x=x;
select1.y=y;
tracking=false;
}
else if(event==CV_EVENT_LBUTTONUP)
{
select1.width=x-select1.x;
select1.height=y-select1.y;
tracking=true;
int u = select1.x + 0.5 * select1.width;
int v = select1.y + 0.5 * select1.height;
vector<double> xyz = getxyz(v, u, depth_16bit, params);
cout << "3d position of the selected pixel: [" << xyz[0] << " " << xyz[1] << " " << xyz[2] << "]" << endl;
}
}
int main()
{
params[0] = 1000;
params[1] = 0.9677*1e3;
params[2] = 0.5423*1e3;
params[3] = 1.0634*1e3;
params[4] = 1.0634*1e3;
HRESULT hResult = S_OK;
IKinectSensor *kinect;
GetDefaultKinectSensor(&kinect);
kinect->Open();
IColorFrameSource *colorsource;
IColorFrameReader *colorreader;
IFrameDescription *colorde;
kinect->get_ColorFrameSource(&colorsource);
colorsource->OpenReader(&colorreader);
colorsource->get_FrameDescription(&colorde);
IDepthFrameSource *depthrsource;
IDepthFrameReader *depthreader;
IFrameDescription *depthde;
kinect->get_DepthFrameSource(&depthrsource);
depthrsource->OpenReader(&depthreader);
depthrsource->get_FrameDescription(&depthde);
int width = 0;
int height = 0;
colorde->get_Height(&height);
colorde->get_Width(&width);
Mat color(height, width, CV_8UC4);
namedWindow("color");
int width_d = 0;
int height_d = 0;
depthde->get_Height(&height_d);
depthde->get_Width(&width_d);
UINT16 *data = new UINT16[width_d*height_d];
cout << "color picture size:" << width << "x" << height << endl;
cout << "depth picture size:" << width_d << "x" << height_d << endl;
vector MappingMatrix(width_d * height_d);
Mat coordinateMapperMat(height_d, width_d, CV_8UC4);
namedWindow("Map color");
setMouseCallback("Map color", onMouse, 0);
int num = 1;
while (1)
{
IColorFrame*frame;
hResult = colorreader->AcquireLatestFrame(&frame);
if (SUCCEEDED(hResult))
{
frame->CopyConvertedFrameDataToArray(height*width * 4,
reinterpret_cast(color.data), ColorImageFormat::ColorImageFormat_Bgra);
}
if (frame != NULL)
{
frame->Release();
frame = NULL;
}
if (waitKey(30) == VK_ESCAPE)
break;
cv::imshow("color", color);
stringstream ss;
ss << num << ".jpg";
if (waitKey(100)==115)
{
cv::imwrite(ss.str(), color);
cout<" saved."<
5.参考
- Opencv+Kinect2.0 的环境配置和获取彩色图
- Opencv+Kinect2.0获取景深图
- 一起做RGB-D SLAM (2) 第二讲 从图像到点云