用Kinect2将人物画面抠图显示在UE4中

 

目录

一、目的

1、用Kinect2人物画面抠图显示在UE4中

二、参考

1、固始《三防知识介绍》中的体感项目

三、过程

1、运行效果:  

1、版本

1、新建工程:第三人称类型:MyKinect2Test

1、新建C++类,HUD类型,里面代码都是空的

1、从VS中运行

1、UE4中创建几个材质球:其中主要使用到了M_MatColor

1、MyHUD.h:添加内容

1、MyHUD.cpp:添加内容(里面很多的代码暂时没有理解)

1、MyKinect2Test.Build.cs:添加调用的h文件路径、lib文件路径

1、文件夹设置:添加lib文件和头文件

1、添加dll文件,到时候MyKinect2Test.Build.cs用到什么lib文件,就添加相对应的dll文件。如果少了会报“缺少模块”错误

1、MyKinect2Test.h:

1、MyKinect2Test.cpp

1、创建蓝图类:Actor类型:BP_MatPlane:显示Kinect抠图画面的plane

1、设置显示Kinect人物画面的位置

1、创建基于C++的MyHUD创建蓝图:BP_myHUD

1、设置地图 

1、UE4设置:HUD Class

 

三、注意:

1、代码中使用到了公司的Kinect库

2、创建的HUD代码中,先打开kinect、然后运行Kinect、

3、里面材质转换的代码,还在研究中,很多地方不理解

4、很多代码使用的不理解,直接借鉴参考的项目,复制其中的代码,最终实现了这个效果

5、自己再次做的时候,如果无法实现的话,一定要核对里面的细节:蓝图节点My Mat Dynamic Material、材质名字Tex001 等等


一、目的

1、用Kinect2人物画面抠图显示在UE4中

 

二、参考

1、固始《三防知识介绍》中的体感项目

 

三、过程

1、运行效果:  

①此时:人物就会在这个plane中抠出来了

 

1、版本

UE4 4.18.3 (同样的方法在UE4 4.24.3+VS2017上面,vs一直报错1)(同样的方法UE4 4.21.2+VS2015是可以的)(同样的方法UE4 4.23.1+VS2017是可以的)

VS2015

 

1、新建工程:第三人称类型:MyKinect2Test

MyKinect2Test

 

1、新建C++类,HUD类型,里面代码都是空的

 

1、从VS中运行

①点击是

 

1、UE4中创建几个材质球:其中主要使用到了M_MatColor

My_materials:文件夹

M_CamColor

M_FaceColor

M_MatColor:只设置这个

①param      

基础颜色:Tex001,纹理

 

1、MyHUD.h:添加内容

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "MyKinect2Test.h"//xzy

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "MyHUD.generated.h"

/**
 * 
 */
UCLASS()
class MYKINECT2TEST_API AMyHUD : public AHUD
{
	GENERATED_BODY()
	
public:
	// Sets default values for this pawn's properties
	AMyHUD();

public:
	virtual void DrawHUD();
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

	// Called every frame
	virtual void Tick(float DeltaTime) override;
	
public:
	static void __stdcall CallBackK2Bone(void* pDataSource, void* pClassExample);
	static void __stdcall CallBackBodyIndex(INT64 nRelativeTime, BYTE* pBuffer, void* pDataExample);
	static void __stdcall CallBackDepth(INT64 nRelativeTime, UINT16* pBuffer, USHORT nDepthMinReliableDistance, USHORT nDepthMaxDistance, void* pDataExample);
	static void __stdcall CallBackColor(INT64 nRelativeTime, BYTE* pBuffer, void* pDataExample);

	K2_BODY* pBody;
	K2_BONE_ADJUST_DATA	 pParam;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "K2Bone")
		bool isTrack;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "K2Bone")
		bool bFaceDetect;

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		int nDebug;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "XZY")
		UTexture2D* MyTex;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterial* MyMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterialInstanceDynamic* MyDynamicMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UTexture2D *MyTexture;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterial* MyFaceMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterialInstanceDynamic* MyFaceDynamicMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UTexture2D *MyFaceTexture;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterial* MyMatMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UMaterialInstanceDynamic* MyMatDynamicMaterial;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "XZY")
		UTexture2D *MyMatTexture;

};

 

1、MyHUD.cpp:添加内容(里面很多的代码暂时没有理解)

①思路:先打开kinect、然后运行Kinect、然后再Tick中不断的设置材质

①构造函数中,设置材质

 

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyHUD.h"

#include "ConstructorHelpers.h"
#include <iostream> 

//Kinect2
float g_nMinX = -0.5f;
float g_nMaxX = 0.5f;
float g_nMinZ = 0.0f;
float g_nMaxZ = 2.0f;

float g_rOffsetX = 0.0f;
float g_rOffsetY = 0.0f;
float g_rScaleX = 1.0f;
float g_rScaleY = 1.0f;

//人脸抠像区间
int g_nFacelumen = 0;
int g_nFaceWidth = 100;
int g_nFaceHeight = 100;
float g_fYaw = 20.0f;

//抠像部分数据
int g_nX = 657;
int g_nY = 0;
int g_nWidth = 706;
int g_nHeight = 1080;
int g_nLumen = 0;

//人脸的中心点
ColorSpacePoint	pColorHeadPoint = { 0,0 };

//彩色图像以及人脸对应的数据
char* pColorBodyData = nullptr;
char* pColorBodyFaceData = nullptr;

//抠像
char* pMatData = nullptr;
char* pBodyIndexData = nullptr;

bool bCToDRet = false;
DepthSpacePoint* pColorSP = new DepthSpacePoint[1920 * 1080];

//右手的坐标
float g_cRX = 0;
float g_cRY = 0;

//人脸识别
void* pFace = nullptr;

//Flash
void* pFlash = nullptr;
char fPath[255] = { 0 };


// Sets default values
AMyHUD::AMyHUD()
{
	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	struct FConstructorStatics
	{
		ConstructorHelpers::FObjectFinderOptional<UMaterial> mat;
		ConstructorHelpers::FObjectFinderOptional<UMaterial> faceMat;
		ConstructorHelpers::FObjectFinderOptional<UMaterial> matMat;
		FConstructorStatics()
			: mat(TEXT("Material'/Game/My_materials/M_CamColor.M_CamColor'")),
			faceMat(TEXT("Material'/Game/My_materials/M_FaceColor.M_FaceColor'")),
			matMat(TEXT("Material'/Game/My_materials/M_MatColor.M_MatColor'"))
		{
		}
	};
	
	static FConstructorStatics ConstructorStatics;
	MyMaterial = ConstructorStatics.mat.Get();
	MyFaceMaterial = ConstructorStatics.faceMat.Get();
	MyMatMaterial = ConstructorStatics.matMat.Get();

	MyTexture = nullptr;
	MyDynamicMaterial = nullptr;
	MyTex = nullptr;
	MyFaceTexture = nullptr;
	MyFaceDynamicMaterial = nullptr;
	MyMatTexture = nullptr;
	MyMatDynamicMaterial = nullptr;
}

void AMyHUD::BeginPlay()
{
	Super::BeginPlay();

	if (pColorBodyData == nullptr)
	{
		pColorBodyData = new char[1080 * 1920 * 4];
	}
	if (pColorBodyFaceData == nullptr)
	{
		pColorBodyFaceData = new char[g_nFaceHeight * g_nFaceWidth * 4];
	}

	if (pMatData == nullptr)
	{
		pMatData = new char[1080 * 1920 * 4];
	}
	if (pBodyIndexData == nullptr)
	{
		pBodyIndexData = new char[424 * 512];
	}

	if (MyTexture == nullptr)
	{
		MyTexture = UTexture2D::CreateTransient(g_nWidth, g_nHeight, PF_B8G8R8A8);
	}
	if (MyDynamicMaterial == nullptr)
	{
		MyDynamicMaterial = UMaterialInstanceDynamic::Create(MyMaterial, this);
	}

	if (MyFaceDynamicMaterial == nullptr)
	{
		MyFaceDynamicMaterial = UMaterialInstanceDynamic::Create(MyFaceMaterial, this);
	}

	if (MyFaceTexture == nullptr)
	{
		MyFaceTexture = UTexture2D::CreateTransient(g_nFaceWidth, g_nFaceHeight, PF_B8G8R8A8);
	}

	if (MyMatTexture == nullptr)
	{
		MyMatTexture = UTexture2D::CreateTransient(g_nWidth, g_nHeight, PF_B8G8R8A8);
	}
	if (MyMatDynamicMaterial == nullptr)
	{
		MyMatDynamicMaterial = UMaterialInstanceDynamic::Create(MyMatMaterial, this);
	}

	isTrack = false;
	if (K2Open() != true)
	{
		int a = -1;
	}

	if (K2RunBoneBind(this, CallBackK2Bone) != true)
	{

	}

	//运行Kinect
	K2Run(this, NULL, CallBackBodyIndex, CallBackDepth, CallBackColor, NULL);

}


void AMyHUD::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);

	K2Stop();
	K2StopBoneBind();
	K2Close();

	if (pColorBodyData != nullptr)
	{
		delete[] pColorBodyData;
		pColorBodyData = nullptr;
	}

	if (pColorBodyFaceData != nullptr)
	{
		delete[] pColorBodyFaceData;
		pColorBodyFaceData = nullptr;
	}

	if (pMatData != nullptr)
	{
		delete[] pMatData;
		pMatData = nullptr;
	}

	if (pBodyIndexData != nullptr)
	{
		delete[] pBodyIndexData;
		pBodyIndexData = nullptr;
	}

}

//测试02:?:扣出人物并且显示在UE4场景中
void AMyHUD::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	//fDeltaTime = DeltaTime;

	if (pColorBodyData != nullptr)
	{
		//更新抠像
		if ((g_nX + g_nWidth) > 1920 ||
			(g_nY + g_nHeight) > 1080 ||
			g_nX < 0 ||
			g_nY < 0 ||
			g_nWidth <= 0 ||
			g_nHeight <= 0 ||
			g_nWidth > 1920 ||
			g_nHeight > 1080)
		{
			return;
		}

		if (pColorBodyData != nullptr)
		{
			//显示采集的摄像头图像
			void* temp_dataPtr = MyMatTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
			for (int i = 0; i < g_nHeight; i++)
			{
				unsigned char* s = (unsigned char*)pMatData + (i + g_nY) * 1920 * 4;
				unsigned char* d = (unsigned char*)temp_dataPtr + i * g_nWidth * 4;
				for (int j = 0; j < g_nWidth; j++)
				{
					//从原图的487列往后开始数据更新到目标纹理
					d[4 * j + 0] = (s[4 * (j + g_nX) + 0] - g_nLumen) >= 0 ? (s[4 * (j + g_nX) + 0] - g_nLumen) : 0;
					d[4 * j + 1] = (s[4 * (j + g_nX) + 1] - g_nLumen) >= 0 ? (s[4 * (j + g_nX) + 1] - g_nLumen) : 0;
					d[4 * j + 2] = (s[4 * (j + g_nX) + 2] - g_nLumen) >= 0 ? (s[4 * (j + g_nX) + 2] - g_nLumen) : 0;
					d[4 * j + 3] = s[4 * (j + g_nX) + 3];
				}
			}
			MyMatTexture->PlatformData->Mips[0].BulkData.Unlock();

			MyMatTexture->UpdateResource();
			MyMatDynamicMaterial->SetTextureParameterValue(FName("Tex001"), MyMatTexture);//将MyMatTexture材质中的Text001材质,更改MyMatDynamicMaterial材质
		}
	}

}


void AMyHUD::DrawHUD()
{
	Super::DrawHUD();

}


void AMyHUD::CallBackK2Bone(void* pDataSource, void* pClassExample)
{
	AMyHUD* pClass = (AMyHUD*)pClassExample;
	K2_BONEBIND_OUT* pData = (K2_BONEBIND_OUT*)pDataSource;

	if ((pData == nullptr) || (pClass == nullptr))
	{
		pClass->isTrack = false;
		return;
	}

	K2_BONE_ADJUST_DATA* pP = pData->adjust;
	pClass->pBody = pData->body;

	for (int i = 0; i < BODY_COUNT; ++i)
	{
		if (pClass->pBody[i].trackedid == (UINT64)-1)
		{
			pClass->isTrack = false;
			continue;
		}
		if (pClass->pBody[i].joints[JointType_SpineMid].Position.Z < g_nMinZ ||
			pClass->pBody[i].joints[JointType_SpineMid].Position.Z > g_nMaxZ ||
			pClass->pBody[i].joints[JointType_SpineMid].Position.X > g_nMaxX ||
			pClass->pBody[i].joints[JointType_SpineMid].Position.X < g_nMinX)
		{
			pClass->isTrack = false;
			continue;
		}
		if (pClass->pBody[i].joints[JointType_SpineMid].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_SpineShoulder].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_ShoulderLeft].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_ShoulderRight].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_Neck].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_Head].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_KneeLeft].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_KneeRight].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_AnkleLeft].TrackingState != TrackingState_Tracked ||
			pClass->pBody[i].joints[JointType_AnkleRight].TrackingState != TrackingState_Tracked)
		{
			pClass->isTrack = false;
			continue;
		}

		if (pClass->pBody[i].joints[JointType_SpineMid].Position.Z <= g_nMaxZ &&
			pClass->pBody[i].joints[JointType_SpineMid].Position.Z >= g_nMinZ &&
			pClass->pBody[i].joints[JointType_SpineMid].Position.X >= g_nMinX &&
			pClass->pBody[i].joints[JointType_SpineMid].Position.X <= g_nMaxX)
		{
			//tDeltaSum = 0.0f;
			pClass->isTrack = true;
			//memcpy_s(pColorBodyData, 1080 * 1920 * 4, pData->color, 1080 * 1920 * 4);
			memcpy_s(&(pClass->pParam), sizeof(K2_BONE_ADJUST_DATA), &(pP[i]), sizeof(K2_BONE_ADJUST_DATA));
			g_cRX = pClass->pBody[i].colorpoints[JointType_HandRight].X / 1920.0f * 1080.0f * g_rScaleX + g_rOffsetX;
			g_cRY = pClass->pBody[i].colorpoints[JointType_HandRight].Y / 1080.0f * 1920.0f * g_rScaleY + g_rOffsetY;
			memcpy_s(&(pColorHeadPoint), sizeof(ColorSpacePoint), &(pClass->pBody[i].colorpoints[JointType_Head]), sizeof(ColorSpacePoint));

//			if (m_nGameStatus == GAME_STATUS::game_wait)
//			{
//				//待机
//				m_nGameStatus = GAME_STATUS::game_count;
//
//				if (pFlash != NULL)
//				{
//					FastFlashPostMouseKeyMessage(pFlash, 0x0100, 32, 0);
//					Sleep(100);//单位秒
//				}
//			}
//			else if (m_nGameStatus == GAME_STATUS::game_count)
//			{
//				//倒计时
//
//			}
//			else if (m_nGameStatus == GAME_STATUS::game_select || m_nGameStatus == GAME_STATUS::game_run)
//			{
//				if (g_cRX >= 0 && g_cRX <= 1080 &&
//					g_cRY >= 0 && g_cRY <= 1920)
//				{
//					if (pFlash != NULL)
//					{
//						FastFlashMCMove(pFlash, "hand_mc", g_cRX, g_cRY);
//					}
//				}
//			}
//			break;


		}

		//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("height= %f"), height));
	}
}


void AMyHUD::CallBackBodyIndex(INT64 nRelativeTime, BYTE* pBuffer, void* pDataExample)
{
	if (pBuffer != nullptr)
	{
		unsigned int len = 512 * 424 * 1;
		memcpy_s(pBodyIndexData, len, pBuffer, len);
	}
}

void AMyHUD::CallBackDepth(INT64 nRelativeTime, UINT16* pBuffer, USHORT nDepthMinReliableDistance, USHORT nDepthMaxDistance, void* pDataExample)
{
	if (pBuffer != nullptr)
	{
		UINT depthCount = 512 * 424;
		UINT colorCount = 1920 * 1080;
		bCToDRet = K2ColorToDepth(depthCount, pBuffer, colorCount, pColorSP);
	}
}


void AMyHUD::CallBackColor(INT64 nRelativeTime, BYTE* pBuffer, void* pDataExample)
{
	if (pBuffer != nullptr)
	{
		unsigned int len = 1080 * 1920 * 4;
		memcpy_s(pColorBodyData, len, pBuffer, len);

		if (bCToDRet && pColorSP != nullptr)
		{
			int colorIndex = 0;
			for (unsigned int i = 0; i < 1080; i++)
			{
				char* pSrc = pColorBodyData + i * 1920 * 4;
				char* pDst = pMatData + i * 1920 * 4;
				for (unsigned int j = 0; j < 1920; j++)
				{
					DepthSpacePoint p = pColorSP[colorIndex++];

					// Values that are negative infinity means it is an invalid color to depth mapping so we
					// skip processing for this pixel
					if (p.X != -std::numeric_limits<float>::infinity() && p.Y != -std::numeric_limits<float>::infinity())
					{
						int depthX = static_cast<int>(p.X + 0.5f);
						int depthY = static_cast<int>(p.Y + 0.5f);

						if ((depthX >= 0 && depthX < 512) && (depthY >= 0 && depthY < 424))
						{
							BYTE player = pBodyIndexData[depthX + (depthY * 512)];
							// if we're tracking a player for the current pixel, draw from the color camera
							if (player != 0xff)
							{
								// set source for copy to the color pixel
								pDst[j * 4 + 0] = pSrc[j * 4 + 0];
								pDst[j * 4 + 1] = pSrc[j * 4 + 1];
								pDst[j * 4 + 2] = pSrc[j * 4 + 2];
								pDst[j * 4 + 3] = pSrc[j * 4 + 3];
							}
							else
							{
								// set source for copy to the color pixel
								pDst[j * 4 + 0] = 0x00;
								pDst[j * 4 + 1] = 0x00;
								pDst[j * 4 + 2] = 0x00;
								pDst[j * 4 + 3] = 0x00;
							}
						}
					}
					else
					{
						// set source for copy to the color pixel
						pDst[j * 4 + 0] = 0x00;
						pDst[j * 4 + 1] = 0x00;
						pDst[j * 4 + 2] = 0x00;
						pDst[j * 4 + 3] = 0x00;
					}
				}
			}
		}
	}
}


 

1、MyKinect2Test.Build.cs:添加调用的h文件路径、lib文件路径

// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;
using System.IO;

public class VirtualDressMirror : ModuleRules
{
    private string ModulePath
    {
        get { return ModuleDirectory; }
    }
   
    public VirtualDressMirror(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
        //Fast
        PublicIncludePaths.Add(Path.Combine(ModulePath, "../../ThirdParty/Fast/include"));
        PublicAdditionalLibraries.Add(Path.Combine(ModulePath, "../../ThirdParty/Fast/lib/Fast_Config.lib"));
        PublicAdditionalLibraries.Add(Path.Combine(ModulePath, "../../ThirdParty/Fast/lib/Fast_Flash.lib"));
        PublicAdditionalLibraries.Add(Path.Combine(ModulePath, "../../ThirdParty/Fast/lib/FastFaceDetect.lib"));

        //TKinect2.0
        PublicIncludePaths.Add(Path.Combine(ModulePath, "../../ThirdParty/Kinect2"));
        PublicAdditionalLibraries.Add(Path.Combine(ModulePath, "../../ThirdParty/Kinect2/K2.lib"));
    }
}

 

1、文件夹设置:添加lib文件和头文件

 

1、添加dll文件,到时候MyKinect2Test.Build.cs用到什么lib文件,就添加相对应的dll文件。如果少了会报“缺少模块”错误

 

1、MyKinect2Test.h:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"


#include "AllowWindowsPlatformTypes.h"
#include <windows.h>
#include "HideWindowsPlatformTypes.h"

//Kinect2
#include "../../ThirdParty/Kinect2/K2.h"
#include "../../ThirdParty/Kinect2/K2Matting.h"
#include "../../ThirdParty/Kinect2/K2Bone.h"
#include "../../ThirdParty/Kinect2/K2Face.h"

#define	K2Vec32FVector(v)					FVector((v).x, (v).y, (v).z)
#define	FVector2K2Vec3(v)					K2Vec3((v).X, (v).Y, (v).Z)

#define	K2Quat2FQuat(q)						FQuat((q).x, (q).y, (q).z, (q).w)
#define	FQuat2K2Quat(q)						K2Quat((q).X, (q).Y, (q).Z, (q).W)
#define	K2Quat2FRotator(q)					FRotator(K2Quat2FQuat(q))
#define	FRotator2K2Quat(r)					FQuat2K2Quat(FQuat(r))

// UE与Kinect2坐标系转换
FVector WINAPI K2Coordinate2UECoordinate(FVector k2v);
FQuat WINAPI K2Coordinate2UECoordinate(FQuat k2q);
FVector WINAPI UECoordinate2K2Coordinate(FVector uev);
FQuat WINAPI UECoordinate2K2Coordinate(FQuat ueq);

 

1、MyKinect2Test.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyKinect2Test.h"
#include "Modules/ModuleManager.h"

IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, MyKinect2Test, "MyKinect2Test" );

//xzy
FVector WINAPI K2Coordinate2UECoordinate(FVector k2v)
{
	return FVector(k2v.X, -k2v.Z, k2v.Y);
}

FQuat WINAPI K2Coordinate2UECoordinate(FQuat k2q)
{
	float angle;
	FVector axis;
	k2q.ToAxisAndAngle(axis, angle);
	axis = K2Coordinate2UECoordinate(axis);
	return FQuat(axis, angle);
}

FVector WINAPI UECoordinate2K2Coordinate(FVector uev)
{
	return FVector(uev.X, uev.Z, -uev.Y);
}

FQuat WINAPI UECoordinate2K2Coordinate(FQuat ueq)
{
	float angle;
	FVector axis;
	ueq.ToAxisAndAngle(axis, angle);
	axis = UECoordinate2K2Coordinate(axis);
	return FQuat(axis, angle);
}

1、创建蓝图类:Actor类型:BP_MatPlane:显示Kinect抠图画面的plane

 

1、设置显示Kinect人物画面的位置

 

1、创建基于C++的MyHUD创建蓝图:BP_myHUD

 ①因为C++的MyHUD类的构造函数中:直接找到了这三个材质球

①创建变量: pBPMatPlane,让其显示体感画面,因为BP_MatPlane里的plane材质会在代码中不断修改获得Kinect的人物抠图画面

 

 

①初始化:获得这个组件、Tick里面不断的刷新组件材质

 

1、设置地图 

①想在什么场景中显示,需要进行设置

 

1、UE4设置:HUD Class

①如果没有自定义的GameMode,那么自定义一个,目的是让游戏类型的HUDClass设置为自己创建的HUD

 

 

 

三、注意:

1、代码中使用到了公司的Kinect库

 

2、创建的HUD代码中,先打开kinect、然后运行Kinect、

 

3、里面材质转换的代码,还在研究中,很多地方不理解

 

4、很多代码使用的不理解,直接借鉴参考的项目,复制其中的代码,最终实现了这个效果

 

5、自己再次做的时候,如果无法实现的话,一定要核对里面的细节:蓝图节点My Mat Dynamic Material、材质名字Tex001 等等

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值