Blender  V3.3
libmv/autotrack/tracks.cc
Go to the documentation of this file.
1 // Copyright (c) 2014 libmv authors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20 //
21 // Author: mierle@gmail.com (Keir Mierle)
22 
23 #include "libmv/autotrack/tracks.h"
24 
25 #include <algorithm>
26 #include <iterator>
27 #include <vector>
28 
29 #include "libmv/numeric/numeric.h"
30 
31 namespace mv {
32 
33 Tracks::Tracks(const Tracks& other) {
34  markers_ = other.markers_;
35 }
36 
37 Tracks::Tracks(const vector<Marker>& markers) : markers_(markers) {
38 }
39 
40 bool Tracks::GetMarker(int clip, int frame, int track, Marker* marker) const {
41  for (int i = 0; i < markers_.size(); ++i) {
42  if (markers_[i].clip == clip && markers_[i].frame == frame &&
43  markers_[i].track == track) {
44  *marker = markers_[i];
45  return true;
46  }
47  }
48  return false;
49 }
50 
51 void Tracks::GetMarkersForTrack(int track, vector<Marker>* markers) const {
52  for (int i = 0; i < markers_.size(); ++i) {
53  if (track == markers_[i].track) {
54  markers->push_back(markers_[i]);
55  }
56  }
57 }
58 
60  int track,
61  vector<Marker>* markers) const {
62  for (int i = 0; i < markers_.size(); ++i) {
63  if (clip == markers_[i].clip && track == markers_[i].track) {
64  markers->push_back(markers_[i]);
65  }
66  }
67 }
68 
70  int frame,
71  vector<Marker>* markers) const {
72  for (int i = 0; i < markers_.size(); ++i) {
73  if (markers_[i].clip == clip && markers_[i].frame == frame) {
74  markers->push_back(markers_[i]);
75  }
76  }
77 }
78 
80  int frame1,
81  int clip2,
82  int frame2,
83  vector<Marker>* markers) const {
84  std::vector<int> image1_tracks;
85  std::vector<int> image2_tracks;
86 
87  // Collect the tracks in each of the two images.
88  for (int i = 0; i < markers_.size(); ++i) {
89  int clip = markers_[i].clip;
90  int frame = markers_[i].frame;
91  if (clip == clip1 && frame == frame1) {
92  image1_tracks.push_back(markers_[i].track);
93  } else if (clip == clip2 && frame == frame2) {
94  image2_tracks.push_back(markers_[i].track);
95  }
96  }
97 
98  // Intersect the two sets to find the tracks of interest.
99  std::sort(image1_tracks.begin(), image1_tracks.end());
100  std::sort(image2_tracks.begin(), image2_tracks.end());
101  std::vector<int> intersection;
102  std::set_intersection(image1_tracks.begin(),
103  image1_tracks.end(),
104  image2_tracks.begin(),
105  image2_tracks.end(),
106  std::back_inserter(intersection));
107 
108  // Scan through and get the relevant tracks from the two images.
109  for (int i = 0; i < markers_.size(); ++i) {
110  // Save markers that are in either frame and are in our candidate set.
111  if (((markers_[i].clip == clip1 && markers_[i].frame == frame1) ||
112  (markers_[i].clip == clip2 && markers_[i].frame == frame2)) &&
113  std::binary_search(
114  intersection.begin(), intersection.end(), markers_[i].track)) {
115  markers->push_back(markers_[i]);
116  }
117  }
118 }
119 
120 void Tracks::AddMarker(const Marker& marker) {
121  // TODO(keir): This is quadratic for repeated insertions. Fix this by adding
122  // a smarter data structure like a set<>.
123  for (int i = 0; i < markers_.size(); ++i) {
124  if (markers_[i].clip == marker.clip && markers_[i].frame == marker.frame &&
125  markers_[i].track == marker.track) {
126  markers_[i] = marker;
127  return;
128  }
129  }
130  markers_.push_back(marker);
131 }
132 
133 void Tracks::SetMarkers(vector<Marker>* markers) {
134  std::swap(markers_, *markers);
135 }
136 
137 bool Tracks::RemoveMarker(int clip, int frame, int track) {
138  int size = markers_.size();
139  for (int i = 0; i < markers_.size(); ++i) {
140  if (markers_[i].clip == clip && markers_[i].frame == frame &&
141  markers_[i].track == track) {
142  markers_[i] = markers_[size - 1];
143  markers_.resize(size - 1);
144  return true;
145  }
146  }
147  return false;
148 }
149 
151  int size = 0;
152  for (int i = 0; i < markers_.size(); ++i) {
153  if (markers_[i].track != track) {
154  markers_[size++] = markers_[i];
155  }
156  }
157  markers_.resize(size);
158 }
159 
160 int Tracks::MaxClip() const {
161  int max_clip = 0;
162  for (int i = 0; i < markers_.size(); ++i) {
163  max_clip = std::max(markers_[i].clip, max_clip);
164  }
165  return max_clip;
166 }
167 
168 int Tracks::MaxFrame(int clip) const {
169  int max_frame = 0;
170  for (int i = 0; i < markers_.size(); ++i) {
171  if (markers_[i].clip == clip) {
172  max_frame = std::max(markers_[i].frame, max_frame);
173  }
174  }
175  return max_frame;
176 }
177 
178 int Tracks::MaxTrack() const {
179  int max_track = 0;
180  for (int i = 0; i < markers_.size(); ++i) {
181  max_track = std::max(markers_[i].track, max_track);
182  }
183  return max_track;
184 }
185 
186 int Tracks::NumMarkers() const {
187  return markers_.size();
188 }
189 
190 } // namespace mv
void swap(T &a, T &b)
Definition: Common.h:19
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
void AddMarker(const Marker &marker)
bool RemoveMarker(int clip, int frame, int track)
void RemoveMarkersForTrack(int track)
void GetMarkersInFrame(int clip, int frame, vector< Marker > *markers) const
void SetMarkers(vector< Marker > *markers)
int MaxFrame(int clip) const
void GetMarkersForTracksInBothImages(int clip1, int frame1, int clip2, int frame2, vector< Marker > *markers) const
void GetMarkersForTrackInClip(int clip, int track, vector< Marker > *markers) const
void GetMarkersForTrack(int track, vector< Marker > *markers) const
const vector< Marker > & markers() const
int NumMarkers() const
bool GetMarker(int clip, int frame, int track, Marker *marker) const
const vector< Marker > & markers
Intersection< segment > intersection
int frame
Definition: marker.h:42
int clip
Definition: marker.h:41
int track
Definition: marker.h:43
float max