cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
semantic_kitti_dataset_impl.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <filesystem>
7#include <algorithm>
8
9namespace toolbox::io {
10
11template<typename DataType>
13 const std::string& sequence_path)
14 : base_dataset_(sequence_path) {
15
16 namespace fs = std::filesystem;
17
18 // Set labels path
19 labels_path_ = (fs::path(sequence_path) / "labels").string();
20
21 // Check if labels directory exists
22 has_labels_ = fs::exists(labels_path_) && fs::is_directory(labels_path_);
23
24 if (has_labels_) {
25 scan_label_files();
26
27 // Verify label count matches frame count
28 if (!label_files_.empty() && label_files_.size() != base_dataset_.size()) {
29 LOG_WARN_S << "Label file count (" << label_files_.size()
30 << ") does not match frame count (" << base_dataset_.size() << ")";
31 }
32 } else {
33 LOG_WARN_S << "No labels directory found at: " << labels_path_;
34 }
35
36 LOG_INFO_S << "Loaded Semantic KITTI sequence " << base_dataset_.get_sequence_name()
37 << " with " << base_dataset_.size() << " frames"
38 << (has_labels_ ? " (with labels)" : " (no labels)");
39}
40
41template<typename DataType>
43 label_files_ = list_kitti_label_files(labels_path_);
44
45 // Verify files are properly numbered
46 for (std::size_t i = 0; i < label_files_.size(); ++i) {
47 int frame_idx = parse_kitti_frame_index(label_files_[i]);
48 if (frame_idx != static_cast<int>(i)) {
49 LOG_WARN_S << "Label index mismatch: expected " << i
50 << " but got " << frame_idx
51 << " for file " << label_files_[i];
52 }
53 }
54}
55
56template<typename DataType>
57std::optional<semantic_kitti_frame_t<DataType>>
59
60 // Get base frame
61 auto base_frame = base_dataset_[index];
62 if (!base_frame) {
63 return std::nullopt;
64 }
65
66 // Create semantic frame
67 frame_type frame;
68 frame.cloud = std::move(base_frame->cloud);
69 frame.pose = base_frame->pose;
70 frame.frame_index = base_frame->frame_index;
71
72 // Load labels if available
73 if (has_labels_ && index < label_files_.size()) {
74 frame.labels = load_labels(index);
75
76 // Validate if enabled
77 if (validate_labels_ && frame.cloud &&
78 frame.labels.size() != frame.cloud->size()) {
79 LOG_ERROR_S << "Label count (" << frame.labels.size()
80 << ") does not match point count (" << frame.cloud->size()
81 << ") for frame " << index;
82
83 // Resize labels to match (fill with unlabeled)
84 frame.labels.resize(frame.cloud->size(),
86 }
87 } else {
88 // No labels - fill with unlabeled
89 if (frame.cloud) {
90 frame.labels.resize(frame.cloud->size(),
92 }
93 }
94
95 return frame;
97
98template<typename DataType>
100 std::size_t index) const {
101
102 // Check cache first
103 auto cache_it = label_cache_.find(index);
104 if (cache_it != label_cache_.end()) {
105 return cache_it->second;
106 }
107
108 if (index >= label_files_.size()) {
109 return {};
110 }
111
112 try {
113 auto labels = read_kitti_labels(label_files_[index]);
114
115 // Update cache
116 label_cache_[index] = labels;
117
118 // Trim cache if needed
119 while (label_cache_.size() > label_cache_size_) {
120 label_cache_.erase(label_cache_.begin());
122
123 return labels;
124
125 } catch (const std::exception& e) {
126 LOG_ERROR_S << "Failed to load labels from " << label_files_[index]
127 << ": " << e.what();
128 return {};
130}
131
132template<typename DataType>
134 bool scan_all) const {
135
136 if (!scan_all && unique_labels_cached_) {
137 return unique_labels_cache_;
138 }
139
140 std::set<uint16_t> unique_labels;
141
142 if (!has_labels_) {
143 unique_labels.insert(kitti_semantic_labels::UNLABELED);
144 return unique_labels;
145 }
146
147 // Scan frames to find unique labels
148 const std::size_t max_scan = scan_all ? size_impl() :
149 std::min(size_impl(), std::size_t(10));
150
151 for (std::size_t i = 0; i < max_scan; ++i) {
152 auto labels = load_labels(i);
153 for (const auto& label : labels) {
154 unique_labels.insert(get_kitti_label_id(label));
155 }
156 }
157
158 if (scan_all) {
159 unique_labels_cache_ = unique_labels;
160 unique_labels_cached_ = true;
161 }
162
163 return unique_labels;
164}
165
166template<typename DataType>
167std::map<uint16_t, std::size_t>
169 std::size_t max_frames) const {
170
171 std::map<uint16_t, std::size_t> stats;
172
173 const std::size_t frames_to_scan = (max_frames == 0) ?
174 size_impl() :
175 std::min(max_frames, size_impl());
176
177 for (std::size_t i = 0; i < frames_to_scan; ++i) {
178 auto frame = at_impl(i);
179 if (!frame) continue;
180
181 auto frame_stats = frame->get_label_statistics();
182 for (const auto& [label, count] : frame_stats) {
183 stats[label] += count;
184 }
185 }
186
187 return stats;
188}
189
190template<typename DataType>
192 uint16_t label,
193 std::size_t min_points) const {
194
195 std::vector<std::size_t> result;
196
197 for (std::size_t i = 0; i < size_impl(); ++i) {
198 auto labels = load_labels(i);
199
200 std::size_t count = 0;
201 for (const auto& full_label : labels) {
202 if (get_kitti_label_id(full_label) == label) {
203 count++;
204 if (count >= min_points) {
205 result.push_back(i);
206 break;
207 }
208 }
209 }
210 }
211
212 return result;
213}
214
215} // namespace toolbox::io
Semantic KITTI dataset loader.
Definition semantic_kitti_dataset.hpp:48
std::optional< frame_type > at_impl(std::size_t index) const
Load frame at specific index.
Definition semantic_kitti_dataset_impl.hpp:58
semantic_kitti_dataset_t(const std::string &sequence_path)
Constructor.
Definition semantic_kitti_dataset_impl.hpp:12
std::vector< std::size_t > get_frames_with_label(uint16_t label, std::size_t min_points=1) const
Get frames containing specific label.
Definition semantic_kitti_dataset_impl.hpp:191
std::set< uint16_t > get_unique_labels(bool scan_all=false) const
Get all unique labels in the dataset.
Definition semantic_kitti_dataset_impl.hpp:133
std::map< uint16_t, std::size_t > compute_label_statistics(std::size_t max_frames=0) const
Compute label statistics across all frames.
Definition semantic_kitti_dataset_impl.hpp:168
#define LOG_INFO_S
INFO级别流式日志的宏 / Macro for INFO level stream logging.
Definition thread_logger.hpp:1330
#define LOG_ERROR_S
ERROR级别流式日志的宏 / Macro for ERROR level stream logging.
Definition thread_logger.hpp:1332
#define LOG_WARN_S
WARN级别流式日志的宏 / Macro for WARN level stream logging.
Definition thread_logger.hpp:1331
constexpr uint16_t UNLABELED
Definition kitti_extended.hpp:232
< 用于列出目录下的文件/For listing files in a directory
Definition dataloader.hpp:15
std::vector< uint32_t > read_kitti_labels(const std::string &file_path)
Read Semantic KITTI label file.
Definition kitti_extended_impl.hpp:19
std::vector< std::string > list_kitti_label_files(const std::string &labels_path)
List all KITTI label files in a directory.
Definition kitti_extended_impl.hpp:371
uint16_t get_kitti_label_id(uint32_t full_label)
Extract label ID from full label (ignoring instance ID)
Definition kitti_extended.hpp:289
int parse_kitti_frame_index(const std::string &filename)
Get frame index from KITTI filename (e.g., "000123.bin" -> 123)
Definition kitti_extended_impl.hpp:392
Single frame data from Semantic KITTI dataset.
Definition kitti_types.hpp:100
std::size_t frame_index
Frame index.
Definition kitti_types.hpp:111
Eigen::Matrix< DataType, 4, 4 > pose
Global pose.
Definition kitti_types.hpp:108
std::unique_ptr< point_cloud_t< DataType > > cloud
Point cloud data.
Definition kitti_types.hpp:102
std::vector< uint32_t > labels
Semantic labels for each point (lower 16 bits: label ID, upper 16 bits: instance ID)
Definition kitti_types.hpp:105