Apollo 11.0
自动驾驶开放平台
feature_generator.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 *****************************************************************************/
17
18#include <limits>
19
22
23namespace apollo {
24namespace perception {
25namespace lidar {
26
28 base::Blob<float>* out_blob) {
29 // set output feature blob
30 out_blob_ = out_blob;
31
32 // set feature parameters
33 range_ = feature_param.point_cloud_range();
34 width_ = feature_param.width();
35 height_ = feature_param.height();
36 min_height_ = feature_param.min_height();
37 max_height_ = feature_param.max_height();
38 CHECK_EQ(width_, height_)
39 << "Current implementation version requires input_width == input_height.";
40 use_intensity_feature_ = feature_param.use_intensity_feature();
41 use_constant_feature_ = feature_param.use_constant_feature();
42
43 // set log lookup table
44 log_table_.resize(kMaxLogNum);
45 for (size_t i = 0; i < log_table_.size(); ++i) {
46 log_table_[i] = std::log(static_cast<float>(1 + i));
47 }
48
49 // set output feature blob data
50 float* out_blob_data = nullptr;
51#if USE_GPU == 1
52 log_blob_.reset(
53 new base::Blob<float>(1, 1, 1, static_cast<int>(log_table_.size())));
54 float* log_table = log_blob_->mutable_gpu_data();
55 cudaMemcpy(log_table, log_table_.data(), log_table_.size() * sizeof(float),
56 cudaMemcpyHostToDevice);
57 out_blob_data = out_blob_->mutable_gpu_data();
58#else
59 out_blob_data = out_blob_->mutable_cpu_data();
60#endif
61
62 // set raw feature data
63 int channel_index = 0;
64 max_height_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
65 mean_height_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
66 count_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
67 if (use_constant_feature_) {
68 direction_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
69 }
70 if (use_intensity_feature_) {
71 top_intensity_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
72 mean_intensity_data_ =
73 out_blob_data + out_blob_->offset(0, channel_index++);
74 }
75 if (use_constant_feature_) {
76 distance_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
77 }
78 nonempty_data_ = out_blob_data + out_blob_->offset(0, channel_index++);
79 CHECK_EQ(out_blob_->offset(0, channel_index), out_blob_->count());
80
81 // compute direction and distance features
82 if (use_constant_feature_) {
83 int map_size = height_ * width_;
84 std::vector<float> direction_data(map_size);
85 std::vector<float> distance_data(map_size);
86 for (int row = 0; row < height_; ++row) {
87 for (int col = 0; col < width_; ++col) {
88 int idx = row * width_ + col;
89 // * row <-> x, column <-> y
90 float center_x = Pixel2Pc(row, static_cast<float>(height_), range_);
91 float center_y = Pixel2Pc(col, static_cast<float>(width_), range_);
92 direction_data[idx] =
93 static_cast<float>(std::atan2(center_y, center_x) / (2.0 * kPI));
94 distance_data[idx] =
95 static_cast<float>(std::hypot(center_x, center_y) / 60.0 - 0.5);
96 }
97 }
98
99// memory copy direction and distance features
100#if USE_GPU == 1
101 cudaMemcpy(direction_data_, direction_data.data(),
102 direction_data.size() * sizeof(float), cudaMemcpyHostToDevice);
103 cudaMemcpy(distance_data_, distance_data.data(),
104 distance_data.size() * sizeof(float), cudaMemcpyHostToDevice);
105#else
106 memcpy(direction_data_, direction_data.data(),
107 direction_data.size() * sizeof(float));
108 memcpy(distance_data_, distance_data.data(),
109 distance_data.size() * sizeof(float));
110#endif
111 }
112 return true;
113}
114
115void FeatureGenerator::GenerateCPU(const base::PointFCloudPtr& pc_ptr,
116 const std::vector<int>& point2grid) {
117 // DO NOT remove this line!!!
118 // Otherwise, the gpu_data will not be updated for the later frames.
119 // It marks the head at cpu for blob.
120 out_blob_->mutable_cpu_data();
121
122 // fill initial value for feature blob
123 const int map_size = height_ * width_;
124 for (int i = 0; i < map_size; ++i) {
125 max_height_data_[i] = -5.f;
126 }
127 memset(mean_height_data_, 0, map_size * sizeof(float));
128 memset(count_data_, 0, map_size * sizeof(float));
129 memset(nonempty_data_, 0, map_size * sizeof(float));
130 if (use_intensity_feature_) {
131 memset(top_intensity_data_, 0, map_size * sizeof(float));
132 memset(mean_intensity_data_, 0, map_size * sizeof(float));
133 }
134
135 // compute features
136 for (size_t i = 0; i < pc_ptr->size(); ++i) {
137 int idx = point2grid[i];
138 if (idx == -1) {
139 continue;
140 }
141 const auto& pt = pc_ptr->at(i);
142 float pz = pt.z;
143 float pi = pt.intensity / 255.0f;
144 if (max_height_data_[idx] < pz) {
145 max_height_data_[idx] = pz;
146 if (use_intensity_feature_) {
147 top_intensity_data_[idx] = pi;
148 }
149 }
150 mean_height_data_[idx] += static_cast<float>(pz);
151 if (use_intensity_feature_) {
152 mean_intensity_data_[idx] += static_cast<float>(pi);
153 }
154 count_data_[idx] += 1.f;
155 }
156
157 for (int i = 0; i < map_size; ++i) {
158 if (count_data_[i] <= std::numeric_limits<float>::epsilon()) {
159 max_height_data_[i] = 0.f;
160 } else {
161 mean_height_data_[i] /= count_data_[i];
162 if (use_intensity_feature_) {
163 mean_intensity_data_[i] /= count_data_[i];
164 }
165 nonempty_data_[i] = 1.f;
166 }
167 count_data_[i] = LogCount(static_cast<int>(count_data_[i]));
168 }
169}
170
171} // namespace lidar
172} // namespace perception
173} // namespace apollo
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
int offset(const int n, const int c=0, const int h=0, const int w=0) const
Definition blob.h:231
bool Init(const cnnseg::FeatureParam &feature_param, base::Blob< float > *out_blob)
Init the Feature Generator
std::shared_ptr< PointFCloud > PointFCloudPtr
float Pixel2Pc(int in_pixel, float in_size, float out_range)
Definition util.h:52
const double kPI
Definition util.h:31
class register implement
Definition arena_queue.h:37