48 CHECK(options_.
Check());
52 const std::vector<std::pair<image_t, image_t>>& image_pairs,
53 const std::vector<int>& num_inliers) {
54 CHECK(!root_cluster_);
55 CHECK_EQ(image_pairs.size(), num_inliers.size());
57 std::set<image_t> image_ids;
58 std::vector<std::pair<int, int>> edges;
59 edges.reserve(image_pairs.size());
60 for (
const auto& image_pair : image_pairs) {
61 image_ids.insert(image_pair.first);
62 image_ids.insert(image_pair.second);
63 edges.emplace_back(image_pair.first, image_pair.second);
66 root_cluster_.reset(
new Cluster());
67 root_cluster_->image_ids.insert(root_cluster_->image_ids.end(),
68 image_ids.begin(), image_ids.end());
70 PartitionHierarchicalCluster(edges, num_inliers, root_cluster_.get());
72 PartitionFlatCluster(edges, num_inliers);
76 void SceneClustering::PartitionHierarchicalCluster(
77 const std::vector<std::pair<int, int>>& edges,
78 const std::vector<int>& weights, Cluster* cluster) {
79 CHECK_EQ(edges.size(), weights.size());
82 if (edges.size() == 0 ||
83 cluster->image_ids.size() <=
93 cluster->child_clusters.resize(options_.
branching);
94 for (
const auto image_id : cluster->image_ids) {
95 if (labels.count(image_id)) {
96 auto& child_cluster = cluster->child_clusters.at(labels.at(image_id));
97 child_cluster.image_ids.push_back(image_id);
99 std::cout <<
"WARN: Graph cut failed to assign cluster label to image "
100 << image_id <<
"; assigning to cluster 0" <<
std::endl;
101 cluster->child_clusters.at(0).image_ids.push_back(image_id);
106 std::vector<std::vector<std::pair<int, int>>> child_edges(options_.
branching);
107 std::vector<std::vector<int>> child_weights(options_.
branching);
108 std::vector<std::vector<std::pair<std::pair<int, int>,
int>>>
110 for (
size_t i = 0; i < edges.size(); ++i) {
111 const int label1 = labels.at(edges[i].first);
112 const int label2 = labels.at(edges[i].second);
113 if (label1 == label2) {
114 child_edges.at(label1).push_back(edges[i]);
115 child_weights.at(label1).push_back(weights[i]);
117 overlapping_edges.at(label1).emplace_back(edges[i], weights[i]);
118 overlapping_edges.at(label2).emplace_back(edges[i], weights[i]);
123 for (
int i = 0; i < options_.
branching; ++i) {
124 PartitionHierarchicalCluster(child_edges[i], child_weights[i],
125 &cluster->child_clusters[i]);
129 for (
int i = 0; i < options_.
branching; ++i) {
132 std::sort(overlapping_edges[i].begin(), overlapping_edges[i].end(),
133 [](
const std::pair<std::pair<int, int>,
int>& edge1,
134 const std::pair<std::pair<int, int>,
int>& edge2) {
135 return edge1.second > edge2.second;
139 std::set<int> overlapping_image_ids;
140 for (
const auto& edge : overlapping_edges[i]) {
141 if (labels.at(edge.first.first) == i) {
142 overlapping_image_ids.insert(edge.first.second);
144 overlapping_image_ids.insert(edge.first.first);
146 if (overlapping_image_ids.size() >=
153 std::function<void(Cluster*)> InsertOverlappingImageIds =
154 [&](Cluster* cluster) {
155 cluster->image_ids.insert(cluster->image_ids.end(),
156 overlapping_image_ids.begin(),
157 overlapping_image_ids.end());
158 for (
auto& child_cluster : cluster->child_clusters) {
159 InsertOverlappingImageIds(&child_cluster);
163 InsertOverlappingImageIds(&cluster->child_clusters[i]);
168 void SceneClustering::PartitionFlatCluster(
169 const std::vector<std::pair<int, int>>& edges,
170 const std::vector<int>& weights) {
171 CHECK_EQ(edges.size(), weights.size());
178 root_cluster_->child_clusters.resize(options_.
branching);
179 for (
const auto image_id : root_cluster_->image_ids) {
180 if (labels.count(image_id)) {
181 auto& child_cluster =
182 root_cluster_->child_clusters.at(labels.at(image_id));
183 child_cluster.image_ids.push_back(image_id);
189 std::sort(root_cluster_->child_clusters.begin(),
190 root_cluster_->child_clusters.end(),
191 [](
const Cluster& first,
const Cluster& second) {
192 return first.image_ids.size() >= second.image_ids.size() &&
193 *std::min_element(first.image_ids.begin(),
194 first.image_ids.end()) <
195 *std::min_element(second.image_ids.begin(),
196 second.image_ids.end());
200 std::unordered_map<int, std::vector<std::pair<int, int>>> related_images;
201 for (
size_t i = 0; i < edges.size(); ++i) {
202 related_images[edges[i].first].emplace_back(edges[i].second, weights[i]);
203 related_images[edges[i].second].emplace_back(edges[i].first, weights[i]);
207 for (
auto&
image : related_images) {
208 std::sort(
image.second.begin(),
image.second.end(),
209 [](
const std::pair<int, int>& first,
210 const std::pair<int, int>& second) {
211 return first.second > second.second;
219 for (
int i = 0; i < options_.
branching; ++i) {
220 auto& orig_image_ids = root_cluster_->child_clusters[i].image_ids;
221 std::set<int> cluster_images(
222 root_cluster_->child_clusters[i].image_ids.begin(),
223 root_cluster_->child_clusters[i].image_ids.end());
224 const size_t max_size = cluster_images.size() + options_.
image_overlap;
227 cluster_images.size() < max_size;
229 for (
const image_t image_id : orig_image_ids) {
230 const auto& images = related_images[image_id];
231 if (j >= images.size()) {
235 const int related_id = images[j].first;
236 if (cluster_images.count(related_id) == 0) {
237 cluster_images.insert(related_id);
239 if (cluster_images.size() >= max_size) {
244 orig_image_ids.clear();
245 orig_image_ids.insert(orig_image_ids.end(), cluster_images.begin(),
246 cluster_images.end());
251 return root_cluster_.get();
256 CHECK(root_cluster_);
258 std::vector<const Cluster*> leaf_clusters;
260 if (!root_cluster_) {
261 return leaf_clusters;
262 }
else if (root_cluster_->child_clusters.empty()) {
263 leaf_clusters.push_back(root_cluster_.get());
264 return leaf_clusters;
267 std::vector<const Cluster*> non_leaf_clusters;
268 non_leaf_clusters.push_back(root_cluster_.get());
270 while (!non_leaf_clusters.empty()) {
271 const auto cluster = non_leaf_clusters.back();
272 non_leaf_clusters.pop_back();
274 for (
const auto& child_cluster : cluster->child_clusters) {
275 if (child_cluster.child_clusters.empty()) {
276 leaf_clusters.push_back(&child_cluster);
278 non_leaf_clusters.push_back(&child_cluster);
283 return leaf_clusters;
288 std::cout <<
"Reading scene graph..." <<
std::endl;
289 std::vector<std::pair<image_t, image_t>> image_pairs;
290 std::vector<int> num_inliers;
293 std::cout <<
"Partitioning scene graph..." <<
std::endl;
295 scene_clustering.
Partition(image_pairs, num_inliers);
296 return scene_clustering;
std::shared_ptr< core::Tensor > image
void ReadTwoViewGeometryNumInliers(std::vector< std::pair< image_t, image_t >> *image_pairs, std::vector< int > *num_inliers) const
const Cluster * GetRootCluster() const
SceneClustering(const Options &options)
void Partition(const std::vector< std::pair< image_t, image_t >> &image_pairs, const std::vector< int > &num_inliers)
static SceneClustering Create(const Options &options, const Database &database)
std::vector< const Cluster * > GetLeafClusters() const
#define CHECK_OPTION_GT(val1, val2)
#define CHECK_OPTION_GE(val1, val2)
QTextStream & endl(QTextStream &stream)
std::unordered_map< int, int > ComputeNormalizedMinGraphCut(const std::vector< std::pair< int, int >> &edges, const std::vector< int > &weights, const int num_parts)