Apollo 10.0
自动驾驶开放平台
polygon_mask.h
浏览该文件的文档.
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#pragma once
18
19#include <algorithm>
20#include <limits>
21#include <vector>
22
26
27namespace apollo {
28namespace perception {
29namespace lidar {
30
31template <typename T>
32bool DrawPolygonMask(const typename PolygonScanCvter<T>::Polygon& polygon,
33 Bitmap2D* bitmap, const double extend_dist = 0.0,
34 const bool no_edge_table = false);
35
36template <typename T>
38 const std::vector<typename PolygonScanCvter<T>::Polygon>& polygons,
39 Bitmap2D* bitmap, const double extend_dist = 0.0,
40 const bool no_edge_table = false);
41
42template <typename T>
43bool DrawPolygonMask(const typename PolygonScanCvter<T>::Polygon& polygon,
44 Bitmap2D* bitmap, const double extend_dist,
45 const bool no_edge_table) {
46 typedef typename PolygonScanCvter<T>::IntervalIn IntervalIn;
47 typedef typename PolygonScanCvter<T>::IntervalOut IntervalOut;
48 typedef typename PolygonScanCvter<T>::DirectionMajor PolyDirMajor;
49 if (bitmap->Empty()) {
50 AERROR << "bitmap is empty";
51 return false;
52 }
53 Eigen::Vector2d poly_min_p, poly_max_p;
54 poly_min_p.setConstant(std::numeric_limits<double>::max());
55 poly_max_p = -poly_min_p;
56 for (const auto& pt : polygon) {
57 poly_min_p.x() = std::min(pt.x(), poly_min_p.x());
58 poly_min_p.y() = std::min(pt.y(), poly_min_p.y());
59
60 poly_max_p.x() = std::max(pt.x(), poly_max_p.x());
61 poly_max_p.y() = std::max(pt.y(), poly_max_p.y());
62 }
63 if (poly_max_p.x() <= poly_min_p.x()) {
64 AERROR << "Invalid polygon";
65 return false;
66 }
67 if (poly_max_p.y() <= poly_min_p.y()) {
68 AERROR << "Invalid polygon";
69 return false;
70 }
71 const Eigen::Vector2d& bitmap_min_range = bitmap->min_range();
72 const Eigen::Vector2d& bitmap_max_range = bitmap->max_range();
73 const Eigen::Vector2d& cell_size = bitmap->cell_size();
74 const int major_dir = bitmap->dir_major();
75 const int op_major_dir = bitmap->op_dir_major();
76
77 // check major x range
78 IntervalIn valid_range;
79 valid_range.first =
80 std::max(poly_min_p[major_dir], bitmap_min_range[major_dir]);
81 valid_range.second =
82 std::min(poly_max_p[major_dir], bitmap_max_range[major_dir]);
83
84 // for numerical stability
85 valid_range.first =
86 (static_cast<int>((valid_range.first - bitmap_min_range[major_dir]) /
87 cell_size[major_dir]) +
88 0.5) *
89 cell_size[major_dir] +
90 bitmap_min_range[major_dir];
91
92 if (valid_range.second < valid_range.first + cell_size[major_dir]) {
93 AWARN << "Invalid range: " << valid_range.first << " " << valid_range.second
94 << ". polygon major directory range: " << poly_min_p[major_dir] << " "
95 << poly_max_p[major_dir] << ". cell size: " << cell_size[major_dir];
96 return true;
97 }
98
99 // start calculating intervals of scans
100 PolygonScanCvter<T> poly_scan_cvter;
101 poly_scan_cvter.Init(polygon);
102 std::vector<std::vector<IntervalOut>> scans_intervals;
103 if (no_edge_table) {
104 size_t scans_size = static_cast<size_t>(
105 (valid_range.second - valid_range.first) / cell_size[major_dir]);
106 scans_intervals.resize(scans_size);
107 for (size_t i = 0; i < scans_size; ++i) {
108 double scan_loc = valid_range.first + i * cell_size[major_dir];
109 poly_scan_cvter.ScanCvt(scan_loc, static_cast<PolyDirMajor>(major_dir),
110 &(scans_intervals[i]));
111 }
112 } else {
113 poly_scan_cvter.ScansCvt(valid_range, static_cast<PolyDirMajor>(major_dir),
114 cell_size[major_dir], &(scans_intervals));
115 }
116 // start to draw
117 double x = valid_range.first;
118 for (size_t i = 0; i < scans_intervals.size();
119 x += cell_size[major_dir], ++i) {
120 for (auto scan_interval : scans_intervals[i]) {
121 if (scan_interval.first > scan_interval.second) {
122 AERROR << "The input polygon is illegal(complex polygon)";
123 return false;
124 }
125
126 // extend
127 scan_interval.first -= extend_dist;
128 scan_interval.second += extend_dist;
129
130 IntervalOut valid_y_range;
131 valid_y_range.first =
132 std::max(bitmap_min_range[op_major_dir], scan_interval.first);
133 valid_y_range.second =
134 std::min(bitmap_max_range[op_major_dir], scan_interval.second);
135 if (valid_y_range.first > valid_y_range.second) {
136 continue;
137 }
138 bitmap->Set(x, valid_y_range.first, valid_y_range.second);
139 }
140 }
141 return true;
142}
143
144template <typename T>
146 const std::vector<typename PolygonScanCvter<T>::Polygon>& polygons,
147 Bitmap2D* bitmap, const double extend_dist, const bool no_edge_table) {
148 for (const auto& polygon : polygons) {
149 bool flag = DrawPolygonMask<T>(polygon, bitmap, extend_dist, no_edge_table);
150 if (!flag) {
151 return false;
152 }
153 }
154 return true;
155}
156
157} // namespace lidar
158} // namespace perception
159} // namespace apollo
const Eigen::Vector2d & max_range() const
Return the max_range_
Definition bitmap2d.h:68
void Set(const Eigen::Vector2d &p)
Set the vector p
Definition bitmap2d.cc:128
int dir_major() const
Return the dir_major_
Definition bitmap2d.h:103
const Eigen::Vector2d & min_range() const
Return the min_range_
Definition bitmap2d.h:61
int op_dir_major() const
Return the op_dir_major
Definition bitmap2d.h:110
bool Empty() const
cehck the bitmap_ is emtpy
Definition bitmap2d.h:136
const Eigen::Vector2d & cell_size() const
Return the cell_size_
Definition bitmap2d.h:75
void Init(const Polygon &polygon)
Init of Polygon Scan Cvter object
void ScanCvt(const T &scan_loc, DirectionMajor dir_major, std::vector< IntervalOut > *scan_intervals)
Get scan intervals
void ScansCvt(const IntervalIn &scans_interval, const DirectionMajor dir_major, const T &step, std::vector< std::vector< IntervalOut > > *scans_intervals)
Get scan intervals
std::vector< Point, Eigen::aligned_allocator< Point > > Polygon
#define AERROR
Definition log.h:44
#define AWARN
Definition log.h:43
bool DrawPolygonsMask(const std::vector< typename PolygonScanCvter< T >::Polygon > &polygons, Bitmap2D *bitmap, const double extend_dist=0.0, const bool no_edge_table=false)
bool DrawPolygonMask(const typename PolygonScanCvter< T >::Polygon &polygon, Bitmap2D *bitmap, const double extend_dist=0.0, const bool no_edge_table=false)
class register implement
Definition arena_queue.h:37