https://github.com/jstraub/rtmf
MIT 2015的IROS工作,用rgb还要让depth提取曼哈顿坐标系和平面分割
代码依赖以下库,还需要安装作者在GPU提取计算法向量以及vMF优化估计曼哈顿系的库,mmf,cudapcl
Ubuntu
14.04.
- pcl 1.7 (and vtk 5.8)
- Opencv 2 (2.3.1)
- Eigen3 (3.0.5)
- cuda 5.5 or 6.5
- Boost (1.52)
The GPU kernels were tested on a Nvidia Quadro K2000M with compute
capability 3.0.
### Install
Once you have those dependencies in place run
```
make checkout && make configure && make
```
This will checkout dependencies from some of my other repositories
([jsCore](https://github.com/jstraub/jsCore),
[mmf](https://github.com/jstraub/mmf),
[cudePcl](https://github.com/jstraub/cudaPcl))
and compile everything to ./build/
代码结构
这里只记录一个分支,
realtimeMF.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <rtmf/rtmf.hpp>
#include <rtmf/realtimeMF_openni.hpp>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
//program options是一系列pair<name,value>组成的选项列表,它允许程序通过命令行或配置文件来读取这些参数选项.
int main (int argc, char** argv)
{
//设置参数
//模式为 approx
string mode = "approx";
string path = "";
//存储法向量的变量
cudaPcl::CfgSmoothNormals cfgNormals;
//焦距
cfgNormals.f_d = 540.;
//?
cfgNormals.eps = 0.2*0.2;
//?
cfgNormals.B = 9;
cfgNormals.compress = true;
// 迭代次数
uint32_t T = 10;
//优化库
CfgOptSO3 cfgOptSO3;
//?
cfgOptSO3.sigma = 5.0f*M_PI/180.0;
// 寻找 gpu设备,通过 jscore库
findCudaDevice(argc,(const char**)argv);
// 主要的曼哈顿类
shared_ptr<RealtimeMF> pRtmf;
std::vector<shared_ptr<RealtimeMF> > pRtmfs;
// 没有输入图片,就寻找openni设备
if (path.length() == 0)
{
cout<<"no input path -> trying openni"<<endl;
RealtimeMF_openni rtmfOpenni(pRtmf);
rtmfOpenni.run();
cout<<cudaDeviceReset()<<endl;
return (0);
}
else{
// 读图
cout<<"reading depth image from "<<path<<endl;
cv::Mat depth = cv::imread(path,
CV_LOAD_IMAGE_ANYDEPTH);
cout<<"type: "<<int(depth.type()) <<" != "<<int(CV_16U) <<endl;
//显示
if(vm.count("display"))
{
cv::Mat dI(depth.rows,depth.cols,CV_8UC1);
depth.convertTo(dI,CV_8UC1,255./4000.,-19.);
cv::imshow("d",dI);
cv::waitKey(0);
}
//模式判断,如果模式为 mmfvmf,这里跳过,选下一个模式
if (mode.compare("mmfvmf") == 0) {
}
else {
//初始化曼哈顿类
pRtmf = shared_ptr<RealtimeMF>(new RealtimeMF(mode,cfgOptSO3,cfgNormals));
for(uint32_t i=0; i<T; ++i) {
// 校对模式 ?? 不是approx吗?
if (mode.compare("vmfCF") == 0) {
//变量初始化
pRtmf->Reset();
//计算过程,这个函数在 hpp中对 cudapcl的函数进行继承并重写
pRtmf->compute(reinterpret_cast<uint16_t*>(depth.data),
depth.cols,depth.rows);
}
}
}
cv::Mat dI = pRtmf->smoothDepthImg();
cv::Mat nI = pRtmf->normalsImg();
cv::Mat zI = pRtmf->labelsImg();
//读彩图转灰度
cv::Mat gray = cv::imread(pathRgb, CV_LOAD_IMAGE_GRAYSCALE);
// 访问不到,是个库函数
cv::Mat Iout = pRtmf->overlaySeg(gray,true,true);
if(vm.count("out"))
{
//输出文件
}
//显示
if(vm.count("display"))
{
cv::imshow("dS",dI);
cv::imshow("normals",nI);
cv::imshow("zI",zI);
cv::imshow("out",Iout);
cv::waitKey(0);
}
cout<<cudaDeviceReset()<<endl;
}
return (0);
}
realtimeMF.hpp中的compute_()函数
void RealtimeMF::compute_()
{
// get compressed normals
tLog_.toctic(1,2);
int32_t nComp = 0;
float* d_nComp = normalExtract_->d_normalsComp(nComp);
cout<<" -- compressed to "<<nComp<<" normals"<<endl;
// normalsImg_ = normalExtract_->normalsImg();
// optimize normals
tLog_.toctic(2,3);
optSO3_->updateExternalGpuNormals(d_nComp,nComp,3,0);
residual_ = optSO3_->conjugateGradientCUDA(cRmf_,nCGIter_);
cRmfs_ = optSO3_->GetRs();
if (mode_.compare("mmfvmf") == 0 && cRmfs_.size() == 1)
cRmf_ = cRmfs_[0];
std::cout << "have " << cRmfs_.size() << " MFs" << std::endl;
D_KL_ = optSO3_->D_KL_axisUnif();
cout<<" -- optimized rotation D_KL to unif "<<D_KL_<<endl
<<cRmf_<<endl;
tLog_.toc(3);
// tLog_.setDt(3,optSO3_->dtPrep());
// tLog_.setDt(4,optSO3_->dtCG());
tLog_.logCycle();
haveLabels_ = false;
};