本篇博客解决的主要问,获取Kinect dk中彩色图,并将彩色图放入openpose中,得到手部骨骼点。然后从kinect dk的深度图中获取每个骨骼点对应到的深度值,从而得到三维骨骼点。如下是其中遇到的问题,和对应的解决方案:
问题1:k4a::image转CV::Mat
使用cv::Mat的有参构造函数进行转化
k4a::capture capture;
cv::Mat m_colorMat;
if (m_device.get_capture(&capture)) {k4a::image m_colorImage = capture.get_color_image();cv_rgbImage_with_alpha = cv::Mat(m_colorImage.get_height_pixels(), m_colorMat.get_width_pixels(), CV_8UC4,(void *)m_colorImage.get_buffer(), cv::Mat::AUTO_STEP);
cv::imshow("color", m_colorMat);
}
问题2:CV::Mat中的RGBA转RGB
step[0]是矩阵中一行元素的字节数
step[1]是矩阵中一个元素的字节数
Openpose中想要的格式是RGB(默认相机获取的图片是可以正常识别的,参考其格式)
直接获取到的是RGBA
操作:转换Mat的图像类型
cv::cvtColor(m_colorMat, m_colorMat, cv::COLOR_BGRA2BGR); // 转换
问题3:图片输入到openpose中无法正常检测
分析原因Mat.data中的数据格式有问题
k4a::image中的数据存储用的是uint8_t,opencv里面用的是uchar,使用cv::imshow也可正常显示(问题1中的代码将k4a::image转化为cv::Mat后)
openpose的数据数据cvInputData,要求uchar format
思路:先将数据有uint_t转为uchar,再将k4a::image转化为cv::Mat
// 数据转化
std::vector<uchar> pos; // 点
int width = m_colorImage.get_width_pixels();
int height = m_colorImage.get_height_pixels();
pos.resize(width * height * 4);
auto depth = m_colorImage.get_buffer();
memcpy(pos.data(), depth, width * height * sizeof(uchar) * 4);// 得到Mat
m_colorMat= cv::Mat(m_colorImage.get_height_pixels(), m_colorImage.get_width_pixels(), CV_8UC4,(void *)pos.data(), cv::Mat::AUTO_STEP); // m_colorImage.get_buffer()
// RGBA转RGB
cv::cvtColor(m_colorMat, m_colorMat, cv::COLOR_BGRA2BGR);
std::move(pos);
结果