Blender V4.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
24
25#include <algorithm>
26#include <iterator>
27#include <vector>
28
30
31namespace mv {
32
33Tracks::Tracks(const Tracks& other) {
34 markers_ = other.markers_;
35}
36
37Tracks::Tracks(const vector<Marker>& markers) : markers_(markers) {
38}
39
40bool 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
51void 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
120void 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
133void Tracks::SetMarkers(vector<Marker>* markers) {
134 std::swap(markers_, *markers);
135}
136
137bool 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
160int 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
168int 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
178int 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
187 return markers_.size();
188}
189
190} // namespace mv
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
bool GetMarker(int clip, int frame, int track, Marker *marker) const
const vector< Marker > & markers
int frame
Definition marker.h:42
int clip
Definition marker.h:41
int track
Definition marker.h:43