AliceVision
Photogrammetric Computer Vision Framework
Regions.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2016 AliceVision contributors.
3 // Copyright (c) 2012 openMVG contributors.
4 // This Source Code Form is subject to the terms of the Mozilla Public License,
5 // v. 2.0. If a copy of the MPL was not distributed with this file,
6 // You can obtain one at https://mozilla.org/MPL/2.0/.
7 
8 #pragma once
9 
10 #include <aliceVision/types.hpp>
11 #include <aliceVision/numeric/numeric.hpp>
12 #include <aliceVision/feature/PointFeature.hpp>
13 #include <aliceVision/feature/Descriptor.hpp>
14 #include <aliceVision/feature/metric.hpp>
15 
16 #include <string>
17 #include <cstddef>
18 #include <typeinfo>
19 #include <memory>
20 
21 namespace aliceVision {
22 namespace feature {
23 
28 {
29  FeatureInImage(IndexT featureIndex, IndexT point3dId)
30  : _featureIndex(featureIndex),
31  _point3dId(point3dId)
32  {}
33 
34  IndexT _featureIndex;
35  IndexT _point3dId;
36 
37  bool operator<(const FeatureInImage& other) const { return _featureIndex < other._featureIndex; }
38 };
39 
42 
46 class Regions
47 {
48  public:
49  virtual ~Regions() = 0;
50 
51  protected:
52  std::vector<PointFeature> _vec_feats; // region features
53 
54  public:
55  void LoadFeatures(const std::string& sfileNameFeats) { loadFeatsFromFile(sfileNameFeats, _vec_feats); }
56 
57  PointFeatures GetRegionsPositions() const { return PointFeatures(_vec_feats.begin(), _vec_feats.end()); }
58 
59  Vec2 GetRegionPosition(std::size_t i) const { return Vec2f(_vec_feats[i].coords()).cast<double>(); }
60 
62  std::size_t RegionCount() const { return _vec_feats.size(); }
63 
65  inline std::vector<PointFeature>& Features() { return _vec_feats; }
66  inline const std::vector<PointFeature>& Features() const { return _vec_feats; }
67 
68  //--
69  // IO - one file for region features, one file for region descriptors
70  //--
71 
72  virtual void Load(const std::string& sfileNameFeats, const std::string& sfileNameDescs) = 0;
73 
74  virtual void Save(const std::string& sfileNameFeats, const std::string& sfileNameDescs) const = 0;
75 
76  virtual void SaveDesc(const std::string& sfileNameDescs) const = 0;
77 
78  //--
79  //- Basic description of a descriptor [Type, Length]
80  //--
81  virtual bool IsScalar() const = 0;
82  virtual bool IsBinary() const = 0;
83 
85  virtual std::string Type_id() const = 0;
86  virtual std::size_t DescriptorLength() const = 0;
87 
93  virtual const void* blindDescriptors() const = 0;
94 
100  virtual const void* DescriptorRawData() const = 0;
101 
102  virtual void clearDescriptors() = 0;
103 
105  // A default metric is used according the descriptor type:
106  // - Scalar: L2,
107  // - Binary: Hamming
108  virtual double SquaredDescriptorDistance(std::size_t i, const Regions*, std::size_t j) const = 0;
109 
111  virtual void CopyRegion(std::size_t i, Regions*) const = 0;
112 
113  virtual Regions* EmptyClone() const = 0;
114 
115  virtual std::unique_ptr<Regions> createFilteredRegions(const std::vector<FeatureInImage>& featuresInImage,
116  std::vector<IndexT>& out_associated3dPoint,
117  std::map<IndexT, IndexT>& out_mapFullToLocal) const = 0;
118 };
119 
120 inline Regions::~Regions() {}
121 
122 enum class ERegionType : bool
123 {
124  Binary = 0,
125  Scalar = 1
126 };
127 
128 template<typename T, ERegionType regionType>
130 
131 template<typename T>
132 struct SquaredMetric<T, ERegionType::Scalar>
133 {
134  using Metric = L2_Vectorized<T>;
135 };
136 
137 template<typename T>
138 struct SquaredMetric<T, ERegionType::Binary>
139 {
140  using Metric = SquaredHamming<T>;
141 };
142 
143 template<typename T, std::size_t L, ERegionType regionType>
144 class FeatDescRegions : public Regions
145 {
146  public:
151  typedef std::vector<DescriptorT> DescsT;
152 
153  protected:
154  std::vector<DescriptorT> _vec_descs; // region descriptions
155 
156  public:
157  std::string Type_id() const override { return typeid(T).name(); }
158  std::size_t DescriptorLength() const override { return static_cast<std::size_t>(L); }
159 
160  bool IsScalar() const override { return regionType == ERegionType::Scalar; }
161  bool IsBinary() const override { return regionType == ERegionType::Binary; }
162 
163  Regions* EmptyClone() const override { return new This(); }
164 
166  void Load(const std::string& sfileNameFeats, const std::string& sfileNameDescs) override
167  {
168  loadFeatsFromFile(sfileNameFeats, this->_vec_feats);
169  loadDescsFromBinFile(sfileNameDescs, _vec_descs);
170  }
171 
173  void Save(const std::string& sfileNameFeats, const std::string& sfileNameDescs) const override
174  {
175  saveFeatsToFile(sfileNameFeats, this->_vec_feats);
176  saveDescsToBinFile(sfileNameDescs, _vec_descs);
177  }
178 
179  void SaveDesc(const std::string& sfileNameDescs) const override { saveDescsToBinFile(sfileNameDescs, _vec_descs); }
180 
182  inline std::vector<DescriptorT>& Descriptors() { return _vec_descs; }
183  inline const std::vector<DescriptorT>& Descriptors() const { return _vec_descs; }
184 
185  inline const void* blindDescriptors() const override { return &_vec_descs; }
186 
187  inline const void* DescriptorRawData() const override { return &_vec_descs[0]; }
188 
189  inline void clearDescriptors() override { _vec_descs.clear(); }
190 
191  inline void swap(This& other)
192  {
193  this->_vec_feats.swap(other._vec_feats);
194  _vec_descs.swap(other._vec_descs);
195  }
196 
197  // Return the distance between two descriptors
198  double SquaredDescriptorDistance(std::size_t i, const Regions* genericRegions, std::size_t j) const override
199  {
200  assert(i < this->_vec_descs.size());
201  assert(genericRegions);
202  assert(j < genericRegions->RegionCount());
203 
204  const This* regionsT = dynamic_cast<const This*>(genericRegions);
205  static typename SquaredMetric<T, regionType>::Metric metric;
206  return metric(this->_vec_descs[i].getData(), regionsT->_vec_descs[j].getData(), DescriptorT::static_size);
207  }
208 
214  void CopyRegion(std::size_t i, Regions* outRegionContainer) const override
215  {
216  assert(i < this->_vec_feats.size() && i < this->_vec_descs.size());
217  static_cast<This*>(outRegionContainer)->_vec_feats.push_back(this->_vec_feats[i]);
218  static_cast<This*>(outRegionContainer)->_vec_descs.push_back(this->_vec_descs[i]);
219  }
220 
227  std::unique_ptr<Regions> createFilteredRegions(const std::vector<FeatureInImage>& featuresInImage,
228  std::vector<IndexT>& out_associated3dPoint,
229  std::map<IndexT, IndexT>& out_mapFullToLocal) const override
230  {
231  out_associated3dPoint.clear();
232  out_mapFullToLocal.clear();
233 
234  This* regionsPtr = new This;
235  std::unique_ptr<Regions> regions(regionsPtr);
236  regionsPtr->Features().reserve(featuresInImage.size());
237  regionsPtr->Descriptors().reserve(featuresInImage.size());
238  out_associated3dPoint.reserve(featuresInImage.size());
239  for (std::size_t i = 0; i < featuresInImage.size(); ++i)
240  {
241  const FeatureInImage& feat = featuresInImage[i];
242  regionsPtr->Features().push_back(this->_vec_feats[feat._featureIndex]);
243  regionsPtr->Descriptors().push_back(this->_vec_descs[feat._featureIndex]);
244 
245  // This assert should be valid in theory, but in the context of CameraLocalization
246  // we can have the same 2D feature associated to different 3D points (2 in practice).
247  // In this particular case, currently it returns the last one...
248  //
249  // assert(out_mapFullToLocal.count(feat._featureIndex) == 0);
250 
251  out_mapFullToLocal[feat._featureIndex] = i;
252  out_associated3dPoint.push_back(feat._point3dId);
253  }
254  return regions;
255  }
256 };
257 
258 template<typename T, std::size_t L>
260 
261 template<std::size_t L>
263 
264 } // namespace feature
265 } // namespace aliceVision
aliceVision::feature::FeatDescRegions::Save
void Save(const std::string &sfileNameFeats, const std::string &sfileNameDescs) const override
Export in two separate files the regions and their corresponding descriptors.
Definition: Regions.hpp:173
aliceVision::feature::Regions::SquaredDescriptorDistance
virtual double SquaredDescriptorDistance(std::size_t i, const Regions *, std::size_t j) const =0
Return the squared distance between two descriptors.
aliceVision::feature::SquaredMetric
Definition: Regions.hpp:129
aliceVision::feature::FeatDescRegions::Load
void Load(const std::string &sfileNameFeats, const std::string &sfileNameDescs) override
Read from files the regions and their corresponding descriptors.
Definition: Regions.hpp:166
aliceVision::feature::FeatDescRegions::blindDescriptors
const void * blindDescriptors() const override
Return a blind pointer to the container of the descriptors array.
Definition: Regions.hpp:185
aliceVision::feature::Regions::blindDescriptors
virtual const void * blindDescriptors() const =0
Return a blind pointer to the container of the descriptors array.
aliceVision::feature::FeatDescRegions::SquaredDescriptorDistance
double SquaredDescriptorDistance(std::size_t i, const Regions *genericRegions, std::size_t j) const override
Return the squared distance between two descriptors.
Definition: Regions.hpp:198
aliceVision::feature::FeatDescRegions::DescriptorRawData
const void * DescriptorRawData() const override
Return a pointer to the first value of the descriptor array.
Definition: Regions.hpp:187
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::feature::FeatDescRegions::DescriptorT
Descriptor< T, L > DescriptorT
Region descriptor.
Definition: Regions.hpp:149
aliceVision::feature::Regions::RegionCount
std::size_t RegionCount() const
Return the number of defined regions.
Definition: Regions.hpp:62
aliceVision::feature::FeatDescRegions::Type_id
std::string Type_id() const override
basis element used for description
Definition: Regions.hpp:157
aliceVision::feature::FeatureInImage
Store a featureIndex and the associated point3dId.
Definition: Regions.hpp:27
aliceVision::feature::Regions::Features
std::vector< PointFeature > & Features()
Mutable and non-mutable PointFeature getters.
Definition: Regions.hpp:65
aliceVision::feature::SquaredHamming
Definition: Hamming.hpp:175
aliceVision::feature::Descriptor
Definition: Descriptor.hpp:29
aliceVision::feature::Regions::CopyRegion
virtual void CopyRegion(std::size_t i, Regions *) const =0
Add the Inth region to another Region container.
aliceVision::feature::Regions::Type_id
virtual std::string Type_id() const =0
basis element used for description
aliceVision::feature::FeatDescRegions
Definition: Regions.hpp:144
aliceVision::feature::Regions
The Regions class describe a set of regions extracted from an image. It contains both a feature (posi...
Definition: Regions.hpp:46
aliceVision::feature::Regions::DescriptorRawData
virtual const void * DescriptorRawData() const =0
Return a pointer to the first value of the descriptor array.
aliceVision::feature::FeatDescRegions::createFilteredRegions
std::unique_ptr< Regions > createFilteredRegions(const std::vector< FeatureInImage > &featuresInImage, std::vector< IndexT > &out_associated3dPoint, std::map< IndexT, IndexT > &out_mapFullToLocal) const override
Duplicate only reconstructed regions.
Definition: Regions.hpp:227
aliceVision::feature::FeatDescRegions::Descriptors
std::vector< DescriptorT > & Descriptors()
Mutable and non-mutable DescriptorT getters.
Definition: Regions.hpp:182
aliceVision::feature::L2_Vectorized
Squared Euclidean distance functor (vectorized version)
Definition: metric.hpp:48
aliceVision::feature::Descriptor::static_size
static const size_type static_size
Compile-time length of the descriptor.
Definition: Descriptor.hpp:38
aliceVision::feature::FeatDescRegions::DescsT
std::vector< DescriptorT > DescsT
Container for multiple regions description.
Definition: Regions.hpp:151
aliceVision::feature::FeatDescRegions::CopyRegion
void CopyRegion(std::size_t i, Regions *outRegionContainer) const override
Add the Inth region to another Region container.
Definition: Regions.hpp:214