mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 09:30:25 +08:00
multiband: add multi-camera support. rtabmap-export: updated options (now supporting creating point cloud from scans).
This commit is contained in:
@@ -1078,7 +1078,14 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (
|
||||
std::vector<std::map<int, FaceInfo > > visibleFaces(cameras.size());
|
||||
std::vector<Eigen::Affine3f> invCamTransform(cameras.size());
|
||||
std::vector<std::list<int> > faceCameras(faces.size());
|
||||
UINFO("Precompute visible faces per cam (%d faces, %d cams)", (int)faces.size(), (int)cameras.size());
|
||||
std::string msg = uFormat("Computing visible faces per cam (%d faces, %d cams)", (int)faces.size(), (int)cameras.size());
|
||||
UINFO(msg.c_str());
|
||||
if(state && !state->callback(msg))
|
||||
{
|
||||
//cancelled!
|
||||
UWARN("Texturing cancelled!");
|
||||
return false;
|
||||
}
|
||||
for (unsigned int current_cam = 0; current_cam < cameras.size(); ++current_cam)
|
||||
{
|
||||
UDEBUG("Texture camera %d...", current_cam);
|
||||
@@ -1274,7 +1281,7 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (
|
||||
}
|
||||
}
|
||||
|
||||
std::string msg = uFormat("Processed camera %d/%d: %d occluded and %d spurious polygons out of %d", (int)current_cam+1, (int)cameras.size(), (int)occludedFaces.size(), clusterFaces, (int)visibilityIndices.size());
|
||||
msg = uFormat("Processed camera %d/%d: %d occluded and %d spurious polygons out of %d", (int)current_cam+1, (int)cameras.size(), (int)occludedFaces.size(), clusterFaces, (int)visibilityIndices.size());
|
||||
UINFO(msg.c_str());
|
||||
if(state && !state->callback(msg))
|
||||
{
|
||||
@@ -1284,7 +1291,7 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (
|
||||
}
|
||||
}
|
||||
|
||||
std::string msg = uFormat("Texturing %d polygons...", (int)faces.size());
|
||||
msg = uFormat("Texturing %d polygons...", (int)faces.size());
|
||||
UINFO(msg.c_str());
|
||||
if(state && !state->callback(msg))
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -1509,7 +1509,7 @@ cv::Mat mergeTextures(
|
||||
cv::Mat globalTextures;
|
||||
if(mesh.tex_materials.size() > 1)
|
||||
{
|
||||
std::vector<std::pair<int, int> > textures(mesh.tex_materials.size(), std::pair<int, int>(-1,-1));
|
||||
std::vector<std::pair<int, int> > textures(mesh.tex_materials.size(), std::pair<int, int>(-1,0));
|
||||
cv::Size imageSize;
|
||||
const int imageType=CV_8UC3;
|
||||
|
||||
@@ -2222,7 +2222,8 @@ bool multiBandTexturing(
|
||||
const std::string & textureFormat,
|
||||
const std::map<int, std::map<int, cv::Vec4d> > & gains, // optional output of util3d::mergeTextures()
|
||||
const std::map<int, std::map<int, cv::Mat> > & blendingGains, // optional output of util3d::mergeTextures()
|
||||
const std::pair<float, float> & contrastValues) // optional output of util3d::mergeTextures()
|
||||
const std::pair<float, float> & contrastValues, // optional output of util3d::mergeTextures()
|
||||
bool gainRGB)
|
||||
{
|
||||
#ifdef RTABMAP_ALICE_VISION
|
||||
if(ULogger::level() == ULogger::kDebug)
|
||||
@@ -2255,7 +2256,6 @@ bool multiBandTexturing(
|
||||
texturing.texParams.textureSide = 8192;
|
||||
texturing.texParams.downscale = 8192/textureSize;
|
||||
|
||||
std::vector<int> camIndexToId(uKeys(cameraModels));
|
||||
for(size_t i=0;i<cloud2.size();++i)
|
||||
{
|
||||
pcl::PointXYZRGB pt = cloud2.at(i);
|
||||
@@ -2281,8 +2281,10 @@ bool multiBandTexturing(
|
||||
UTimer timer;
|
||||
std::string outputDirectory = UDirectory::getDir(outputOBJPath);
|
||||
std::string tmpImageDirectory = outputDirectory+"/rtabmap_tmp_textures";
|
||||
UDirectory::removeDir(tmpImageDirectory);
|
||||
UDirectory::makeDir(tmpImageDirectory);
|
||||
UINFO("Temporary saving images in directory \"%s\"...", tmpImageDirectory.c_str());
|
||||
int viewId = 0;
|
||||
for(std::map<int, Transform>::const_iterator iter = cameraPoses.lower_bound(1); iter!=cameraPoses.end(); ++iter)
|
||||
{
|
||||
int camId = iter->first;
|
||||
@@ -2338,11 +2340,6 @@ bool multiBandTexturing(
|
||||
UERROR("No camera models found for camera %d. Aborting multiband texturing...", iter->first);
|
||||
return false;
|
||||
}
|
||||
else if(models.size() != 1)
|
||||
{
|
||||
UERROR("Unwrapping not supporting multi-camera yet... ignoring %d. Aborting multiband texturing...", iter->first);
|
||||
return false;
|
||||
}
|
||||
if(image.empty())
|
||||
{
|
||||
UERROR("No image found for camera %d. Aborting multiband texturing...", iter->first);
|
||||
@@ -2358,60 +2355,72 @@ bool multiBandTexturing(
|
||||
image = image.clone();
|
||||
}
|
||||
|
||||
UASSERT(models.size() == 1);
|
||||
const CameraModel & model = models[0];
|
||||
Transform t = iter->second * model.localTransform();
|
||||
Eigen::Matrix<double, 3, 4> m = (t.inverse()).toEigen3d().matrix().block<3,4>(0, 0);
|
||||
sfmData::CameraPose pose(geometry::Pose3(m), true);
|
||||
sfmData.setAbsolutePose((IndexT)camId, pose);
|
||||
cv::Size imageSize = model.imageSize();
|
||||
if(imageSize.height == 0)
|
||||
for(size_t i=0; i<models.size(); ++i)
|
||||
{
|
||||
// backward compatibility
|
||||
imageSize.height = image.rows;
|
||||
imageSize.width = image.cols;
|
||||
const CameraModel & model = models.at(i);
|
||||
cv::Size imageSize = model.imageSize();
|
||||
if(imageSize.height == 0)
|
||||
{
|
||||
// backward compatibility
|
||||
imageSize.height = image.rows;
|
||||
imageSize.width = image.cols;
|
||||
}
|
||||
UASSERT(image.cols % imageSize.width == 0);
|
||||
cv::Mat imageRoi = image.colRange(i*imageSize.width, (i+1)*imageSize.width);
|
||||
if(gains.find(camId) != gains.end() &&
|
||||
gains.at(camId).find(i) != gains.at(camId).end())
|
||||
{
|
||||
const cv::Vec4d & g = gains.at(camId).at(i);
|
||||
std::vector<cv::Mat> channels;
|
||||
cv::split(imageRoi, channels);
|
||||
|
||||
// assuming BGR
|
||||
cv::multiply(channels[0], g.val[gainRGB?3:0], channels[0]);
|
||||
cv::multiply(channels[1], g.val[gainRGB?2:0], channels[1]);
|
||||
cv::multiply(channels[2], g.val[gainRGB?1:0], channels[2]);
|
||||
|
||||
cv::Mat output;
|
||||
cv::merge(channels, output);
|
||||
imageRoi = output;
|
||||
}
|
||||
|
||||
if(blendingGains.find(camId) != blendingGains.end() &&
|
||||
blendingGains.at(camId).find(i) != blendingGains.at(camId).end())
|
||||
{
|
||||
cv::Mat g = blendingGains.at(camId).at(i);
|
||||
cv::Mat dst;
|
||||
cv::blur(g, dst, cv::Size(3,3));
|
||||
cv::Mat gResized;
|
||||
cv::resize(dst, gResized, imageRoi.size(), 0, 0, cv::INTER_LINEAR);
|
||||
cv::Mat output;
|
||||
cv::multiply(imageRoi, gResized, output, 1.0, CV_8UC3);
|
||||
imageRoi = output;
|
||||
}
|
||||
|
||||
Transform t = iter->second * model.localTransform();
|
||||
Eigen::Matrix<double, 3, 4> m = (t.inverse()).toEigen3d().matrix().block<3,4>(0, 0);
|
||||
sfmData::CameraPose pose(geometry::Pose3(m), true);
|
||||
sfmData.setAbsolutePose((IndexT)viewId, pose);
|
||||
|
||||
std::shared_ptr<camera::IntrinsicBase> camPtr(new camera::Pinhole(imageSize.width, imageSize.height, model.fx(), model.cx(), model.cy()));
|
||||
sfmData.intrinsics.insert(std::make_pair((IndexT)viewId, camPtr));
|
||||
|
||||
std::string imagePath = tmpImageDirectory+uFormat("/%d.jpg", viewId);
|
||||
|
||||
cv::imwrite(imagePath, imageRoi);
|
||||
|
||||
sfmData.views.insert(std::make_pair((IndexT)viewId,
|
||||
new sfmData::View(
|
||||
imagePath,
|
||||
(IndexT)viewId,
|
||||
(IndexT)viewId,
|
||||
(IndexT)viewId,
|
||||
imageSize.width,
|
||||
imageSize.height)));
|
||||
++viewId;
|
||||
}
|
||||
std::shared_ptr<camera::IntrinsicBase> camPtr(new camera::Pinhole(imageSize.width, imageSize.height, model.fx(), model.cx(), model.cy()));
|
||||
sfmData.intrinsics.insert(std::make_pair((IndexT)camId, camPtr));
|
||||
|
||||
std::string imagePath = tmpImageDirectory+uFormat("/%d.jpg", camId);
|
||||
|
||||
if(gains.find(camId) != gains.end())
|
||||
{
|
||||
UASSERT(gains.at(camId).size() == 1);
|
||||
const cv::Vec4d & g = gains.at(camId).begin()->second;
|
||||
std::vector<cv::Mat> channels;
|
||||
cv::split(image, channels);
|
||||
|
||||
// assuming BGR
|
||||
cv::multiply(channels[0], g.val[3], channels[0]);
|
||||
cv::multiply(channels[1], g.val[2], channels[1]);
|
||||
cv::multiply(channels[2], g.val[1], channels[2]);
|
||||
|
||||
cv::merge(channels, image);
|
||||
}
|
||||
if(blendingGains.find(camId) != blendingGains.end())
|
||||
{
|
||||
UASSERT(blendingGains.at(camId).size() == 1);
|
||||
cv::Mat g = blendingGains.at(camId).begin()->second;
|
||||
cv::Mat dst;
|
||||
cv::blur(g, dst, cv::Size(3,3));
|
||||
cv::Mat gResized;
|
||||
cv::resize(dst, gResized, image.size(), 0, 0, cv::INTER_LINEAR);
|
||||
cv::multiply(image, gResized, image, 1.0, CV_8UC3);
|
||||
}
|
||||
cv::imwrite(imagePath, image);
|
||||
|
||||
sfmData.views.insert(std::make_pair((IndexT)camId,
|
||||
new sfmData::View(
|
||||
imagePath,
|
||||
(IndexT)camId,
|
||||
(IndexT)camId,
|
||||
(IndexT)camId,
|
||||
imageSize.width,
|
||||
imageSize.height)));
|
||||
}
|
||||
UINFO("Temporary saving images in directory \"%s\"... done. %fs", tmpImageDirectory.c_str(), timer.ticks());
|
||||
UINFO("Temporary saving images in directory \"%s\"... done (%d images). %fs", tmpImageDirectory.c_str(), viewId, (int)cameraPoses.size(), timer.ticks());
|
||||
|
||||
mvsUtils::MultiViewParams mp(sfmData);
|
||||
|
||||
@@ -2458,6 +2467,7 @@ bool multiBandTexturing(
|
||||
{
|
||||
UASSERT(img.channels() == 3);
|
||||
// Re-use same contrast values with all images
|
||||
UINFO("Apply contrast values %f %f", contrastValues.first, contrastValues.second);
|
||||
img.convertTo(img, -1, contrastValues.first, contrastValues.second);
|
||||
}
|
||||
std::string newName = *iter;
|
||||
|
||||
Reference in New Issue
Block a user