33 #include <opencv2/calib3d/calib3d.hpp> 34 #include <pcl/search/kdtree.h> 35 #include <pcl/common/point_tests.h> 45 const std::multimap<int, pcl::PointXYZ> & words2,
46 pcl::PointCloud<pcl::PointXYZ> & cloud1,
47 pcl::PointCloud<pcl::PointXYZ> & cloud2)
50 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
52 if(words1.count(*i) == 1 && words2.count(*i) == 1)
54 const pcl::PointXYZ & pt1 = words1.find(*i)->second;
55 const pcl::PointXYZ & pt2 = words2.find(*i)->second;
58 cloud1.push_back(pt1);
59 cloud2.push_back(pt2);
66 const std::multimap<int, pcl::PointXYZ> & words2,
67 pcl::PointCloud<pcl::PointXYZ> & cloud1,
68 pcl::PointCloud<pcl::PointXYZ> & cloud2)
70 std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> > pairs;
72 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
74 if(words1.count(*i) == 1 && words2.count(*i) == 1)
76 const pcl::PointXYZ & pt1 = words1.find(*i)->second;
77 const pcl::PointXYZ & pt2 = words2.find(*i)->second;
80 pairs.push_back(std::pair<pcl::PointXYZ, pcl::PointXYZ>(pt1, pt2));
88 std::vector<uchar> status(pairs.size(), 0);
91 cv::Mat points1(1, (
int)pairs.size(), CV_32FC2);
92 cv::Mat points2(1, (
int)pairs.size(), CV_32FC2);
94 float * points1data = points1.ptr<
float>(0);
95 float * points2data = points2.ptr<
float>(0);
99 for(std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> >::const_iterator iter = pairs.begin();
103 points1data[i*2] = (*iter).first.x;
104 points1data[i*2+1] = (*iter).first.y;
106 points2data[i*2] = (*iter).second.x;
107 points2data[i*2+1] = (*iter).second.y;
113 cv::Mat fundamentalMatrix = cv::findFundamentalMat(
121 if(!fundamentalMatrix.empty())
124 for(std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> >::iterator iter=pairs.begin(); iter!=pairs.end(); ++iter)
128 cloud1.push_back(iter->first);
129 cloud2.push_back(iter->second);
138 const cv::Mat & depthImage1,
139 const cv::Mat & depthImage2,
143 pcl::PointCloud<pcl::PointXYZ> & cloud1,
144 pcl::PointCloud<pcl::PointXYZ> & cloud2)
146 cloud1.resize(correspondences.size());
147 cloud2.resize(correspondences.size());
149 for(std::list<std::pair<cv::Point2f, cv::Point2f> >::const_iterator iter = correspondences.begin();
150 iter!=correspondences.end();
153 pcl::PointXYZ pt1 =
projectDepthTo3D(depthImage1, iter->first.x, iter->first.y, cx, cy, fx, fy,
true);
154 pcl::PointXYZ pt2 =
projectDepthTo3D(depthImage2, iter->second.x, iter->second.y, cx, cy, fx, fy,
true);
156 (maxDepth <= 0 || (pt1.z <= maxDepth && pt2.z<=maxDepth)))
167 template<
typename Po
intT>
169 const pcl::PointCloud<PointT> & cloud1,
170 const pcl::PointCloud<PointT> & cloud2,
171 pcl::PointCloud<pcl::PointXYZ> & inliers1,
172 pcl::PointCloud<pcl::PointXYZ> & inliers2,
175 for(std::list<std::pair<cv::Point2f, cv::Point2f> >::const_iterator iter = correspondences.begin();
176 iter!=correspondences.end();
179 PointT pt1 = cloud1.at(
int(iter->first.y+0.5f) * cloud1.width +
int(iter->first.x+0.5f));
180 PointT pt2 = cloud2.at(
int(iter->second.y+0.5f) * cloud2.width +
int(iter->second.x+0.5f));
184 inliers1.push_back(pcl::PointXYZ(pt1.x, pt1.y, pt1.z));
185 inliers2.push_back(pcl::PointXYZ(pt2.x, pt2.y, pt2.z));
191 const pcl::PointCloud<pcl::PointXYZ> & cloud1,
192 const pcl::PointCloud<pcl::PointXYZ> & cloud2,
193 pcl::PointCloud<pcl::PointXYZ> & inliers1,
194 pcl::PointCloud<pcl::PointXYZ> & inliers2,
200 const pcl::PointCloud<pcl::PointXYZRGB> & cloud1,
201 const pcl::PointCloud<pcl::PointXYZRGB> & cloud2,
202 pcl::PointCloud<pcl::PointXYZ> & inliers1,
203 pcl::PointCloud<pcl::PointXYZ> & inliers2,
210 const std::multimap<int, pcl::PointXYZ> & wordsB)
214 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
216 std::list<pcl::PointXYZ> ptsA =
uValues(wordsA, *i);
217 std::list<pcl::PointXYZ> ptsB =
uValues(wordsB, *i);
218 if(ptsA.size() == 1 && ptsB.size() == 1)
227 pcl::PointCloud<pcl::PointXYZ> & inliers2,
230 bool removeDuplicates)
232 std::list<pcl::PointXYZ> addedPts;
233 if(maxDepth > 0.0
f && inliers1.size() && inliers1.size() == inliers2.size())
235 pcl::PointCloud<pcl::PointXYZ> tmpInliers1;
236 pcl::PointCloud<pcl::PointXYZ> tmpInliers2;
237 for(
unsigned int i=0; i<inliers1.size(); ++i)
239 if((depthAxis ==
'x' && inliers1.at(i).x < maxDepth && inliers2.at(i).x < maxDepth) ||
240 (depthAxis ==
'y' && inliers1.at(i).y < maxDepth && inliers2.at(i).y < maxDepth) ||
241 (depthAxis ==
'z' && inliers1.at(i).z < maxDepth && inliers2.at(i).z < maxDepth))
246 for(std::list<pcl::PointXYZ>::iterator iter = addedPts.begin(); iter!=addedPts.end(); ++iter)
248 if(iter->x == inliers1.at(i).x &&
249 iter->y == inliers1.at(i).y &&
250 iter->z == inliers1.at(i).z)
257 addedPts.push_back(inliers1.at(i));
263 tmpInliers1.push_back(inliers1.at(i));
264 tmpInliers2.push_back(inliers2.at(i));
268 inliers1 = tmpInliers1;
269 inliers2 = tmpInliers2;
277 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_target,
280 pcl::search::KdTree<pcl::PointXYZ>::Ptr kdTree(
new pcl::search::KdTree<pcl::PointXYZ>);
281 kdTree->setInputCloud(cloud_target);
283 float sqrdMaxDistance = maxDistance * maxDistance;
284 for(
unsigned int i=0; i<cloud_source->size(); ++i)
286 std::vector<int> ind(1);
287 std::vector<float>
dist(1);
288 if(kdTree->nearestKSearch(cloud_source->at(i), 1, ind, dist) && dist[0] < sqrdMaxDistance)
301 const std::multimap<int, cv::KeyPoint> & wordsA,
302 const std::multimap<int, cv::KeyPoint> & wordsB,
303 std::list<std::pair<cv::Point2f, cv::Point2f> > & pairs)
307 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
309 std::list<cv::KeyPoint> ptsA =
uValues(wordsA, *i);
310 std::list<cv::KeyPoint> ptsB =
uValues(wordsB, *i);
311 if(ptsA.size() == 1 && ptsB.size() == 1)
313 pairs.push_back(std::pair<cv::Point2f, cv::Point2f>(ptsA.front().pt, ptsB.front().pt));
319 const std::multimap<int, cv::Point3f> & words1,
320 const std::multimap<int, cv::Point3f> & words2,
321 std::vector<cv::Point3f> & inliers1,
322 std::vector<cv::Point3f> & inliers2,
324 std::vector<int> * uniqueCorrespondences)
328 inliers1.resize(ids.size());
329 inliers2.resize(ids.size());
330 if(uniqueCorrespondences)
332 uniqueCorrespondences->resize(ids.size());
336 for(std::list<int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
338 if(words1.count(*iter) == 1 && words2.count(*iter) == 1)
340 inliers1[oi] = words1.find(*iter)->second;
341 inliers2[oi] = words2.find(*iter)->second;
344 (inliers1[oi].x != 0 || inliers1[oi].y != 0 || inliers1[oi].z != 0) &&
345 (inliers2[oi].x != 0 || inliers2[oi].y != 0 || inliers2[oi].z != 0) &&
346 (maxDepth <= 0 || (inliers1[oi].x > 0 && inliers1[oi].x <= maxDepth && inliers2[oi].x>0 &&inliers2[oi].x<=maxDepth)))
348 if(uniqueCorrespondences)
350 uniqueCorrespondences->at(oi) = *iter;
358 if(uniqueCorrespondences)
360 uniqueCorrespondences->resize(oi);
365 const std::map<int, cv::Point3f> & words1,
366 const std::map<int, cv::Point3f> & words2,
367 std::vector<cv::Point3f> & inliers1,
368 std::vector<cv::Point3f> & inliers2,
370 std::vector<int> * correspondences)
372 std::vector<int> ids =
uKeys(words1);
374 inliers1.resize(ids.size());
375 inliers2.resize(ids.size());
378 correspondences->resize(ids.size());
382 for(std::vector<int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
384 if(words2.find(*iter) != words2.end())
386 inliers1[oi] = words1.find(*iter)->second;
387 inliers2[oi] = words2.find(*iter)->second;
390 (inliers1[oi].x != 0 || inliers1[oi].y != 0 || inliers1[oi].z != 0) &&
391 (inliers2[oi].x != 0 || inliers2[oi].y != 0 || inliers2[oi].z != 0) &&
392 (maxDepth <= 0 || (inliers1[oi].x > 0 && inliers1[oi].x <= maxDepth && inliers2[oi].x>0 &&inliers2[oi].x<=maxDepth)))
396 correspondences->at(oi) = *iter;
406 correspondences->resize(oi);
std::list< K > uUniqueKeys(const std::multimap< K, V > &mm)
bool RTABMAP_EXP isFinite(const cv::Point3f &pt)
std::vector< K > uKeys(const std::multimap< K, V > &mm)
Wrappers of STL for convenient functions.
pcl::PointXYZ RTABMAP_EXP projectDepthTo3D(const cv::Mat &depthImage, float x, float y, float cx, float cy, float fx, float fy, bool smoothing, float depthErrorRatio=0.02f)
void RTABMAP_EXP extractXYZCorrespondencesRANSAC(const std::multimap< int, pcl::PointXYZ > &words1, const std::multimap< int, pcl::PointXYZ > &words2, pcl::PointCloud< pcl::PointXYZ > &cloud1, pcl::PointCloud< pcl::PointXYZ > &cloud2)
void RTABMAP_EXP filterMaxDepth(pcl::PointCloud< pcl::PointXYZ > &inliers1, pcl::PointCloud< pcl::PointXYZ > &inliers2, float maxDepth, char depthAxis, bool removeDuplicates)
void extractXYZCorrespondencesImpl(const std::list< std::pair< cv::Point2f, cv::Point2f > > &correspondences, const pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2, pcl::PointCloud< pcl::PointXYZ > &inliers1, pcl::PointCloud< pcl::PointXYZ > &inliers2, char depthAxis)
int RTABMAP_EXP getCorrespondencesCount(const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &cloud_source, const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &cloud_target, float maxDistance)
std::vector< V > uValues(const std::multimap< K, V > &mm)
void RTABMAP_EXP extractXYZCorrespondences(const std::multimap< int, pcl::PointXYZ > &words1, const std::multimap< int, pcl::PointXYZ > &words2, pcl::PointCloud< pcl::PointXYZ > &cloud1, pcl::PointCloud< pcl::PointXYZ > &cloud2)
int RTABMAP_EXP countUniquePairs(const std::multimap< int, pcl::PointXYZ > &wordsA, const std::multimap< int, pcl::PointXYZ > &wordsB)
void RTABMAP_EXP findCorrespondences(const std::multimap< int, cv::KeyPoint > &wordsA, const std::multimap< int, cv::KeyPoint > &wordsB, std::list< std::pair< cv::Point2f, cv::Point2f > > &pairs)