KinectV2 installation tutorial : https://blog.csdn.net/weixin_44414948/article/details/112346307
OpenCV installation and configuration tutorial : https://blog.csdn.net/weixin_44414948/article/details/112382735
Demo goal
Use the C++ interface provided by KinectV2 to write code to obtain real-time color images and display the corresponding human skeleton.
First upload the complete C++ code (readers who do not configure KinectV2, opencv's C++ link library, can see the link library configuration tutorial below):
#include <iostream>
#include <opencv2\imgproc.hpp> //opencv头文件
#include <opencv2\calib3d.hpp>
#include <opencv2\highgui.hpp>
#include <Kinect.h> //Kinect头文件
using namespace std;
using namespace cv;
void draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper);
void kinect_sk();
int main(void)
{
kinect_sk();
return 0;
}
void draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper)
{
//用两个关节点来做线段的两端,并且进行状态过滤
if (r_1.TrackingState == TrackingState_Tracked && r_2.TrackingState == TrackingState_Tracked)
{
ColorSpacePoint t_point; //要把关节点用的摄像机坐标下的点转换成彩色空间的点
Point p_1, p_2;
myMapper->MapCameraPointToColorSpace(r_1.Position, &t_point);
p_1.x = t_point.X;
p_1.y = t_point.Y;
myMapper->MapCameraPointToColorSpace(r_2.Position, &t_point);
p_2.x = t_point.X;
p_2.y = t_point.Y;
line(img, p_1, p_2, Vec3b(0, 255, 0), 5);
circle(img, p_1, 10, Vec3b(255, 0, 0), -1);
circle(img, p_2, 10, Vec3b(255, 0, 0), -1);
}
}
void kinect_sk()
{
IKinectSensor * mySensor = nullptr;
GetDefaultKinectSensor(&mySensor);
mySensor->Open();
IColorFrameSource * myColorSource = nullptr;
mySensor->get_ColorFrameSource(&myColorSource);
IColorFrameReader * myColorReader = nullptr;
myColorSource->OpenReader(&myColorReader);
int colorHeight = 0, colorWidth = 0;
IFrameDescription * myDescription = nullptr;
myColorSource->get_FrameDescription(&myDescription);
myDescription->get_Height(&colorHeight);
myDescription->get_Width(&colorWidth);
IColorFrame * myColorFrame = nullptr;
Mat original(colorHeight, colorWidth, CV_8UC4);
//**********************以上为ColorFrame的读取前准备**************************
IBodyFrameSource * myBodySource = nullptr;
mySensor->get_BodyFrameSource(&myBodySource);
IBodyFrameReader * myBodyReader = nullptr;
myBodySource->OpenReader(&myBodyReader);
int myBodyCount = 0;
myBodySource->get_BodyCount(&myBodyCount);
IBodyFrame * myBodyFrame = nullptr;
ICoordinateMapper * myMapper = nullptr;
mySensor->get_CoordinateMapper(&myMapper);
//**********************以上为BodyFrame以及Mapper的准备***********************
while (1)
{
while (myColorReader->AcquireLatestFrame(&myColorFrame) != S_OK);
myColorFrame->CopyConvertedFrameDataToArray(colorHeight * colorWidth * 4, original.data, ColorImageFormat_Bgra);
Mat copy = original.clone(); //读取彩色图像并输出到矩阵
while (myBodyReader->AcquireLatestFrame(&myBodyFrame) != S_OK); //读取身体图像
IBody ** myBodyArr = new IBody *[myBodyCount]; //为存身体数据的数组做准备
for (int i = 0; i < myBodyCount; i++)
myBodyArr[i] = nullptr;
if (myBodyFrame->GetAndRefreshBodyData(myBodyCount, myBodyArr) == S_OK) //把身体数据输入数组
for (int i = 0; i < myBodyCount; i++)
{
BOOLEAN result = true;
if (myBodyArr[i]->get_IsTracked(&result) == S_OK && result) //先判断是否侦测到
{
//cout << "Detection is work!" << endl;
Joint myJointArr[JointType_Count];
if (myBodyArr[i]->GetJoints(JointType_Count, myJointArr) == S_OK) //如果侦测到就把关节数据输入到数组并画图
{
draw(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper);
draw(copy, myJointArr[JointType_Neck], myJointArr[JointType_SpineShoulder], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderLeft], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_SpineMid], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderRight], myMapper);
draw(copy, myJointArr[JointType_ShoulderLeft], myJointArr[JointType_ElbowLeft], myMapper);
draw(copy, myJointArr[JointType_SpineMid], myJointArr[JointType_SpineBase], myMapper);
draw(copy, myJointArr[JointType_ShoulderRight], myJointArr[JointType_ElbowRight], myMapper);
draw(copy, myJointArr[JointType_ElbowLeft], myJointArr[JointType_WristLeft], myMapper);
draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipLeft], myMapper);
draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipRight], myMapper);
draw(copy, myJointArr[JointType_ElbowRight], myJointArr[JointType_WristRight], myMapper);
draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_ThumbLeft], myMapper);
draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_HandLeft], myMapper);
draw(copy, myJointArr[JointType_HipLeft], myJointArr[JointType_KneeLeft], myMapper);
draw(copy, myJointArr[JointType_HipRight], myJointArr[JointType_KneeRight], myMapper);
draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_ThumbRight], myMapper);
draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_HandRight], myMapper);
draw(copy, myJointArr[JointType_HandLeft], myJointArr[JointType_HandTipLeft], myMapper);
draw(copy, myJointArr[JointType_KneeLeft], myJointArr[JointType_FootLeft], myMapper);
draw(copy, myJointArr[JointType_KneeRight], myJointArr[JointType_FootRight], myMapper);
draw(copy, myJointArr[JointType_HandRight], myJointArr[JointType_HandTipRight], myMapper);
}
}
}
delete[]myBodyArr;
myBodyFrame->Release();
myColorFrame->Release();
imshow("TEST", copy);
if (waitKey(30) == VK_ESCAPE)
break;
}
myMapper->Release();
myDescription->Release();
myColorReader->Release();
myColorSource->Release();
myBodyReader->Release();
myBodySource->Release();
mySensor->Close();
mySensor->Release();
cv::destroyAllWindows();
}
running result:
KinectV2, OpenCV C++ link library configuration:
We chose to set up the property manager file in vs2015, and after configuring it, we will throw it directly into Release/x64 when we use it next time, once and for all.
1. Find the property manager of vs2015, as shown in the figure below.
2. Add a new project attribute table in Release/x64 (Note: I am in the release mode, if the reader is debug, choose the corresponding debug).
3. Name it whatever you want. For convenience, I named it Kinect-cv. The following are the detailed setting steps:
3.1. Set the include directory and library directory under the vc++ directory. The following figure shows my include directory, library directory, readers Just change to your own OpenCV corresponding path.
If OpenCV is installed directly in the root directory of C drive, the include directory is:
C:\opencv\build\include\opencv
C:\opencv\build\include\opencv2
C:\opencv\build\include
If OpenCV is installed directly in the root directory of
C drive , the library directory is: C:\opencv\build\x64\vc14\lib
3.2. Set c/c++ | General | Additional include directory, the setting content is as follows (if Kinect SDK2.0 is installed by default, you can set it as mine, if it is not the default, you need to change to the corresponding path).
3.3. Set the linker|General|Additional library directory (if Kinect SDK2.0 is installed by default, it can be set as mine, if it is not the default, you need to change to the corresponding path).
3.4. Set the linker | input | additional dependencies, set according to the version number of OpenCV and KinectSDK (I am OpenCV3.4, Kinect20.lib remains the same).
Here is an explanation : opencv_world340.lib and opencv_world340d.lib are static link files called in Release and Debug modes respectively. In order to prevent switching modes, add both to him, and then add this kinect under both Release and Debug property managers. -cv project properties file.
4. So far, all the C++ link libraries have been configured. In order to facilitate the next use, you can directly add the existing project property sheet Kinect-cv in the property manager of the latest project.