C++ 从三维kinect模型中提取人脸
我正在使用Kinect创建一个人的3D模型。我得到的是这样的东西:C++ 从三维kinect模型中提取人脸,c++,3d,kinect,C++,3d,Kinect,我正在使用Kinect创建一个人的3D模型。我得到的是这样的东西: 我将其导出到Wavefront.obj文件。但我只对脸本身感兴趣,我想去掉它周围的一切。由于Kinect有一个RGB摄像头,我可以在RGB中进行人脸检测,没有问题。但这给了我一个包含人脸的640x480图像内的矩形,我如何将其转换为3D网格 不久前我也做过类似的事情: 录像带 我所做的很简单: 使用OpenCV的haar级联检测RGB图像中的人脸 使用检测到的面矩形仅从深度图像裁剪面区域 将深度图像转换为深度值(3d点云/网
我将其导出到Wavefront.obj文件。但我只对脸本身感兴趣,我想去掉它周围的一切。由于Kinect有一个RGB摄像头,我可以在RGB中进行人脸检测,没有问题。但这给了我一个包含人脸的640x480图像内的矩形,我如何将其转换为3D网格 不久前我也做过类似的事情: 录像带 我所做的很简单:
这是我用来获取Depthstream并用Fusion处理它的代码:
void processDepth()
{
NUI_IMAGE_FRAME depthFrame = { 0 };
ERROR_CHECK( kinect->NuiImageStreamGetNextFrame( depthStreamHandle, 0, &depthFrame ) );
BOOL nearMode = FALSE;
INuiFrameTexture *frameTexture = 0;
kinect->NuiImageFrameGetDepthImagePixelFrameTexture( depthStreamHandle, &depthFrame, &nearMode, &frameTexture );
NUI_LOCKED_RECT depthData = { 0 };
frameTexture->LockRect( 0, &depthData, 0, 0 );
if ( depthData.Pitch == 0 ) {
std::cout << "zero" << std::endl;
}
processKinectFusion( (NUI_DEPTH_IMAGE_PIXEL*)depthData.pBits, depthData.size);
ERROR_CHECK( kinect->NuiImageStreamReleaseFrame( depthStreamHandle, &depthFrame ) );
}
void processKinectFusion( const NUI_DEPTH_IMAGE_PIXEL* depthPixel, int depthPixelSize)
{
// DepthImagePixel
HRESULT hr = ::NuiFusionDepthToDepthFloatFrame( depthPixel, width, height, m_pDepthFloatImage,
NUI_FUSION_DEFAULT_MINIMUM_DEPTH, NUI_FUSION_DEFAULT_MAXIMUM_DEPTH, TRUE );
if (FAILED(hr)) {
throw std::runtime_error( "::NuiFusionDepthToDepthFloatFrame failed." );
}
Matrix4 worldToBGRTransform = { 0.0f };
worldToBGRTransform.M11 = 256 / 512;
worldToBGRTransform.M22 = 256 / 384;
worldToBGRTransform.M33 = 256 / 512;
worldToBGRTransform.M41 = 0.5f;
worldToBGRTransform.M42 = 0.5f;
worldToBGRTransform.M44 = 1.0f;
Matrix4 worldToCameraTransform;
m_pVolume->GetCurrentWorldToCameraTransform( &worldToCameraTransform );
hr = m_pVolume->ProcessFrame( m_pDepthFloatImage, NUI_FUSION_DEFAULT_ALIGN_ITERATION_COUNT,
NUI_FUSION_DEFAULT_INTEGRATION_WEIGHT, &worldToCameraTransform );
worldToCameraTransform;
if (FAILED(hr)) {
++trackingErrorCount;
if ( trackingErrorCount >= 100 ) {
trackingErrorCount = 0;
m_pVolume->ResetReconstruction( &IdentityMatrix(), nullptr );
}
return;
}
// PointCloud
hr = m_pVolume->CalculatePointCloud( m_pPointCloud, &worldToCameraTransform );
if (FAILED(hr)) {
throw std::runtime_error( "CalculatePointCloud failed." );
}
// PointCloud
hr = ::NuiFusionShadePointCloud( m_pPointCloud, &worldToCameraTransform,
&worldToBGRTransform, m_pShadedSurface, nullptr );
if (FAILED(hr)) {
throw std::runtime_error( "::NuiFusionShadePointCloud failed." );
}
INuiFrameTexture * pShadedImageTexture = m_pShadedSurface->pFrameTexture;
NUI_LOCKED_RECT ShadedLockedRect;
hr = pShadedImageTexture->LockRect(0, &ShadedLockedRect, nullptr, 0);
if (FAILED(hr)) {
throw std::runtime_error( "LockRect failed." );
}
pShadedImageTexture->UnlockRect(0);
}
};
void processDepth()
{
NUI_图像_帧深度FRAME={0};
错误检查(kinect->NuiImageStreamGetNextFrame(depthStreamHandle、0和depthFrame));
BOOL nearMode=FALSE;
INuiFrameTexture*frameTexture=0;
kinect->NuiImageFrameGetDepthImagePixelFrameTexture(depthStreamHandle、&depthFrame、&nearMode、&frameTexture);
NUI_LOCKED_RECT depthData={0};
frameTexture->LockRect(0,&depthData,0,0);
if(depthData.Pitch==0){
std::无法获取当前世界到现金转移(&世界到现金转移);
hr=m_pVolume->ProcessFrame(m_pDepthFloatImage,NUI_FUSION_DEFAULT_ALIGN_ITERATION_COUNT,
NUI_FUSION_DEFAULT_INTEGRATION_WEIGHT和worldToCameraTransform);
世界货币转换;
如果(失败(小时)){
++跟踪错误计数;
如果(trackingErrorCount>=100){
trackingErrorCount=0;
m_pVolume->reset重构(&IdentityMatrix(),nullptr);
}
返回;
}
//点云
hr=m_pVolume->CalculatePointCloud(m_pPointCloud和worldToCameraTransform);
如果(失败(小时)){
抛出std::runtime_错误(“CalculatePointCloud失败”);
}
//点云
hr=::NuiFusionShadePointCloud(m_PointCloud和worldToCameraTransform,
&worldToBGRTransform,m_pshaddedsface,nullptr);
如果(失败(小时)){
抛出std::runtime_错误(“::NuiFusionShadePointCloud失败”);
}
INuiFrameTexture*pShadedImageTexture=m_pShadedSurface->pFrameTexture;
NUI_LOCKED_RECT ShadedLockedRect;
hr=pShadedImageTexture->LockRect(0,&ShadedLockedRect,nullptr,0);
如果(失败(小时)){
抛出std::runtime_错误(“LockRect失败”);
}
pshadeImageTexture->UnlockRect(0);
}
};
现在我认为最好的方法是编辑/裁剪depthData.pBits。但我不知道如何做到这一点。您使用点云库吗?这就是您想要的:非常感谢,编辑输入以计算点云可能确实比尝试编辑输出更有意义。但我还不知道怎么做。我对这个很陌生。我在下面添加了更多信息。