Apollo 11.0
自动驾驶开放平台
offline_lidar_detection.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#include <memory>
18#include <string>
19
20#include "Eigen/Dense"
21#include "gflags/gflags.h"
22
23#include "cyber/common/file.h"
30
31DEFINE_string(pcd_path, "./pcd/", "pcd path");
32DEFINE_string(output_path, "./output/", "output path");
33DEFINE_string(detector_name, "CNNSegmentation", "detector name");
34DEFINE_string(config_path, "perception/lidar_detection/data", "config path");
35DEFINE_string(config_file, "cnnseg16_param.pb.txt", "config file");
36DEFINE_string(sensor_name, "velodyne64", "sensor name");
37
38namespace apollo {
39namespace perception {
40namespace lidar {
41
43 public:
45
47
48 bool Init() {
49 BaseLidarDetector* detector =
50 BaseLidarDetectorRegisterer::GetInstanceByName(FLAGS_detector_name);
51 CHECK_NOTNULL(detector);
52 detector_.reset(detector);
53
54 LidarDetectorInitOptions detection_init_options;
55 detection_init_options.sensor_name = FLAGS_sensor_name;
56 detection_init_options.config_path = FLAGS_config_path;
57 detection_init_options.config_file = FLAGS_config_file;
58 ACHECK(detector_->Init(detection_init_options))
59 << "lidar detector init error";
60
61 ObjectBuilderInitOptions builder_init_options;
62 builder_.reset(new ObjectBuilder);
63 ACHECK(builder_->Init(builder_init_options));
64
65 return true;
66 }
67
68 bool TransformCloud(const base::PointFCloudPtr& local_cloud,
69 const Eigen::Affine3d& pose,
70 base::PointDCloudPtr world_cloud) const {
71 if (local_cloud == nullptr) {
72 return false;
73 }
74 world_cloud->clear();
75 world_cloud->reserve(local_cloud->size());
76 for (size_t i = 0; i < local_cloud->size(); ++i) {
77 auto& pt = local_cloud->at(i);
78 Eigen::Vector3d trans_point(pt.x, pt.y, pt.z);
79 trans_point = pose * trans_point;
80 base::PointD world_point;
81 world_point.x = trans_point(0);
82 world_point.y = trans_point(1);
83 world_point.z = trans_point(2);
84 world_point.intensity = pt.intensity;
85 world_cloud->push_back(world_point, local_cloud->points_timestamp(i),
86 std::numeric_limits<float>::max(),
87 local_cloud->points_beam_id()[i], 0);
88 }
89 return true;
90 }
91
92 bool Run() {
93 std::string pcd_folder = FLAGS_pcd_path;
94 std::vector<std::string> pcd_file_names;
95 if (!algorithm::GetFileList(pcd_folder, ".pcd", &pcd_file_names)) {
96 AERROR << "pcd_folder: " << pcd_folder << " get file list error.";
97 return false;
98 }
99
100 std::sort(pcd_file_names.begin(), pcd_file_names.end(),
101 [](const std::string& lhs, const std::string& rhs) {
102 if (lhs.length() != rhs.length()) {
103 return lhs.length() < rhs.length();
104 }
105 return lhs <= rhs;
106 });
107
108 for (size_t i = 0; i < pcd_file_names.size(); ++i) {
109 AINFO << "***************** Frame " << i << " ******************";
110 AINFO << pcd_file_names[i];
111
112 std::shared_ptr<LidarFrame> frame = LidarFramePool::Instance().Get();
113 if (frame->cloud == nullptr) {
114 frame->cloud = base::PointFCloudPool::Instance().Get();
115 }
116 if (frame->world_cloud == nullptr) {
117 frame->world_cloud = base::PointDCloudPool::Instance().Get();
118 }
119 LoadPCLPCD(pcd_file_names[i], frame->cloud.get());
120 // frame->lidar2world_pose is default identity matrix
121 TransformCloud(frame->cloud, frame->lidar2world_pose, frame->world_cloud);
122 AINFO << "Read point cloud from " << pcd_file_names[i]
123 << " with cloud size: " << frame->cloud->size();
124
125 LidarDetectorOptions detection_options;
126 if (!detector_->Detect(detection_options, frame.get())) {
127 AERROR << "Lidar detector detect error!";
128 return false;
129 }
130
131 ObjectBuilderOptions builder_options;
132 if (!builder_->Build(builder_options, frame.get())) {
133 AERROR << "Lidar detector, object builder error.";
134 return false;
135 }
136
137 std::string output_path = FLAGS_output_path;
138 WriteObjectsForNewBenchmark(i, frame.get(), output_path);
139 }
140
141 return true;
142 }
143
144 bool WriteObjectsForNewBenchmark(size_t frame_id, LidarFrame* frame,
145 const std::string& path) {
147 AERROR << "Failed to create: " << path;
148 return false;
149 }
150 std::ofstream fout;
151 fout.open(absl::StrCat(path, "/", frame_id, ".txt"));
152 fout << frame_id << " " << frame->segmented_objects.size() << std::endl;
153
154 for (auto& object : frame->segmented_objects) {
155 fout << "velodyne_64"
156 << " " << object->id << " " << object->track_id << " "
157 << object->lidar_supplement.is_background << " "
158 << std::setprecision(8) << object->confidence << " ";
159
160 std::string type = "unknow";
161 if (object->type == base::ObjectType::UNKNOWN ||
162 object->type == base::ObjectType::UNKNOWN_MOVABLE ||
163 object->type == base::ObjectType::UNKNOWN_UNMOVABLE) {
164 // type is unknow in this case
165 } else if (object->type == base::ObjectType::PEDESTRIAN) {
166 type = "pedestrian";
167 } else if (object->type == base::ObjectType::VEHICLE) {
168 type = "smallMot";
169 } else if (object->type == base::ObjectType::BICYCLE) {
170 type = "nonMot";
171 }
172
173 double yaw = atan2(object->direction(1), object->direction(0));
174 auto& object_cloud = object->lidar_supplement.cloud;
175
176 fout << type << " " << object->center(0) << " " << object->center(1)
177 << " " << object->center(2) << " " << object->size(0) << " "
178 << object->size(1) << " " << object->size(2) << " "
179 << yaw /*yaw*/ << " " << 0 /*roll*/ << " " << 0 /*pitch*/ << " "
180 << 0 /*truncated*/ << " " << 0 /*occluded*/ << " "
181 << object->velocity(0) << " " << object->velocity(1) << " "
182 << object->velocity(2) << " ";
183 fout << object_cloud.size() << " ";
184 for (size_t i = 0; i < object_cloud.size(); ++i) {
185 auto& pt = object_cloud.at(i);
186 fout << std::setprecision(8) << pt.x << " " << pt.y << " " << pt.z
187 << " " << pt.intensity << " ";
188 }
189 // fout << 0/*#indices*/ << " ";
190 // we save polygon here for debug
191 int polygon_size = -static_cast<int>(object->polygon.size());
192 fout << polygon_size /*negative polygon size*/ << " ";
193 for (size_t i = 0; i < object->polygon.size(); ++i) {
194 const auto& pt = object->polygon[i];
195 fout << std::setprecision(8) << pt.x << " " << pt.y << " " << pt.z
196 << " ";
197 }
198 fout << std::endl;
199 }
200
201 fout.close();
202 return true;
203 }
204
205 protected:
206 std::unique_ptr<BaseLidarDetector> detector_;
207 std::unique_ptr<ObjectBuilder> builder_;
208};
209
210} // namespace lidar
211} // namespace perception
212} // namespace apollo
213
214int main(int argc, char** argv) {
215 FLAGS_alsologtostderr = 1;
216 google::ParseCommandLineFlags(&argc, &argv, true);
217 google::InitGoogleLogging(argv[0]);
218
219 // Todo(zero): core dump when rt_net is destructed!
221 if (!test.Init()) {
222 AINFO << "Failed to setup OfflineLidarDetection";
223 return -1;
224 }
225 return test.Run() ? 0 : -1;
226}
std::shared_ptr< ObjectType > Get() override
bool TransformCloud(const base::PointFCloudPtr &local_cloud, const Eigen::Affine3d &pose, base::PointDCloudPtr world_cloud) const
bool WriteObjectsForNewBenchmark(size_t frame_id, LidarFrame *frame, const std::string &path)
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool EnsureDirectory(const std::string &directory_path)
Check if a specified directory specified by directory_path exists.
Definition file.cc:285
bool GetFileList(const std::string &path, const std::string &suffix, std::vector< std::string > *files)
Definition io_util.cc:163
std::shared_ptr< PointDCloud > PointDCloudPtr
std::shared_ptr< PointFCloud > PointFCloudPtr
bool LoadPCLPCD(const std::string &file_path, base::PointFCloud *cloud_out)
Definition pcl_util.h:54
class register implement
Definition arena_queue.h:37
int main(int argc, char **argv)
DEFINE_string(pcd_path, "./pcd/", "pcd path")
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition lidar_frame.h:53