33 #include <opencv2/calib3d/calib3d.hpp> 34 #include <pcl/search/kdtree.h> 44 const std::multimap<int, pcl::PointXYZ> & words2,
45 pcl::PointCloud<pcl::PointXYZ> & cloud1,
46 pcl::PointCloud<pcl::PointXYZ> & cloud2)
49 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
51 if(words1.count(*i) == 1 && words2.count(*i) == 1)
53 const pcl::PointXYZ & pt1 = words1.find(*i)->second;
54 const pcl::PointXYZ & pt2 = words2.find(*i)->second;
57 cloud1.push_back(pt1);
58 cloud2.push_back(pt2);
65 const std::multimap<int, pcl::PointXYZ> & words2,
66 pcl::PointCloud<pcl::PointXYZ> & cloud1,
67 pcl::PointCloud<pcl::PointXYZ> & cloud2)
69 std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> > pairs;
71 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
73 if(words1.count(*i) == 1 && words2.count(*i) == 1)
75 const pcl::PointXYZ & pt1 = words1.find(*i)->second;
76 const pcl::PointXYZ & pt2 = words2.find(*i)->second;
79 pairs.push_back(std::pair<pcl::PointXYZ, pcl::PointXYZ>(pt1, pt2));
87 std::vector<uchar> status(pairs.size(), 0);
90 cv::Mat points1(1, (
int)pairs.size(), CV_32FC2);
91 cv::Mat points2(1, (
int)pairs.size(), CV_32FC2);
93 float * points1data = points1.ptr<
float>(0);
94 float * points2data = points2.ptr<
float>(0);
98 for(std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> >::const_iterator iter = pairs.begin();
102 points1data[i*2] = (*iter).first.x;
103 points1data[i*2+1] = (*iter).first.y;
105 points2data[i*2] = (*iter).second.x;
106 points2data[i*2+1] = (*iter).second.y;
112 cv::Mat fundamentalMatrix = cv::findFundamentalMat(
120 if(!fundamentalMatrix.empty())
123 for(std::list<std::pair<pcl::PointXYZ, pcl::PointXYZ> >::iterator iter=pairs.begin(); iter!=pairs.end(); ++iter)
127 cloud1.push_back(iter->first);
128 cloud2.push_back(iter->second);
137 const cv::Mat & depthImage1,
138 const cv::Mat & depthImage2,
142 pcl::PointCloud<pcl::PointXYZ> & cloud1,
143 pcl::PointCloud<pcl::PointXYZ> & cloud2)
145 cloud1.resize(correspondences.size());
146 cloud2.resize(correspondences.size());
148 for(std::list<std::pair<cv::Point2f, cv::Point2f> >::const_iterator iter = correspondences.begin();
149 iter!=correspondences.end();
152 pcl::PointXYZ pt1 =
projectDepthTo3D(depthImage1, iter->first.x, iter->first.y, cx, cy, fx, fy,
true);
153 pcl::PointXYZ pt2 =
projectDepthTo3D(depthImage2, iter->second.x, iter->second.y, cx, cy, fx, fy,
true);
155 (maxDepth <= 0 || (pt1.z <= maxDepth && pt2.z<=maxDepth)))
166 template<
typename Po
intT>
168 const pcl::PointCloud<PointT> & cloud1,
169 const pcl::PointCloud<PointT> & cloud2,
170 pcl::PointCloud<pcl::PointXYZ> & inliers1,
171 pcl::PointCloud<pcl::PointXYZ> & inliers2,
174 for(std::list<std::pair<cv::Point2f, cv::Point2f> >::const_iterator iter = correspondences.begin();
175 iter!=correspondences.end();
178 PointT pt1 = cloud1.at(
int(iter->first.y+0.5f) * cloud1.width +
int(iter->first.x+0.5f));
179 PointT pt2 = cloud2.at(
int(iter->second.y+0.5f) * cloud2.width +
int(iter->second.x+0.5f));
183 inliers1.push_back(pcl::PointXYZ(pt1.x, pt1.y, pt1.z));
184 inliers2.push_back(pcl::PointXYZ(pt2.x, pt2.y, pt2.z));
190 const pcl::PointCloud<pcl::PointXYZ> & cloud1,
191 const pcl::PointCloud<pcl::PointXYZ> & cloud2,
192 pcl::PointCloud<pcl::PointXYZ> & inliers1,
193 pcl::PointCloud<pcl::PointXYZ> & inliers2,
199 const pcl::PointCloud<pcl::PointXYZRGB> & cloud1,
200 const pcl::PointCloud<pcl::PointXYZRGB> & cloud2,
201 pcl::PointCloud<pcl::PointXYZ> & inliers1,
202 pcl::PointCloud<pcl::PointXYZ> & inliers2,
209 const std::multimap<int, pcl::PointXYZ> & wordsB)
213 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
215 std::list<pcl::PointXYZ> ptsA =
uValues(wordsA, *i);
216 std::list<pcl::PointXYZ> ptsB =
uValues(wordsB, *i);
217 if(ptsA.size() == 1 && ptsB.size() == 1)
226 pcl::PointCloud<pcl::PointXYZ> & inliers2,
229 bool removeDuplicates)
231 std::list<pcl::PointXYZ> addedPts;
232 if(maxDepth > 0.0
f && inliers1.size() && inliers1.size() == inliers2.size())
234 pcl::PointCloud<pcl::PointXYZ> tmpInliers1;
235 pcl::PointCloud<pcl::PointXYZ> tmpInliers2;
236 for(
unsigned int i=0; i<inliers1.size(); ++i)
238 if((depthAxis ==
'x' && inliers1.at(i).x < maxDepth && inliers2.at(i).x < maxDepth) ||
239 (depthAxis ==
'y' && inliers1.at(i).y < maxDepth && inliers2.at(i).y < maxDepth) ||
240 (depthAxis ==
'z' && inliers1.at(i).z < maxDepth && inliers2.at(i).z < maxDepth))
245 for(std::list<pcl::PointXYZ>::iterator iter = addedPts.begin(); iter!=addedPts.end(); ++iter)
247 if(iter->x == inliers1.at(i).x &&
248 iter->y == inliers1.at(i).y &&
249 iter->z == inliers1.at(i).z)
256 addedPts.push_back(inliers1.at(i));
262 tmpInliers1.push_back(inliers1.at(i));
263 tmpInliers2.push_back(inliers2.at(i));
267 inliers1 = tmpInliers1;
268 inliers2 = tmpInliers2;
276 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_target,
279 pcl::search::KdTree<pcl::PointXYZ>::Ptr kdTree(
new pcl::search::KdTree<pcl::PointXYZ>);
280 kdTree->setInputCloud(cloud_target);
282 float sqrdMaxDistance = maxDistance * maxDistance;
283 for(
unsigned int i=0; i<cloud_source->size(); ++i)
285 std::vector<int> ind(1);
286 std::vector<float> dist(1);
287 if(kdTree->nearestKSearch(cloud_source->at(i), 1, ind, dist) && dist[0] < sqrdMaxDistance)
300 const std::multimap<int, cv::KeyPoint> & wordsA,
301 const std::multimap<int, cv::KeyPoint> & wordsB,
302 std::list<std::pair<cv::Point2f, cv::Point2f> > & pairs)
306 for(std::list<int>::const_iterator i=ids.begin(); i!=ids.end(); ++i)
308 std::list<cv::KeyPoint> ptsA =
uValues(wordsA, *i);
309 std::list<cv::KeyPoint> ptsB =
uValues(wordsB, *i);
310 if(ptsA.size() == 1 && ptsB.size() == 1)
312 pairs.push_back(std::pair<cv::Point2f, cv::Point2f>(ptsA.front().pt, ptsB.front().pt));
318 const std::multimap<int, cv::Point3f> & words1,
319 const std::multimap<int, cv::Point3f> & words2,
320 std::vector<cv::Point3f> & inliers1,
321 std::vector<cv::Point3f> & inliers2,
323 std::vector<int> * uniqueCorrespondences)
327 inliers1.resize(ids.size());
328 inliers2.resize(ids.size());
329 if(uniqueCorrespondences)
331 uniqueCorrespondences->resize(ids.size());
335 for(std::list<int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
337 if(words1.count(*iter) == 1 && words2.count(*iter) == 1)
339 inliers1[oi] = words1.find(*iter)->second;
340 inliers2[oi] = words2.find(*iter)->second;
343 (inliers1[oi].x != 0 || inliers1[oi].y != 0 || inliers1[oi].z != 0) &&
344 (inliers2[oi].x != 0 || inliers2[oi].y != 0 || inliers2[oi].z != 0) &&
345 (maxDepth <= 0 || (inliers1[oi].x > 0 && inliers1[oi].x <= maxDepth && inliers2[oi].x>0 &&inliers2[oi].x<=maxDepth)))
347 if(uniqueCorrespondences)
349 uniqueCorrespondences->at(oi) = *iter;
357 if(uniqueCorrespondences)
359 uniqueCorrespondences->resize(oi);
364 const std::map<int, cv::Point3f> & words1,
365 const std::map<int, cv::Point3f> & words2,
366 std::vector<cv::Point3f> & inliers1,
367 std::vector<cv::Point3f> & inliers2,
369 std::vector<int> * correspondences)
371 std::vector<int> ids =
uKeys(words1);
373 inliers1.resize(ids.size());
374 inliers2.resize(ids.size());
377 correspondences->resize(ids.size());
381 for(std::vector<int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
383 if(words2.find(*iter) != words2.end())
385 inliers1[oi] = words1.find(*iter)->second;
386 inliers2[oi] = words2.find(*iter)->second;
389 (inliers1[oi].x != 0 || inliers1[oi].y != 0 || inliers1[oi].z != 0) &&
390 (inliers2[oi].x != 0 || inliers2[oi].y != 0 || inliers2[oi].z != 0) &&
391 (maxDepth <= 0 || (inliers1[oi].x > 0 && inliers1[oi].x <= maxDepth && inliers2[oi].x>0 &&inliers2[oi].x<=maxDepth)))
395 correspondences->at(oi) = *iter;
405 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)