40 #include <pcl/common/common.h> 41 #include <pcl/common/centroid.h> 42 #include <pcl/common/io.h> 55 bool unknownSpaceFilled,
58 cv::Point3f viewpoint(0,0,0);
72 const cv::Point3f & viewpoint,
76 bool unknownSpaceFilled,
83 const cv::Mat & scanHitIn,
84 const cv::Mat & scanNoHitIn,
85 const cv::Point3f & viewpoint,
89 bool unknownSpaceFilled,
92 if(scanHitIn.empty() && scanNoHitIn.empty())
99 if(scanHitIn.channels()>2)
101 std::vector<cv::Mat> channels;
102 cv::split(scanHitIn,channels);
103 while(channels.size()>2)
107 cv::merge(channels,scanHit);
111 scanHit = scanHitIn.clone();
113 if(scanNoHitIn.channels()>2)
115 std::vector<cv::Mat> channels;
116 cv::split(scanNoHitIn,channels);
117 while(channels.size()>2)
121 cv::merge(channels,scanNoHit);
125 scanNoHit = scanHitIn;
128 std::map<int, Transform> poses;
131 std::map<int, std::pair<cv::Mat, cv::Mat> > scans;
132 scans.insert(std::make_pair(1, std::make_pair(scanHit, scanNoHit)));
134 std::map<int, cv::Point3f> viewpoints;
135 viewpoints.insert(std::make_pair(1, viewpoint));
138 cv::Mat map8S =
create2DMap(poses, scans, viewpoints, cellSize, unknownSpaceFilled, xMin, yMin, 0.0
f, scanMaxRange);
141 std::list<int> emptyIndices;
142 for(
unsigned int i=0; i< map8S.total(); ++i)
144 if(map8S.data[i] == 0)
146 emptyIndices.push_back(i);
152 if(emptyIndices.size())
154 empty = cv::Mat(1, (
int)emptyIndices.size(), CV_32FC2);
156 for(std::list<int>::iterator iter=emptyIndices.begin();iter!=emptyIndices.end(); ++iter)
158 int y = *iter / map8S.cols;
159 int x = *iter - y*map8S.cols;
160 cv::Vec2f * ptr = empty.ptr<cv::Vec2f>();
161 ptr[i][0] = (float(x))*cellSize + xMin;
162 ptr[i][1] = (float(y))*cellSize + yMin;
168 if(scanMaxRange > cellSize)
192 const std::map<int, Transform> & posesIn,
193 const std::map<
int, std::pair<cv::Mat, cv::Mat> > & occupancy,
199 float footprintRadius)
202 UDEBUG(
"cellSize=%f m, minMapSize=%f m, erode=%d", cellSize, minMapSize, erode?1:0);
205 std::map<int, cv::Mat> emptyLocalMaps;
206 std::map<int, cv::Mat> occupiedLocalMaps;
208 std::list<std::pair<int, Transform> > poses;
210 for(std::map<int, Transform>::const_reverse_iterator iter = posesIn.rbegin(); iter!=posesIn.rend(); ++iter)
214 poses.push_front(*iter);
218 poses.push_back(*iter);
222 float minX=-minMapSize/2.0, minY=-minMapSize/2.0, maxX=minMapSize/2.0, maxY=minMapSize/2.0;
223 bool undefinedSize = minMapSize == 0.0f;
224 for(std::list<std::pair<int, Transform> >::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
226 UASSERT(!iter->second.isNull());
228 float x = iter->second.x();
229 float y =iter->second.y();
234 undefinedSize =
false;
251 const std::pair<cv::Mat, cv::Mat> & pair = occupancy.at(iter->first);
256 if(pair.first.rows > 1 && pair.first.cols == 1)
258 UFATAL(
"Occupancy local maps should be 1 row and X cols! (rows=%d cols=%d)", pair.first.rows, pair.first.cols);
260 cv::Mat ground(1, pair.first.cols, CV_32FC2);
261 for(
int i=0; i<ground.cols; ++i)
263 const float * vi = pair.first.ptr<
float>(0,i);
264 float * vo = ground.ptr<
float>(0,i);
266 if(pair.first.channels() != 2 && pair.first.channels() != 5)
278 else if(maxX < vo[0])
283 else if(maxY < vo[1])
286 emptyLocalMaps.insert(std::make_pair(iter->first, ground));
292 if(pair.second.rows > 1 && pair.second.cols == 1)
294 UFATAL(
"Occupancy local maps should be 1 row and X cols! (rows=%d cols=%d)", pair.second.rows, pair.second.cols);
296 cv::Mat obstacles(1, pair.second.cols, CV_32FC2);
297 for(
int i=0; i<obstacles.cols; ++i)
299 const float * vi = pair.second.ptr<
float>(0,i);
300 float * vo = obstacles.ptr<
float>(0,i);
302 if(pair.second.channels() != 2 && pair.second.channels() != 5)
314 else if(maxX < vo[0])
319 else if(maxY < vo[1])
322 occupiedLocalMaps.insert(std::make_pair(iter->first, obstacles));
329 if(minX != maxX && minY != maxY)
332 float margin = cellSize*10.0f;
335 float xMax = maxX+margin;
336 float yMax = maxY+margin;
337 if(fabs((yMax - yMin) / cellSize) > 30000 ||
338 fabs((xMax - xMin) / cellSize) > 30000)
340 UERROR(
"Large map size!! map min=(%f, %f) max=(%f,%f). " 341 "There's maybe an error with the poses provided! The map will not be created!",
342 xMin, yMin, xMax, yMax);
346 UDEBUG(
"map min=(%f, %f) max=(%f,%f)", xMin, yMin, xMax, yMax);
349 map = cv::Mat::ones((yMax - yMin) / cellSize, (xMax - xMin) / cellSize, CV_8S)*-1;
350 for(std::list<std::pair<int, Transform> >::const_iterator kter = poses.begin(); kter!=poses.end(); ++kter)
352 std::map<int, cv::Mat >::iterator iter = emptyLocalMaps.find(kter->first);
353 std::map<int, cv::Mat >::iterator jter = occupiedLocalMaps.find(kter->first);
354 if(iter!=emptyLocalMaps.end())
356 for(
int i=0; i<iter->second.cols; ++i)
358 float * ptf = iter->second.ptr<
float>(0, i);
359 cv::Point2i pt((ptf[0]-xMin)/cellSize, (ptf[1]-yMin)/cellSize);
360 UASSERT_MSG(pt.y>0 && pt.y<map.rows && pt.x>0 && pt.x<map.cols,
361 uFormat(
"id=%d, map min=(%f, %f) max=(%f,%f) map=%dx%d pt=(%d,%d)", kter->first, xMin, yMin, xMax, yMax, map.cols, map.rows, pt.x, pt.y).c_str());
362 char & value = map.at<
char>(pt.y, pt.x);
370 if(footprintRadius >= cellSize*1.5
f)
373 cv::Point2i ptBegin((kter->second.x()-footprintRadius-xMin)/cellSize, (kter->second.y()-footprintRadius-yMin)/cellSize);
374 cv::Point2i ptEnd((kter->second.x()+footprintRadius-xMin)/cellSize, (kter->second.y()+footprintRadius-yMin)/cellSize);
377 if(ptEnd.x >= map.cols)
378 ptEnd.x = map.cols-1;
382 if(ptEnd.y >= map.rows)
383 ptEnd.y = map.rows-1;
384 for(
int i=ptBegin.x; i<ptEnd.x; ++i)
386 for(
int j=ptBegin.y; j<ptEnd.y; ++j)
388 map.at<
char>(j, i) = -2;
393 if(jter!=occupiedLocalMaps.end())
395 for(
int i=0; i<jter->second.cols; ++i)
397 float * ptf = jter->second.ptr<
float>(0, i);
398 cv::Point2i pt((ptf[0]-xMin)/cellSize, (ptf[1]-yMin)/cellSize);
399 UASSERT_MSG(pt.y>0 && pt.y<map.rows && pt.x>0 && pt.x<map.cols,
400 uFormat(
"id=%d: map min=(%f, %f) max=(%f,%f) map=%dx%d pt=(%d,%d)", kter->first, xMin, yMin, xMax, yMax, map.cols, map.rows, pt.x, pt.y).c_str());
401 char & value = map.at<
char>(pt.y, pt.x);
413 cv::Mat updatedMap = map.clone();
414 std::list<std::pair<int, int> > obstacleIndices;
415 for(
int i=0; i<map.rows; ++i)
417 for(
int j=0; j<map.cols; ++j)
419 if(map.at<
char>(i, j) == -2)
421 updatedMap.at<
char>(i, j) = 0;
424 if(i >=2 && i<map.rows-2 && j>=2 && j<map.cols-2)
426 if(map.at<
char>(i, j) == -1 &&
427 map.at<
char>(i+1, j) != -1 &&
428 map.at<
char>(i-1, j) != -1 &&
429 map.at<
char>(i, j+1) != -1 &&
430 map.at<
char>(i, j-1) != -1)
432 updatedMap.at<
char>(i, j) = 0;
434 else if(map.at<
char>(i, j) == 100)
438 if((map.at<
char>(i-1, j) == 0 || map.at<
char>(i-1, j) == -2) &&
439 map.at<
char>(i-2, j) == -1)
441 updatedMap.at<
char>(i-1, j) = -1;
443 else if((map.at<
char>(i+1, j) == 0 || map.at<
char>(i+1, j) == -2) &&
444 map.at<
char>(i+2, j) == -1)
446 updatedMap.at<
char>(i+1, j) = -1;
448 if((map.at<
char>(i, j-1) == 0 || map.at<
char>(i, j-1) == -2) &&
449 map.at<
char>(i, j-2) == -1)
451 updatedMap.at<
char>(i, j-1) = -1;
453 else if((map.at<
char>(i, j+1) == 0 || map.at<
char>(i, j+1) == -2) &&
454 map.at<
char>(i, j+2) == -1)
456 updatedMap.at<
char>(i, j+1) = -1;
461 obstacleIndices.push_back(std::make_pair(i, j));
464 else if(map.at<
char>(i, j) == 0)
467 if(map.at<
char>(i-1, j) == 100 &&
468 map.at<
char>(i+1, j) == 100)
470 updatedMap.at<
char>(i, j) = -1;
472 else if(map.at<
char>(i, j-1) == 100 &&
473 map.at<
char>(i, j+1) == 100)
475 updatedMap.at<
char>(i, j) = -1;
486 cv::Mat erodedMap = map.clone();
487 for(std::list<std::pair<int,int> >::iterator iter = obstacleIndices.begin();
488 iter!= obstacleIndices.end();
492 int j = iter->second;
493 int touchEmpty = (map.at<
char>(i+1, j) == 0?1:0) +
494 (map.at<
char>(i-1, j) == 0?1:0) +
495 (map.at<
char>(i, j+1) == 0?1:0) +
496 (map.at<
char>(i, j-1) == 0?1:0);
497 if(touchEmpty>=3 && map.at<
char>(i+1, j) != -1 &&
498 map.at<
char>(i-1, j) != -1 &&
499 map.at<
char>(i, j+1) != -1 &&
500 map.at<
char>(i, j-1) != -1)
502 erodedMap.at<
char>(i, j) = 0;
529 const std::map<
int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
531 bool unknownSpaceFilled,
537 std::map<int, cv::Point3f > viewpoints;
538 std::map<int, std::pair<cv::Mat, cv::Mat> > scansCv;
539 for(std::map<
int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::const_iterator iter = scans.begin(); iter!=scans.end(); ++iter)
555 const std::map<
int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
556 const std::map<int, cv::Point3f > & viewpoints,
558 bool unknownSpaceFilled,
564 std::map<int, std::pair<cv::Mat, cv::Mat> > scansCv;
565 for(std::map<
int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::const_iterator iter = scans.begin(); iter!=scans.end(); ++iter)
596 const std::map<
int, std::pair<cv::Mat, cv::Mat> > & scans,
597 const std::map<int, cv::Point3f > & viewpoints,
599 bool unknownSpaceFilled,
605 UDEBUG(
"poses=%d, scans = %d scanMaxRange=%f", poses.size(), scans.size(), scanMaxRange);
608 std::map<int, std::pair<cv::Mat, cv::Mat> > localScans;
610 pcl::PointCloud<pcl::PointXYZ> minMax;
611 if(minMapSize > 0.0
f)
613 minMax.push_back(pcl::PointXYZ(-minMapSize/2.0, -minMapSize/2.0, 0));
614 minMax.push_back(pcl::PointXYZ(minMapSize/2.0, minMapSize/2.0, 0));
616 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
618 std::map<int, std::pair<cv::Mat, cv::Mat> >::const_iterator jter=scans.find(iter->first);
619 if(jter!=scans.end() && (jter->second.first.cols || jter->second.second.cols))
621 UASSERT(!iter->second.isNull());
628 minMax.push_back(min);
629 minMax.push_back(max);
634 minMax.push_back(min);
635 minMax.push_back(max);
637 minMax.push_back(pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z()));
639 std::map<int, cv::Point3f>::const_iterator kter=viewpoints.find(iter->first);
640 if(kter!=viewpoints.end())
642 minMax.push_back(pcl::PointXYZ(iter->second.x()+kter->second.x, iter->second.y()+kter->second.y, iter->second.z()+kter->second.z));
645 localScans.insert(std::make_pair(iter->first, std::make_pair(hit, noHit)));
657 float margin = cellSize*10.0f;
658 xMin = (unknownSpaceFilled && scanMaxRange > 0 && -scanMaxRange < min.x?-scanMaxRange:min.x) - margin;
659 yMin = (unknownSpaceFilled && scanMaxRange > 0 && -scanMaxRange < min.y?-scanMaxRange:min.y) - margin;
660 float xMax = (unknownSpaceFilled && scanMaxRange > 0 && scanMaxRange > max.x?scanMaxRange:max.x) + margin;
661 float yMax = (unknownSpaceFilled && scanMaxRange > 0 && scanMaxRange > max.y?scanMaxRange:max.y) + margin;
663 UDEBUG(
"map min=(%fm, %fm) max=(%fm,%fm) (margin=%fm, cellSize=%fm, scan range=%f, min=[%fm,%fm] max=[%fm,%fm])",
664 xMin, yMin, xMax, yMax, margin, cellSize, scanMaxRange, min.x, min.y, max.x, max.y);
668 map = cv::Mat::ones((yMax - yMin) / cellSize, (xMax - xMin) / cellSize, CV_8S)*-1;
669 UDEBUG(
"map size = %dx%d", map.cols, map.rows);
672 float scanMaxRangeSqr = scanMaxRange * scanMaxRange;
673 for(std::map<
int, std::pair<cv::Mat, cv::Mat> >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
675 const Transform & pose = poses.at(iter->first);
676 cv::Point3f viewpoint(0,0,0);
677 std::map<int, cv::Point3f>::const_iterator kter=viewpoints.find(iter->first);
678 if(kter!=viewpoints.end())
680 viewpoint = kter->second;
682 cv::Point2i start(((pose.
x()+viewpoint.x)-xMin)/cellSize, ((pose.
y()+viewpoint.y)-yMin)/cellSize);
685 for(
int i=0; i<iter->second.first.cols; ++i)
687 const float * ptr = iter->second.first.ptr<
float>(0, i);
688 bool ignore = scanMaxRange>cellSize &&
uNormSquared(ptr[0]-(pose.
x()+viewpoint.x)+cellSize, ptr[1]-(pose.
y()+viewpoint.y)+cellSize) > scanMaxRangeSqr;
691 cv::Point2i end((ptr[0]-xMin)/cellSize, (ptr[1]-yMin)/cellSize);
694 map.at<
char>(end.y, end.x) = 100;
700 for(
int i=0; i<iter->second.first.cols; ++i)
702 const float * ptr = iter->second.first.ptr<
float>(0, i);
704 cv::Vec2f pt(ptr[0], ptr[1]);
705 if(scanMaxRange>cellSize)
707 cv::Vec2f v(pt[0]-(pose.
x()+viewpoint.x), pt[1]-(pose.
y()+viewpoint.y));
708 float n = cv::norm(v);
709 if(n > scanMaxRange+cellSize)
711 v = (v/n) * scanMaxRange;
712 pt[0] = pose.
x()+viewpoint.x + v[0];
713 pt[1] = pose.
y()+viewpoint.y + v[1];
717 cv::Point2i end((pt[0]-xMin)/cellSize, (pt[1]-yMin)/cellSize);
720 if(localScans.size() > 1 || map.at<
char>(end.y, end.x) != 0)
727 for(
int i=0; i<iter->second.second.cols; ++i)
729 const float * ptr = iter->second.second.ptr<
float>(0, i);
731 cv::Vec2f pt(ptr[0], ptr[1]);
732 if(scanMaxRange>cellSize)
734 cv::Vec2f v(pt[0]-(pose.
x()+viewpoint.x), pt[1]-(pose.
y()+viewpoint.y));
735 float n = cv::norm(v);
736 if(n > scanMaxRange+cellSize)
738 v = (v/n) * scanMaxRange;
739 pt[0] = pose.
x()+viewpoint.x + v[0];
740 pt[1] = pose.
y()+viewpoint.y + v[1];
744 cv::Point2i end((pt[0]-xMin)/cellSize, (pt[1]-yMin)/cellSize);
747 if(localScans.size() > 1 || map.at<
char>(end.y, end.x) != 0)
750 if(map.at<
char>(end.y, end.x) == -1)
752 map.at<
char>(end.y, end.x) = 0;
759 UDEBUG(
"Ray trace known space=%fs", timer.
ticks());
762 if(unknownSpaceFilled && scanMaxRange > 0)
765 float a = CV_PI/256.0f;
766 for(std::map<
int, std::pair<cv::Mat, cv::Mat> >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
768 if(iter->second.first.cols > 1)
770 if(scanMaxRange > cellSize)
772 const Transform & pose = poses.at(iter->first);
773 cv::Point3f viewpoint(0,0,0);
774 std::map<int, cv::Point3f>::const_iterator kter=viewpoints.find(iter->first);
775 if(kter!=viewpoints.end())
777 viewpoint = kter->second;
779 cv::Point2i start(((pose.
x()+viewpoint.x)-xMin)/cellSize, ((pose.
y()+viewpoint.y)-yMin)/cellSize);
786 cv::Mat origin(2,1,CV_32F), endFirst(2,1,CV_32F), endLast(2,1,CV_32F);
787 origin.at<
float>(0) = pose.
x()+viewpoint.x;
788 origin.at<
float>(1) = pose.
y()+viewpoint.y;
789 endFirst.at<
float>(0) = iter->second.first.ptr<
float>(0,0)[0];
790 endFirst.at<
float>(1) = iter->second.first.ptr<
float>(0,0)[1];
791 endLast.at<
float>(0) = iter->second.first.ptr<
float>(0,iter->second.first.cols-1)[0];
792 endLast.at<
float>(1) = iter->second.first.ptr<
float>(0,iter->second.first.cols-1)[1];
796 cv::Mat tmp = (endFirst - origin);
797 cv::Mat endRotated = rotation*((tmp/cv::norm(tmp))*scanMaxRange) + origin;
798 cv::Mat endLastVector(3,1,CV_32F), endRotatedVector(3,1,CV_32F);
799 endLastVector.at<
float>(0) = endLast.at<
float>(0) - origin.at<
float>(0);
800 endLastVector.at<
float>(1) = endLast.at<
float>(1) - origin.at<
float>(1);
801 endLastVector.at<
float>(2) = 0.0
f;
802 endRotatedVector.at<
float>(0) = endRotated.at<
float>(0) - origin.at<
float>(0);
803 endRotatedVector.at<
float>(1) = endRotated.at<
float>(1) - origin.at<
float>(1);
804 endRotatedVector.at<
float>(2) = 0.0
f;
806 float normEndRotatedVector = cv::norm(endRotatedVector);
807 endLastVector = endLastVector / cv::norm(endLastVector);
808 float angle = (endRotatedVector/normEndRotatedVector).
dot(endLastVector);
809 angle = angle<-1.0f?-1.0f:angle>1.0f?1.0f:
angle;
810 while(
acos(angle) > M_PI_4 || endRotatedVector.cross(endLastVector).at<
float>(2) > 0.0
f)
812 cv::Point2i end((endRotated.at<
float>(0)-xMin)/cellSize, (endRotated.at<
float>(1)-yMin)/cellSize);
814 end.x = end.x < 0?0:end.x;
815 end.x = end.x >= map.cols?map.cols-1:end.x;
816 end.y = end.y < 0?0:end.y;
817 end.y = end.y >= map.rows?map.rows-1:end.y;
820 endRotated = rotation*(endRotated - origin) + origin;
821 endRotatedVector.at<
float>(0) = endRotated.at<
float>(0) - origin.at<
float>(0);
822 endRotatedVector.at<
float>(1) = endRotated.at<
float>(1) - origin.at<
float>(1);
823 angle = (endRotatedVector/normEndRotatedVector).
dot(endLastVector);
824 angle = angle<-1.0f?-1.0f:angle>1.0f?1.0f:
angle;
844 void rayTrace(
const cv::Point2i & start,
const cv::Point2i & end, cv::Mat & grid,
bool stopOnObstacle)
846 UASSERT_MSG(start.x >= 0 && start.x < grid.cols,
uFormat(
"start.x=%d grid.cols=%d", start.x, grid.cols).c_str());
847 UASSERT_MSG(start.y >= 0 && start.y < grid.rows,
uFormat(
"start.y=%d grid.rows=%d", start.y, grid.rows).c_str());
848 UASSERT_MSG(end.x >= 0 && end.x < grid.cols,
uFormat(
"end.x=%d grid.cols=%d", end.x, grid.cols).c_str());
849 UASSERT_MSG(end.y >= 0 && end.y < grid.rows,
uFormat(
"end.x=%d grid.cols=%d", end.y, grid.rows).c_str());
851 cv::Point2i ptA, ptB;
855 float slope = float(ptB.y - ptA.y)/float(ptB.x - ptA.x);
857 bool swapped =
false;
858 if(slope<-1.0f || slope>1.0
f)
874 float b = ptA.y - slope*ptA.x;
875 for(
int x=ptA.x; ptA.x<ptB.x?x<ptB.x:x>ptB.x; ptA.x<ptB.x?++x:--x)
877 int upperbound = float(x)*slope + b;
878 int lowerbound = upperbound;
881 lowerbound = (ptA.x<ptB.x?x+1:x-1)*slope + b;
884 if(lowerbound > upperbound)
886 int tmp = upperbound;
887 upperbound = lowerbound;
893 UASSERT_MSG(lowerbound >= 0 && lowerbound < grid.rows,
uFormat(
"lowerbound=%f grid.rows=%d x=%d slope=%f b=%f x=%f", lowerbound, grid.rows, x, slope, b, x).c_str());
894 UASSERT_MSG(upperbound >= 0 && upperbound < grid.rows,
uFormat(
"upperbound=%f grid.rows=%d x+1=%d slope=%f b=%f x=%f", upperbound, grid.rows, x+1, slope, b, x).c_str());
898 UASSERT_MSG(lowerbound >= 0 && lowerbound < grid.cols,
uFormat(
"lowerbound=%f grid.cols=%d x=%d slope=%f b=%f x=%f", lowerbound, grid.cols, x, slope, b, x).c_str());
899 UASSERT_MSG(upperbound >= 0 && upperbound < grid.cols,
uFormat(
"upperbound=%f grid.cols=%d x+1=%d slope=%f b=%f x=%f", upperbound, grid.cols, x+1, slope, b, x).c_str());
902 for(
int y = lowerbound; y<=(int)upperbound; ++y)
907 v = &grid.at<
char>(x, y);
911 v = &grid.at<
char>(y, x);
913 if(*v == 100 && stopOnObstacle)
928 UASSERT(map8S.channels() == 1 && map8S.type() == CV_8S);
929 cv::Mat map8U = cv::Mat(map8S.rows, map8S.cols, CV_8U);
930 for (
int i = 0; i < map8S.rows; ++i)
932 for (
int j = 0; j < map8S.cols; ++j)
934 char v = pgmFormat?map8S.at<
char>((map8S.rows-1)-i, j):map8S.at<
char>(i, j);
938 gray = pgmFormat?254:178;
946 gray = pgmFormat?254:200;
950 gray = pgmFormat?205:89;
952 map8U.at<
unsigned char>(i, j) = gray;
961 UASSERT_MSG(map8U.channels() == 1 && map8U.type() == CV_8U,
uFormat(
"map8U.channels()=%d map8U.type()=%d", map8U.channels(), map8U.type()).c_str());
962 cv::Mat map8S = cv::Mat(map8U.rows, map8U.cols, CV_8S);
963 for (
int i = 0; i < map8U.rows; ++i)
965 for (
int j = 0; j < map8U.cols; ++j)
967 unsigned char v = pgmFormat?map8U.at<
char>((map8U.rows-1)-i, j):map8U.at<
char>(i, j);
1004 map8S.at<
char>(i, j) = occupancy;
1012 UASSERT(map.type() == CV_8SC1);
1013 cv::Mat erodedMap = map.clone();
1014 for(
int i=0; i<map.rows; ++i)
1016 for(
int j=0; j<map.cols; ++j)
1018 if(map.at<
char>(i, j) == 100)
1021 int touchEmpty = (map.at<
char>(i+1, j) == 0?1:0) +
1022 (map.at<
char>(i-1, j) == 0?1:0) +
1023 (map.at<
char>(i, j+1) == 0?1:0) +
1024 (map.at<
char>(i, j-1) == 0?1:0);
1026 if(touchEmpty>=3 && map.at<
char>(i+1, j) != -1 &&
1027 map.at<
char>(i-1, j) != -1 &&
1028 map.at<
char>(i, j+1) != -1 &&
1029 map.at<
char>(i, j-1) != -1)
1031 erodedMap.at<
char>(i, j) = 0;
cv::Mat RTABMAP_EXP erodeMap(const cv::Mat &map)
cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(const std::map< int, Transform > &poses, const std::map< int, std::pair< cv::Mat, cv::Mat > > &occupancy, float cellSize, float &xMin, float &yMin, float minMapSize=0.0f, bool erode=false, float footprintRadius=0.0f)
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
const cv::Mat & data() const
void RTABMAP_EXP getMinMax3D(const cv::Mat &laserScan, cv::Point3f &min, cv::Point3f &max)
cv::Mat RTABMAP_EXP create2DMap(const std::map< int, Transform > &poses, const std::map< int, std::pair< cv::Mat, cv::Mat > > &scans, const std::map< int, cv::Point3f > &viewpoints, float cellSize, bool unknownSpaceFilled, float &xMin, float &yMin, float minMapSize=0.0f, float scanMaxRange=0.0f)
void RTABMAP_EXP occupancy2DFromLaserScan(const cv::Mat &scanHit, const cv::Mat &scanNoHit, const cv::Point3f &viewpoint, cv::Mat &empty, cv::Mat &occupied, float cellSize, bool unknownSpaceFilled=false, float scanMaxRange=0.0f)
Basic mathematics functions.
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
Some conversion functions.
#define UASSERT(condition)
GLM_FUNC_DECL genType cos(genType const &angle)
Wrappers of STL for convenient functions.
GLM_FUNC_DECL genType sin(genType const &angle)
#define UASSERT_MSG(condition, msg_str)
LaserScan RTABMAP_EXP transformLaserScan(const LaserScan &laserScan, const Transform &transform)
cv::Mat RTABMAP_EXP convertImage8U2Map(const cv::Mat &map8U, bool pgmFormat=false)
bool uContains(const std::list< V > &list, const V &value)
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
cv::Mat RTABMAP_EXP convertMap2Image8U(const cv::Mat &map8S, bool pgmFormat=false)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
T uNormSquared(const std::vector< T > &v)
GLM_FUNC_DECL T dot(vecType< T, P > const &x, vecType< T, P > const &y)
ULogger class and convenient macros.
GLM_FUNC_DECL genType acos(genType const &x)
LaserScan RTABMAP_EXP rangeFiltering(const LaserScan &scan, float rangeMin, float rangeMax)
void RTABMAP_EXP rayTrace(const cv::Point2i &start, const cv::Point2i &end, cv::Mat &grid, bool stopOnObstacle)
std::string UTILITE_EXP uFormat(const char *fmt,...)
static LaserScan backwardCompatibility(const cv::Mat &oldScanFormat, int maxPoints=0, int maxRange=0, const Transform &localTransform=Transform::getIdentity())
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 &cloud, bool filterNaNs=true, bool is2D=false, const Transform &transform=Transform())