/** * This file is part of ORB-SLAM2. * * Copyright (C) 2014-2016 Raúl Mur-Artal (University of Zaragoza) * For more information see * * ORB-SLAM2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ORB-SLAM2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ORB-SLAM2. If not, see . */ #include #include #include #include #include #include #include #include // #include // #include // #include // #include #include // #include // #include #include using namespace std; void LoadLabel(const string &strLabelFilename, vector> &vvLabel); void LoadImages(const string &strPathToSequence, vector &vstrImageLeft, vector &vstrImageRight, vector &vstrlabel, vector &vTimestamps); // pcl::PointCloud::Ptr BEV_GEN(const cv::String &strFile, cv::Mat &BEV_IMG); int main(int argc, char **argv) { if (argc != 6) { cerr << endl << "Usage: ./stereo_kitti path_to_vocabulary path_to_settings path_to_sequence path_to_RGB path_to_cloud" << endl; return 1; } // Retrieve paths to images vector vstrImageLeft; vector vstrImageRight; vector vTimestamps; vector vstrlabel; LoadImages(string(argv[3]), vstrImageLeft, vstrImageRight, vstrlabel, vTimestamps); std::vector fn_cloud, fn_img, fn_label; cv::String pattern_img = string(argv[4]); cv::String pattern_cloud = string(argv[5]); glob(pattern_cloud, fn_cloud, false); glob(pattern_img, fn_img, false); cout << "读取成功" << endl; const int nImages = vstrImageLeft.size(); // Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM2::System SLAM(argv[1], argv[2], ORB_SLAM2::System::STEREO, true); SLAM.mpSemantic_Maper->mvpointcloud_adress = fn_cloud; SLAM.mpSemantic_Maper->mvRGBIMG_adress = fn_img; // Vector for tracking time statistics vector vTimesTrack; vTimesTrack.resize(nImages); cout << endl << "-------" << endl; cout << "Start processing sequence ..." << endl; cout << "Images in the sequence: " << nImages << endl << endl; // Main loop cv::Mat imLeft, imRight; cv::String pattern = string(argv[4]); std::vector fn; glob(pattern, fn, false); for (int ni = 0; ni < nImages; ni++) { cv::Mat imbev; // pcl::PointCloud::Ptr tmp; // 保存的原始点云数据,pcl格式 // tmp = BEV_GEN(fn[ni], imbev); // imRGB为BEV视图 vector> vvLabel; // Read left and right images from file imLeft = cv::imread(vstrImageLeft[ni], CV_LOAD_IMAGE_UNCHANGED); imRight = cv::imread(vstrImageRight[ni], CV_LOAD_IMAGE_UNCHANGED); LoadLabel(vstrlabel[ni], vvLabel); SLAM.mpSemantic_Maper->mvvvLabel.push_back(vvLabel); double tframe = vTimestamps[ni]; if (imLeft.empty()) { cerr << endl << "Failed to load image at: " << string(vstrImageLeft[ni]) << endl; return 1; } #ifdef COMPILEDWITHC11 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); #else std::chrono::monotonic_clock::time_point t1 = std::chrono::monotonic_clock::now(); #endif // Pass the images to the SLAM system double delta_t = 0.1; if (ni > 0) { delta_t = vTimestamps[ni] - vTimestamps[ni - 1]; } SLAM.TrackStereo(imLeft, imRight, tframe, vvLabel, imbev, delta_t); #ifdef COMPILEDWITHC11 std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); #else std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now(); #endif double ttrack = std::chrono::duration_cast>(t2 - t1).count(); vTimesTrack[ni] = ttrack; // Wait to load the next frame double T = 0; if (ni < nImages - 1) T = vTimestamps[ni + 1] - tframe; else if (ni > 0) T = tframe - vTimestamps[ni - 1]; if (ttrack < T) usleep((T - ttrack) * 1e6); } // Stop all threads SLAM.Shutdown(); // Tracking time statistics sort(vTimesTrack.begin(), vTimesTrack.end()); float totaltime = 0; for (int ni = 0; ni < nImages; ni++) { totaltime += vTimesTrack[ni]; } cout << "-------" << endl << endl; cout << "median tracking time: " << vTimesTrack[nImages / 2] << endl; cout << "mean tracking time: " << totaltime / nImages << endl; // Save camera trajectory SLAM.SaveTrajectoryKITTI("CameraTrajectory.txt"); return 0; } /* pcl::PointCloud::Ptr BEV_GEN(const cv::String &strFile, cv::Mat &BEV_IMG) { int32_t num = 1000000; float *data = (float *)malloc(num * sizeof(float)); // void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。 // pointers float *px = data + 0; float *py = data + 1; float *pz = data + 2; float *pr = data + 3; // load point cloud pcl::PointCloud::Ptr point_cloud(new pcl::PointCloud()); FILE *stream; std::string Filename = strFile; char ch[200]; strcpy(ch, Filename.c_str()); stream = fopen(ch, "rb"); num = fread(data, sizeof(float), num, stream) / 4; point_cloud->width = num; // 设定长 point_cloud->height = 1; // 设定高 point_cloud->is_dense = false; // 如果没有无效点(例如,具有NaN或Inf值),则为True for (int32_t i = 0; i < num; i++) { // vector point_cloud; pcl::PointXYZI point; point.x = *px; point.y = *py; point.z = *pz; point.intensity = *pr; point_cloud->points.push_back(point); px += 4; py += 4; pz += 4; pr += 4; } fclose(stream); free(data); // 释放内存 pcl::PointCloud::Ptr point_cloud_new(new pcl::PointCloud()); for (int i = 0; i < point_cloud->points.size(); i++) { if (point_cloud->points[i].x > 0 && point_cloud->points[i].x < 50 && point_cloud->points[i].y > -25 && point_cloud->points[i].y < 25 && point_cloud->points[i].z > -0.8 && point_cloud->points[i].z < 1.3) { point_cloud_new->push_back(point_cloud->points[i]); // cout<points[j].x<::Ptr cloud_Curvature(new pcl::PointCloud); pcl::copyPointCloud(*point_cloud_new, *cloud_Curvature); // src中的xyz覆盖掉src_PN中的xyz值,然后把xyz+normal的信息给src_PN // MaxCurvaturePoints(point_cloud_new, cloud_Curvature); //点云曲率 // point_cloud_new->points. // 可视化 int Height = 608 + 1; int Width = (608 + 1); float Discretization = 50.0 / 608.0; // pcl::PointCloud::Ptr point_cloud_new_ = *point_cloud_new; cv::Mat height_map = cv::Mat::zeros(608, 608, CV_8UC1); cv::Mat intensityMap = cv::Mat::zeros(608, 608, CV_8UC1); cv::Mat densityMap = cv::Mat::zeros(608, 608, CV_8UC1); cv::Mat CurvatureMap = cv::Mat::zeros(608, 608, CV_8UC1); vector>> PointCloud_frac(608, vector>(608, vector())); for (int i = 0; i < point_cloud_new->points.size(); i++) { point_cloud_new->points[i].y = (floor(point_cloud_new->points[i].y / Discretization) + Height / 2); point_cloud_new->points[i].x = (floor(point_cloud_new->points[i].x / Discretization)); cloud_Curvature->points[i].y = (floor(cloud_Curvature->points[i].y / Discretization) + Height / 2); cloud_Curvature->points[i].x = (floor(cloud_Curvature->points[i].x / Discretization)); // cout<<"int(point_cloud_new->points[i].x " <points[i].x << "int(point_cloud_new->points[i].y " <points[i].y <points[i].z + 1.2; p.y = point_cloud_new->points[i].intensity; // p.z = cloud_Curvature->points[i].intensity; //曲率 p.z = cloud_Curvature->points[i].intensity; PointCloud_frac[int(point_cloud_new->points[i].x)][int(point_cloud_new->points[i].y)].push_back(p); } // for(int i =0;i<608;i++) // { // for(int j =0;j<1218;j++) // // cout<<"poincloud _size " << PointCloud_frac[i][j].size()< 0) { vector temp_h, temp_I, temp_c; for (int k = 0; k < PointCloud_frac[i][j].size(); k++) { temp_h.push_back(PointCloud_frac[i][j][k].x); temp_I.push_back(PointCloud_frac[i][j][k].y); temp_c.push_back(PointCloud_frac[i][j][k].z); } height_map.at(i, j) = (int)(*max_element(temp_h.begin(), temp_h.end()) / 2.1 * 255.0); intensityMap.at(i, j) = (int)(*max_element(temp_I.begin(), temp_I.end()) * 255.0); densityMap.at(i, j) = (int)(min(1.0, log10(temp_h.size() + 1) / log10(64)) * 255.0); CurvatureMap.at(i, j) = (int)min(255.0, (10000 * (*max_element(temp_c.begin(), temp_c.end())) * 255.0)); } } } vector vimg; vimg.push_back(intensityMap); vimg.push_back(height_map); vimg.push_back(densityMap); // vimg.push_back(intensityMap); // vimg.push_back(height_map); // vimg.push_back(CurvatureMap); cv::merge(vimg, BEV_IMG); cv::flip(BEV_IMG, BEV_IMG, 0); cv::flip(BEV_IMG, BEV_IMG, 1); return point_cloud; } */ void LoadImages(const string &strPathToSequence, vector &vstrImageLeft, vector &vstrImageRight, vector &vstrlabel, vector &vTimestamps) { ifstream fTimes; string strPathTimeFile = strPathToSequence + "/times.txt"; fTimes.open(strPathTimeFile.c_str()); while (!fTimes.eof()) { string s; getline(fTimes, s); if (!s.empty()) { stringstream ss; ss << s; double t; ss >> t; vTimestamps.push_back(t); } } cout << "读取times.txt完成" << endl; // 用于kitti-odom string strPrefixLeft = strPathToSequence + "/image_0/"; string strPrefixRight = strPathToSequence + "/image_1/"; // 用于kitti-raw // string strPrefixLeft = strPathToSequence + "/image_00/"; // string strPrefixRight = strPathToSequence + "/image_01/"; string strlabel = strPathToSequence + "/labels/"; const int nTimes = vTimestamps.size(); vstrImageLeft.resize(nTimes); vstrImageRight.resize(nTimes); vstrlabel.resize(nTimes); for (int i = 0; i < nTimes; i++) { stringstream ss; // 用于kitti-odom ss << setfill('0') << setw(6) << i; // 用于kitti-raw // ss << setfill('0') << setw(10) << i; vstrImageLeft[i] = strPrefixLeft + ss.str() + ".png"; vstrImageRight[i] = strPrefixRight + ss.str() + ".png"; // vstrlabel[i] = strlabel + ss.str() + ".txt"; } for (int i = 0; i < nTimes; i++) { stringstream ss; ss << setfill('0') << setw(6) << i; vstrlabel[i] = strlabel + ss.str() + ".txt"; } /*for (int i = 0; i < nTimes; i++) { stringstream ss; ss << setfill('0') << setw(6) << i; vstrlabel[i] = strlabel + ss.str() + ".txt"; }*/ } void LoadLabel(const string &strLabelFilename, vector> &vvLabel) { ifstream fAssociation; fAssociation.open(strLabelFilename.c_str()); while (!fAssociation.eof()) { string s; getline(fAssociation, s); if (!s.empty()) { stringstream ss; ss << s; double cls, x, y, w, h, im, re, yaw; vector label; ss >> cls; label.push_back(cls); ss >> x; x = 608 - x; label.push_back(x); ss >> y; y = 608 - y; label.push_back(y); ss >> w; label.push_back(w); ss >> h; label.push_back(h); ss >> im; label.push_back(im); ss >> re; label.push_back(re); ss >> yaw; label.push_back(yaw); vvLabel.push_back(label); } } }