1 // Copyright (c) 2011 libmv authors.
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:
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
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
21 #include "libmv/simple_pipeline/tracks.h"
27 #include "libmv/numeric/numeric.h"
31 Tracks::Tracks(const Tracks &other) {
32 markers_ = other.markers_;
35 Tracks::Tracks(const vector<Marker> &markers) : markers_(markers) {}
37 void Tracks::Insert(int image, int track, double x, double y) {
38 // TODO(keir): Wow, this is quadratic for repeated insertions. Fix this by
39 // adding a smarter data structure like a set<>.
40 for (int i = 0; i < markers_.size(); ++i) {
41 if (markers_[i].image == image &&
42 markers_[i].track == track) {
48 Marker marker = { image, track, x, y };
49 markers_.push_back(marker);
52 vector<Marker> Tracks::AllMarkers() const {
56 vector<Marker> Tracks::MarkersInImage(int image) const {
57 vector<Marker> markers;
58 for (int i = 0; i < markers_.size(); ++i) {
59 if (image == markers_[i].image) {
60 markers.push_back(markers_[i]);
66 vector<Marker> Tracks::MarkersForTrack(int track) const {
67 vector<Marker> markers;
68 for (int i = 0; i < markers_.size(); ++i) {
69 if (track == markers_[i].track) {
70 markers.push_back(markers_[i]);
76 vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const {
77 vector<Marker> markers;
78 for (int i = 0; i < markers_.size(); ++i) {
79 int image = markers_[i].image;
80 if (image == image1 || image == image2)
81 markers.push_back(markers_[i]);
86 vector<Marker> Tracks::MarkersForTracksInBothImages(int image1,
88 std::vector<int> image1_tracks;
89 std::vector<int> image2_tracks;
91 for (int i = 0; i < markers_.size(); ++i) {
92 int image = markers_[i].image;
93 if (image == image1) {
94 image1_tracks.push_back(markers_[i].track);
95 } else if (image == image2) {
96 image2_tracks.push_back(markers_[i].track);
100 std::sort(image1_tracks.begin(), image1_tracks.end());
101 std::sort(image2_tracks.begin(), image2_tracks.end());
103 std::vector<int> intersection;
104 std::set_intersection(image1_tracks.begin(), image1_tracks.end(),
105 image2_tracks.begin(), image2_tracks.end(),
106 std::back_inserter(intersection));
108 vector<Marker> markers;
109 for (int i = 0; i < markers_.size(); ++i) {
110 if ((markers_[i].image == image1 || markers_[i].image == image2) &&
111 std::binary_search(intersection.begin(), intersection.end(),
112 markers_[i].track)) {
113 markers.push_back(markers_[i]);
119 Marker Tracks::MarkerInImageForTrack(int image, int track) const {
120 for (int i = 0; i < markers_.size(); ++i) {
121 if (markers_[i].image == image && markers_[i].track == track) {
125 Marker null = { -1, -1, -1, -1 };
129 void Tracks::RemoveMarkersForTrack(int track) {
131 for (int i = 0; i < markers_.size(); ++i) {
132 if (markers_[i].track != track) {
133 markers_[size++] = markers_[i];
136 markers_.resize(size);
139 void Tracks::RemoveMarker(int image, int track) {
141 for (int i = 0; i < markers_.size(); ++i) {
142 if (markers_[i].image != image || markers_[i].track != track) {
143 markers_[size++] = markers_[i];
146 markers_.resize(size);
149 int Tracks::MaxImage() const {
150 // TODO(MatthiasF): maintain a max_image_ member (updated on Insert)
152 for (int i = 0; i < markers_.size(); ++i) {
153 max_image = std::max(markers_[i].image, max_image);
158 int Tracks::MaxTrack() const {
159 // TODO(MatthiasF): maintain a max_track_ member (updated on Insert)
161 for (int i = 0; i < markers_.size(); ++i) {
162 max_track = std::max(markers_[i].track, max_track);
167 int Tracks::NumMarkers() const {
168 return markers_.size();
171 void CoordinatesForMarkersInImage(const vector<Marker> &markers,
175 for (int i = 0; i < markers.size(); ++i) {
176 const Marker &marker = markers[i];
177 if (markers[i].image == image) {
178 coords.push_back(Vec2(marker.x, marker.y));
181 coordinates->resize(2, coords.size());
182 for (int i = 0; i < coords.size(); i++) {
183 coordinates->col(i) = coords[i];