Răsfoiți Sursa

ready for experiments

Helge Wrede 9 ani în urmă
părinte
comite
5f5001a435

+ 13 - 24
algo/Berclaz.cpp

@@ -129,33 +129,14 @@ namespace algo
                       size_t batch_size, size_t max_track_count,
                       size_t batch_size, size_t max_track_count,
                       std::vector<core::TrackletPtr> & tracks, util::Filter2D & filter)
                       std::vector<core::TrackletPtr> & tracks, util::Filter2D & filter)
     {
     {
-        for (size_t i = 0; i < sequence.GetFrameCount(); i += batch_size)
+        size_t batch_count = 0;
+        for (size_t i = sequence.GetFrameOffset(); i < sequence.GetFrameCount(); i += batch_size)
         {
         {
             util::Logger::LogDebug("batch offset: " + std::to_string(i));
             util::Logger::LogDebug("batch offset: " + std::to_string(i));
 
 
             util::Grid grid = util::Parser::ParseGrid(sequence, i, i + batch_size,
             util::Grid grid = util::Parser::ParseGrid(sequence, i, i + batch_size,
                                                       0.0, 1.0, h_res_, 0.0, 1.0, v_res_);
                                                       0.0, 1.0, h_res_, 0.0, 1.0, v_res_);
 
 
-            // Convolve with linear filter
-//            int vicinity = 1;
-//            double multiplier = 0.25;
-//            double* linear_filter = new double[9] {
-//                    0.25, 0.50, 0.25,
-//                    0.50, 1.00, 0.50,
-//                    0.25, 0.50, 0.25
-//            };
-//            grid.Convolve2D(vicinity, linear_filter, multiplier);
-//            delete[] linear_filter;
-
-            // Convolve with gaussian filter
-//            int vicinity = 1;
-//            double* gaussian_filter = new double[9] {
-//                    0.002284, 0.043222, 0.002284,
-//                    0.043222, 0.817976, 0.043222,
-//                    0.002284, 0.043222, 0.002284
-//            };
-//            grid.Convolve2D(vicinity, gaussian_filter, 1.0);
-//            delete[] gaussian_filter;
             grid.Convolve2D(filter);
             grid.Convolve2D(filter);
 
 
             util::Logger::LogDebug("create graph");
             util::Logger::LogDebug("create graph");
@@ -173,19 +154,27 @@ namespace algo
 
 
             util::Logger::LogDebug("extract tracks");
             util::Logger::LogDebug("extract tracks");
             VertexValueMap values = boost::get(boost::vertex_name, graph);
             VertexValueMap values = boost::get(boost::vertex_name, graph);
-            for (auto path : paths)
+
+            util::Logger::LogDebug("");
+            for (auto p : paths)
             {
             {
+                std::string path_string = "";
                 core::TrackletPtr tlt(new core::Tracklet());
                 core::TrackletPtr tlt(new core::Tracklet());
-                for (auto v : path)
+                for (auto v : p)
                 {
                 {
+                    path_string += std::to_string(v) + " ";
                     tlt->AddPathObject(values[v]);
                     tlt->AddPathObject(values[v]);
                 }
                 }
                 tracks.push_back(tlt);
                 tracks.push_back(tlt);
+                util::Logger::LogDebug(path_string);
             }
             }
+            util::Logger::LogDebug("");
+
+            batch_count++;
         }
         }
 
 
         // Only connect tracks if the sequence was split
         // Only connect tracks if the sequence was split
-        if (batch_size < sequence.GetFrameCount())
+        if (batch_count > 1)
         {
         {
             //TODO find a better way to connect tracks (n-stage)
             //TODO find a better way to connect tracks (n-stage)
             util::Logger::LogDebug("connect tracks");
             util::Logger::LogDebug("connect tracks");

+ 4 - 1
algo/KShortestPaths.cpp

@@ -367,6 +367,8 @@ namespace algo
         // All found paths
         // All found paths
         MultiPredecessorMap k_orig_paths;
         MultiPredecessorMap k_orig_paths;
 
 
+        util::Logger::LogDebug("find the 1. path (in the original graph)");
+
         // Find the first path (only path found in the original graph)
         // Find the first path (only path found in the original graph)
         VertexDistanceMap orig_distances;
         VertexDistanceMap orig_distances;
         VertexPredecessorMap orig_first_path;
         VertexPredecessorMap orig_first_path;
@@ -481,7 +483,8 @@ namespace algo
                 boost::add_edge(source, target, weight, trans_graph);
                 boost::add_edge(source, target, weight, trans_graph);
             }
             }
 
 
-            util::Logger::LogDebug("find the second path (in the copied and transformed graph)");
+            util::Logger::LogDebug("find the " + std::to_string(i + 1) +
+                                           ". path (in the copied and transformed graph)");
 
 
             // Find the next path in the transformed graph
             // Find the next path in the transformed graph
             VertexPredecessorMap trans_next_path;
             VertexPredecessorMap trans_next_path;

+ 9 - 6
algo/NStage.cpp

@@ -10,16 +10,19 @@ namespace algo
 {
 {
     NStage::NStage(std::vector<size_t> max_frame_skip,
     NStage::NStage(std::vector<size_t> max_frame_skip,
                    std::vector<double> penalty_value,
                    std::vector<double> penalty_value,
-                   std::vector<size_t> max_tracklet_count)
+                   std::vector<size_t> max_tracklet_count,
+                   double edge_weight_threshold)
     {
     {
         max_frame_skips_ = max_frame_skip;
         max_frame_skips_ = max_frame_skip;
         penalty_values_ = penalty_value;
         penalty_values_ = penalty_value;
         max_tracklet_counts_ = max_tracklet_count;
         max_tracklet_counts_ = max_tracklet_count;
         iterations_ = std::min(max_tracklet_count.size(), penalty_value.size());
         iterations_ = std::min(max_tracklet_count.size(), penalty_value.size());
+        edge_weight_threshold_ = edge_weight_threshold;
     }
     }
 
 
-    void NStage::CreateObjectGraph(DirectedGraph& graph, const core::DetectionSequence& detections)
+    void NStage::CreateObjectGraph(DirectedGraph & graph, core::DetectionSequence & detections)
     {
     {
+        //TODO constraints to only create necessary
         util::Logger::LogInfo("Creating object graph");
         util::Logger::LogInfo("Creating object graph");
 
 
         std::vector<std::vector<Vertex>> layers;
         std::vector<std::vector<Vertex>> layers;
@@ -66,9 +69,9 @@ namespace algo
                     {
                     {
                         Vertex v = layers[i + k][l];
                         Vertex v = layers[i + k][l];
 
 
-                        boost::add_edge(u, v,
-                                        values[u]->CompareTo(values[v]),
-                                        graph);
+                        double weight = values[u]->CompareTo(values[v]);
+                        if (weight < edge_weight_threshold_)
+                            boost::add_edge(u, v, weight, graph);
                     }
                     }
                 }
                 }
 
 
@@ -246,7 +249,7 @@ namespace algo
         util::Logger::LogDebug("track count " + std::to_string(tracks.size()));
         util::Logger::LogDebug("track count " + std::to_string(tracks.size()));
     }
     }
 
 
-    void NStage::Run(const core::DetectionSequence& sequence,
+    void NStage::Run(core::DetectionSequence & sequence,
                      std::vector<core::TrackletPtr>& tracks)
                      std::vector<core::TrackletPtr>& tracks)
     {
     {
         // Running the two stage graph algorithm
         // Running the two stage graph algorithm

+ 18 - 6
algo/NStage.h

@@ -38,43 +38,55 @@ namespace algo
          */
          */
         size_t iterations_;
         size_t iterations_;
 
 
+        /**
+         * The maximum edge weights the edge can have to be created in the initial graph building
+         */
+        double edge_weight_threshold_;
+
         /**
         /**
          * Creates a graph with vertices for every detected object
          * Creates a graph with vertices for every detected object
+         *
          * @param graph The graph to write into
          * @param graph The graph to write into
          * @param detections The objects to use for the graph
          * @param detections The objects to use for the graph
          */
          */
-        void CreateObjectGraph(DirectedGraph& graph, const core::DetectionSequence& detections);
+        void CreateObjectGraph(DirectedGraph & graph, core::DetectionSequence & detections);
 
 
         /**
         /**
          * Reduces the object graph into linked tracklets.
          * Reduces the object graph into linked tracklets.
+         *
          * @param obj_graph The object graph to reduce
          * @param obj_graph The object graph to reduce
          * @param tlt_graph The graph to write the tracklets in
          * @param tlt_graph The graph to write the tracklets in
          * @param frame_count The frame count of the object graph
          * @param frame_count The frame count of the object graph
          * @param iteration The current iteration
          * @param iteration The current iteration
          */
          */
-        void CreateTrackletGraph(DirectedGraph& obj_graph, DirectedGraph& tlt_graph,
+        void CreateTrackletGraph(DirectedGraph & obj_graph, DirectedGraph & tlt_graph,
                                  size_t frame_count, size_t iteration);
                                  size_t frame_count, size_t iteration);
 
 
         /**
         /**
          * Extracts the finished tracks from the given tracklet graph.
          * Extracts the finished tracks from the given tracklet graph.
+         *
          * @param tlt_graph The tracklet graph to extract from
          * @param tlt_graph The tracklet graph to extract from
          * @param depth The depth to flatten the tracklets to
          * @param depth The depth to flatten the tracklets to
          * @param tracks The vector to write the extracted tracks in
          * @param tracks The vector to write the extracted tracks in
          */
          */
         void ExtractTracks(DirectedGraph& tlt_graph, size_t depth,
         void ExtractTracks(DirectedGraph& tlt_graph, size_t depth,
-                           std::vector<core::TrackletPtr>& tracks);
+                           std::vector<core::TrackletPtr> & tracks);
     public:
     public:
         /**
         /**
          * Initializes the algorithm wih the given values.
          * Initializes the algorithm wih the given values.
          * The number of stages is determined by the size of the given
          * The number of stages is determined by the size of the given
          * vectors.
          * vectors.
+         *
          * @param max_frame_skip The maximum edge length to link objects
          * @param max_frame_skip The maximum edge length to link objects
          * @param penalty_value The edge value to link to source and sink
          * @param penalty_value The edge value to link to source and sink
          * @param max_tracklet_count The maximum number of tracklets to create
          * @param max_tracklet_count The maximum number of tracklets to create
+         * @param edge_weight_threshold The maximum weight an edge can have in the initial graph,
+         *                              edges with higher weights are discarded
          */
          */
         NStage(std::vector<size_t> max_frame_skip,
         NStage(std::vector<size_t> max_frame_skip,
                std::vector<double> penalty_value,
                std::vector<double> penalty_value,
-               std::vector<size_t> max_tracklet_count);
+               std::vector<size_t> max_tracklet_count,
+               double edge_weight_threshold);
 
 
         /**
         /**
          * Runs the algorithm on the specified sequence and stores the found tracks into the
          * Runs the algorithm on the specified sequence and stores the found tracks into the
@@ -83,8 +95,8 @@ namespace algo
          * @param sequence The detection values to use
          * @param sequence The detection values to use
          * @param tracks A vector to store the found tracks in
          * @param tracks A vector to store the found tracks in
          */
          */
-        void Run(const core::DetectionSequence& sequence,
-                 std::vector<core::TrackletPtr>& tracks);
+        void Run(core::DetectionSequence & sequence,
+                 std::vector<core::TrackletPtr> & tracks);
     };
     };
 }
 }
 
 

+ 33 - 12
core/DetectionSequence.cpp

@@ -9,16 +9,33 @@ namespace core
     DetectionSequence::DetectionSequence(const std::string& name)
     DetectionSequence::DetectionSequence(const std::string& name)
     {
     {
         name_ = name;
         name_ = name;
-        objects_ = std::vector<std::vector<ObjectDataPtr>>();
+        //TODO ORIGINAL
+//        objects_ = std::vector<std::vector<ObjectDataPtr>>();
+        frame_offset_ = std::numeric_limits<size_t>::max();
+        frame_count_ = 0;
     }
     }
 
 
     void DetectionSequence::AddObject(ObjectDataPtr object_data)
     void DetectionSequence::AddObject(ObjectDataPtr object_data)
     {
     {
-        while (object_data->GetFrameIndex() >= objects_.size())
+        size_t frame = object_data->GetFrameIndex();
+
+        objects_[frame].push_back(object_data);
+
+        if (!object_data->IsVirtual())
         {
         {
-            objects_.push_back(std::vector<ObjectDataPtr>());
+            if (frame < frame_offset_)
+                frame_offset_ = frame;
+
+            if (frame > frame_count_)
+                frame_count_ = frame;
         }
         }
-        objects_[object_data->GetFrameIndex()].push_back(object_data);
+
+        //TODO ORIGINAL
+//        while (object_data->GetFrameIndex() >= objects_.size())
+//        {
+//            objects_.push_back(std::vector<ObjectDataPtr>());
+//        }
+//        objects_[object_data->GetFrameIndex()].push_back(object_data);
     }
     }
 
 
     void DetectionSequence::Clear()
     void DetectionSequence::Clear()
@@ -31,29 +48,28 @@ namespace core
         return name_;
         return name_;
     }
     }
 
 
-    ObjectDataPtr DetectionSequence::GetObject
-            (size_t frame_index, size_t object_index) const
+    ObjectDataPtr DetectionSequence::GetObject(size_t frame_index, size_t object_index)
     {
     {
         return objects_[frame_index][object_index];
         return objects_[frame_index][object_index];
     }
     }
 
 
     size_t DetectionSequence::GetFrameCount() const
     size_t DetectionSequence::GetFrameCount() const
     {
     {
-        return objects_.size();
+        return frame_count_;
     }
     }
 
 
-    size_t DetectionSequence::GetObjectCount(size_t frame_index) const
+    size_t DetectionSequence::GetObjectCount(size_t frame_index)
     {
     {
         return objects_[frame_index].size();
         return objects_[frame_index].size();
     }
     }
 
 
-    std::ostream& operator<<(std::ostream& os, const DetectionSequence& obj)
+    std::ostream & operator<<(std::ostream & os, DetectionSequence const & obj)
     {
     {
-        for (size_t frame = 0; frame < obj.objects_.size(); ++frame)
+        for (auto frame : obj.objects_)
         {
         {
-            os << "Frame: " << frame << std::endl;
+            os << "Frame: " << frame.first << std::endl;
 
 
-            for (auto obj_in_frame : obj.objects_[frame])
+            for (auto obj_in_frame : frame.second)
             {
             {
                 os << *obj_in_frame << std::endl;
                 os << *obj_in_frame << std::endl;
             }
             }
@@ -61,4 +77,9 @@ namespace core
 
 
         return os;
         return os;
     }
     }
+
+    size_t DetectionSequence::GetFrameOffset() const
+    {
+        return frame_offset_;
+    }
 }
 }

+ 31 - 6
core/DetectionSequence.h

@@ -28,17 +28,31 @@ namespace core
          * The first dimension is the frame.
          * The first dimension is the frame.
          * The second dimension is the object in that frame.
          * The second dimension is the object in that frame.
          */
          */
-        std::vector<std::vector<ObjectDataPtr>> objects_;
+        std::unordered_map<size_t, std::vector<ObjectDataPtr>> objects_;
+        //TODO ORIGINAL
+//        std::vector<std::vector<ObjectDataPtr>> objects_;
+
+        /**
+         * The frame offset for the first detection
+         */
+        size_t frame_offset_;
+
+        /**
+         * The frame count
+         */
+        size_t frame_count_;
     public:
     public:
         /**
         /**
          * Creates a detection sequence with the given name.
          * Creates a detection sequence with the given name.
+         *
          * @param name The name of this sequence
          * @param name The name of this sequence
          */
          */
-        DetectionSequence(const std::string& name = "DetectionSequence");
+        DetectionSequence(std::string const & name = "DetectionSequence");
 
 
         /**
         /**
          * Adds a new object, creates a new frame vector if the given objects
          * Adds a new object, creates a new frame vector if the given objects
          * frame index is greater than the current frame vector size.
          * frame index is greater than the current frame vector size.
+         *
          * @param object_data The object to add
          * @param object_data The object to add
          */
          */
         void AddObject(ObjectDataPtr object_data);
         void AddObject(ObjectDataPtr object_data);
@@ -50,39 +64,50 @@ namespace core
 
 
         /**
         /**
          * Gets the name of this sequence.
          * Gets the name of this sequence.
+         *
          * @return The name
          * @return The name
          */
          */
         std::string GetName() const;
         std::string GetName() const;
 
 
         /**
         /**
          * Gets a pointer to the object in the given frame with the given index.
          * Gets a pointer to the object in the given frame with the given index.
+         *
          * @param frame_index The frame to get the object from
          * @param frame_index The frame to get the object from
          * @param object_index The objects index in the corresponding frame
          * @param object_index The objects index in the corresponding frame
          * @return A pointer to the stored object data
          * @return A pointer to the stored object data
          */
          */
-        ObjectDataPtr GetObject(size_t frame_index, size_t object_index) const;
+        ObjectDataPtr GetObject(size_t frame_index, size_t object_index);
 
 
         /**
         /**
          * Gets the frame count.
          * Gets the frame count.
+         *
          * @return The frame count
          * @return The frame count
          */
          */
         size_t GetFrameCount() const;
         size_t GetFrameCount() const;
 
 
+        /**
+         * Gets the frame offset.
+         *
+         * @return The Frame offset
+         */
+        size_t GetFrameOffset() const;
+
         /**
         /**
          * Gets the object count in the given frame.
          * Gets the object count in the given frame.
+         *
          * @param frame_index The frame to get the object count of
          * @param frame_index The frame to get the object count of
          * @return The number of objects in this frame
          * @return The number of objects in this frame
          */
          */
-        size_t GetObjectCount(size_t frame_index) const;
+        size_t GetObjectCount(size_t frame_index);
 
 
         /**
         /**
          * Overrides the << operator for easy output.
          * Overrides the << operator for easy output.
+         *
          * @param os The stream to write to
          * @param os The stream to write to
          * @param obj The object to write into the stream
          * @param obj The object to write into the stream
          * @return The stream written to
          * @return The stream written to
          */
          */
-        friend std::ostream& operator<<(std::ostream& os,
-                                        const DetectionSequence& obj);
+        friend std::ostream & operator<<(std::ostream & os, DetectionSequence const & obj);
     };
     };
 }
 }
 
 

+ 5 - 0
core/ObjectData.cpp

@@ -81,6 +81,11 @@ namespace core
     {
     {
         return detection_score_;
         return detection_score_;
     }
     }
+
+    std::string ObjectData::ToString(char delimiter) const
+    {
+        return std::to_string(frame_index_);
+    }
 }
 }
 
 
 
 

+ 8 - 0
core/ObjectData.h

@@ -122,6 +122,14 @@ namespace core
          * @return The stream written to
          * @return The stream written to
          */
          */
         friend std::ostream& operator<<(std::ostream& os, const ObjectData& obj);
         friend std::ostream& operator<<(std::ostream& os, const ObjectData& obj);
+
+        /**
+         * Returns a string representing the values of this object data.
+         *
+         * @param delimiter The delimiter used to separate values
+         * @return The string containing the values
+         */
+        virtual std::string ToString(char delimiter) const;
     };
     };
 }
 }
 
 

+ 8 - 2
core/ObjectData2D.cpp

@@ -76,10 +76,16 @@ namespace core
 
 
     void ObjectData2D::Visualize(cv::Mat& image, cv::Scalar& color) const
     void ObjectData2D::Visualize(cv::Mat& image, cv::Scalar& color) const
     {
     {
-        double x = position_.x * image.cols;
-        double y = position_.y * image.rows;
+        double x = position_.x;
+        double y = position_.y;
         int r = (int) (0.005 * (image.rows + image.cols) * 0.5);
         int r = (int) (0.005 * (image.rows + image.cols) * 0.5);
 
 
         cv::circle(image, cv::Point2d(x, y), r, color);
         cv::circle(image, cv::Point2d(x, y), r, color);
     }
     }
+
+    std::string ObjectData2D::ToString(char delimiter) const
+    {
+        return ObjectData::ToString(delimiter) + delimiter +
+                std::to_string(position_.x) + delimiter + std::to_string(position_.y);
+    }
 }
 }

+ 2 - 2
core/ObjectData2D.h

@@ -75,9 +75,9 @@ namespace core
         double GetSpatialWeight() const;
         double GetSpatialWeight() const;
 
 
         virtual double CompareTo(ObjectDataPtr obj) const override;
         virtual double CompareTo(ObjectDataPtr obj) const override;
-        virtual ObjectDataPtr Interpolate(ObjectDataPtr obj,
-                                          double fraction) const override;
+        virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
+        virtual std::string ToString(char delimiter) const override;
     };
     };
 }
 }
 
 

+ 5 - 0
core/ObjectDataAngular.cpp

@@ -94,4 +94,9 @@ namespace core
         << "y:" << GetPosition().y << ", "
         << "y:" << GetPosition().y << ", "
         << "a:" << GetAngle() << "}";
         << "a:" << GetAngle() << "}";
     }
     }
+
+    std::string ObjectDataAngular::ToString(char delimiter) const
+    {
+        return ObjectData2D::ToString(delimiter) + delimiter + std::to_string(angle_);
+    }
 }
 }

+ 1 - 0
core/ObjectDataAngular.h

@@ -75,6 +75,7 @@ namespace core
         virtual double CompareTo(ObjectDataPtr obj) const override;
         virtual double CompareTo(ObjectDataPtr obj) const override;
         virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
         virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
+        virtual std::string ToString(char delimiter) const override;
     };
     };
 }
 }
 
 

+ 6 - 0
core/ObjectDataBox.cpp

@@ -71,4 +71,10 @@ namespace core
     {
     {
         return size_;
         return size_;
     }
     }
+
+    std::string ObjectDataBox::ToString(char delimiter) const
+    {
+        return ObjectData2D::ToString(delimiter) + delimiter +
+                std::to_string(size_.x) + delimiter + std::to_string(size_.y);
+    }
 }
 }

+ 1 - 0
core/ObjectDataBox.h

@@ -44,6 +44,7 @@ namespace core
         virtual double CompareTo(ObjectDataPtr obj) const override;
         virtual double CompareTo(ObjectDataPtr obj) const override;
         virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
         virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
         virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
+        virtual std::string ToString(char delimiter) const override;
     };
     };
 }
 }
 
 

+ 7 - 0
core/Tracklet.cpp

@@ -48,6 +48,9 @@ namespace core
                      iter != path_objects_.end() && !inserted;
                      iter != path_objects_.end() && !inserted;
                      ++iter)
                      ++iter)
                 {
                 {
+                    // If the frame index is the same, either overwrite the value or do nothing
+                    // If the frame index is smaller than the stored, the new object should be
+                    // inserted here to accomplish a frame index order
                     if ((*iter)->GetFrameIndex() == obj->GetFrameIndex())
                     if ((*iter)->GetFrameIndex() == obj->GetFrameIndex())
                     {
                     {
                         if (overwrite)
                         if (overwrite)
@@ -65,11 +68,14 @@ namespace core
                 }
                 }
             }
             }
 
 
+            // If the frame index is higher than all already stored object, the new object is
+            // simple added at the end to preserve the ascending frame index order
             if (!inserted)
             if (!inserted)
             {
             {
                 path_objects_.push_back(obj);
                 path_objects_.push_back(obj);
             }
             }
 
 
+            // Update the lowest and highest frame index fields
             SetFrameIndex(path_objects_.front()->GetFrameIndex());
             SetFrameIndex(path_objects_.front()->GetFrameIndex());
             last_frame_index_ = path_objects_.back()->GetFrameIndex();
             last_frame_index_ = path_objects_.back()->GetFrameIndex();
         }
         }
@@ -121,6 +127,7 @@ namespace core
         }
         }
     }
     }
 
 
+    //TODO find a better method than linear interpolation
     void Tracklet::InterpolateMissingFrames()
     void Tracklet::InterpolateMissingFrames()
     {
     {
         for (size_t i = 1; i < path_objects_.size(); ++i)
         for (size_t i = 1; i < path_objects_.size(); ++i)

+ 4 - 7
core/Tracklet.h

@@ -82,13 +82,6 @@ namespace core
          */
          */
         void InterpolateMissingFrames();
         void InterpolateMissingFrames();
 
 
-        virtual double CompareTo(ObjectDataPtr obj) const override;
-
-        virtual ObjectDataPtr Interpolate(ObjectDataPtr obj,
-                                          double fraction) const override;
-
-        virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
-
         /**
         /**
          * Visualizes the tracklet by visualizing the path object in the given
          * Visualizes the tracklet by visualizing the path object in the given
          * frame and the number of path objects in the given range before and
          * frame and the number of path objects in the given range before and
@@ -127,6 +120,10 @@ namespace core
          * @return A pointer to the detection in the given frame
          * @return A pointer to the detection in the given frame
          */
          */
         ObjectDataPtr GetFrameObject(size_t frame_index);
         ObjectDataPtr GetFrameObject(size_t frame_index);
+
+        virtual double CompareTo(ObjectDataPtr obj) const override;
+        virtual ObjectDataPtr Interpolate(ObjectDataPtr obj, double fraction) const override;
+        virtual void Visualize(cv::Mat& image, cv::Scalar& color) const override;
     };
     };
 }
 }
 
 

+ 55 - 29
main/main.cpp

@@ -20,6 +20,7 @@ struct
     std::string max_frame_skip;
     std::string max_frame_skip;
     std::string max_tracklet_count;
     std::string max_tracklet_count;
     std::string penalty_value;
     std::string penalty_value;
+    double edge_weight_threshold;
 } n_stage_params;
 } n_stage_params;
 
 
 void RunNStage(core::DetectionSequence& sequence, std::vector<core::TrackletPtr>& tracks)
 void RunNStage(core::DetectionSequence& sequence, std::vector<core::TrackletPtr>& tracks)
@@ -79,8 +80,9 @@ void RunNStage(core::DetectionSequence& sequence, std::vector<core::TrackletPtr>
     }
     }
     while (d_index != std::string::npos);
     while (d_index != std::string::npos);
 
 
-    // Init n stage
-    algo::NStage n_stage(max_frame_skips, penalty_values, max_tracklet_counts);
+    // Init n-stage
+    algo::NStage n_stage(max_frame_skips, penalty_values, max_tracklet_counts,
+                         n_stage_params.edge_weight_threshold);
 
 
     n_stage.Run(sequence, tracks);
     n_stage.Run(sequence, tracks);
 
 
@@ -103,7 +105,7 @@ struct
     util::Filter2D filter;
     util::Filter2D filter;
 } berclaz_params;
 } berclaz_params;
 
 
-void RunBerclaz(core::DetectionSequence& sequence, std::vector<core::TrackletPtr>& tracks)
+void RunBerclaz(core::DetectionSequence & sequence, std::vector<core::TrackletPtr> & tracks)
 {
 {
     util::Logger::LogInfo("Running berclaz");
     util::Logger::LogInfo("Running berclaz");
 
 
@@ -133,7 +135,7 @@ void Run(int argc, char const * const * argv)
     // Algorithm independent values
     // Algorithm independent values
     std::string input_file, output_path, images_folder, algorithm, config_path, header;
     std::string input_file, output_path, images_folder, algorithm, config_path, header;
     std::string input_format, berclaz_filter;
     std::string input_format, berclaz_filter;
-    bool info, debug, display, output, output_images;
+    bool info, debug, display, output, output_images, show_grid;
     char input_delimiter, output_delimiter;
     char input_delimiter, output_delimiter;
     double temporal_weight, spatial_weight, angular_weight, image_width, image_height;
     double temporal_weight, spatial_weight, angular_weight, image_width, image_height;
 
 
@@ -149,54 +151,58 @@ void Run(int argc, char const * const * argv)
              boost::program_options::value<bool>(&debug)
              boost::program_options::value<bool>(&debug)
                      ->default_value(false),
                      ->default_value(false),
              "if the program should show debug messages")
              "if the program should show debug messages")
-            ("display",
+            ("display.enabled",
              boost::program_options::value<bool>(&display)
              boost::program_options::value<bool>(&display)
                      ->default_value(false),
                      ->default_value(false),
              "if a window with the images and the detected tracks should be opened")
              "if a window with the images and the detected tracks should be opened")
-            ("output",
-             boost::program_options::value<bool>(&output)
+            ("display.show-grid",
+             boost::program_options::value<bool>(&show_grid)
                      ->default_value(false),
                      ->default_value(false),
-             "if the results should be written into the specified output folder")
-            ("output-images",
-             boost::program_options::value<bool>(&output_images)
-                     ->default_value(false),
-             "if the images containing the visualized detections should be written to the output")
+             "if a grid should be shown in the visualized tracks (will only be shown if a resolution is given)")
             ("config",
             ("config",
              boost::program_options::value<std::string>(&config_path),
              boost::program_options::value<std::string>(&config_path),
              "the path to the config file, if no path is given the command line arguments are read")
              "the path to the config file, if no path is given the command line arguments are read")
-            ("input-file",
+            ("input.file",
              boost::program_options::value<std::string>(&input_file),
              boost::program_options::value<std::string>(&input_file),
              "set detections file path")
              "set detections file path")
-            ("output-path",
+            ("output.enabled",
+             boost::program_options::value<bool>(&output)
+                     ->default_value(false),
+             "if the results should be written into the specified output folder")
+            ("output.images",
+             boost::program_options::value<bool>(&output_images)
+                     ->default_value(false),
+             "if the images containing the visualized detections should be written to the output")
+            ("output.path",
              boost::program_options::value<std::string>(&output_path),
              boost::program_options::value<std::string>(&output_path),
              "set the output file path")
              "set the output file path")
-            ("output-delimiter",
+            ("output.delimiter",
              boost::program_options::value<char>(&output_delimiter)
              boost::program_options::value<char>(&output_delimiter)
                     ->default_value(';'),
                     ->default_value(';'),
              "the delimiter used to separate values in the specified output file")
              "the delimiter used to separate values in the specified output file")
-            ("images-folder",
+            ("input.images-folder",
              boost::program_options::value<std::string>(&images_folder),
              boost::program_options::value<std::string>(&images_folder),
              "set images folder path")
              "set images folder path")
-            ("input-header",
+            ("input.header",
              boost::program_options::value<std::string>(&header),
              boost::program_options::value<std::string>(&header),
              "sets the input header, this value is optional if the input file has a header labeling the values,"
              "sets the input header, this value is optional if the input file has a header labeling the values,"
                      "the delimiter used for the header needs to be the same as for the rest of the file")
                      "the delimiter used for the header needs to be the same as for the rest of the file")
-            ("input-format",
+            ("input.format",
              boost::program_options::value<std::string>(&input_format)
              boost::program_options::value<std::string>(&input_format)
                      ->default_value("ObjectData"),
                      ->default_value("ObjectData"),
              "the format the input should be parsed into, valid formats are: "
              "the format the input should be parsed into, valid formats are: "
                      "2D, Box, Angular")
                      "2D, Box, Angular")
-            ("input-delimiter",
+            ("input.delimiter",
              boost::program_options::value<char>(&input_delimiter)
              boost::program_options::value<char>(&input_delimiter)
                      ->default_value(';'),
                      ->default_value(';'),
              "the delimiter used to separate values in the specified input file")
              "the delimiter used to separate values in the specified input file")
-            ("image-width",
+            ("input.image-width",
              boost::program_options::value<double>(&image_width)
              boost::program_options::value<double>(&image_width)
-                     ->default_value(1),
+                     ->default_value(1.0),
              "the width of the image")
              "the width of the image")
-            ("image-height",
+            ("input.image-height",
              boost::program_options::value<double>(&image_height)
              boost::program_options::value<double>(&image_height)
-                     ->default_value(1),
+                     ->default_value(1.0),
              "the height of the image")
              "the height of the image")
             ("algorithm",
             ("algorithm",
              boost::program_options::value<std::string>(&algorithm),
              boost::program_options::value<std::string>(&algorithm),
@@ -226,11 +232,16 @@ void Run(int argc, char const * const * argv)
              boost::program_options::value<double>(&angular_weight)
              boost::program_options::value<double>(&angular_weight)
                      ->default_value(1.0),
                      ->default_value(1.0),
              "(n-stage) angular weight for difference calculations between two detections")
              "(n-stage) angular weight for difference calculations between two detections")
-            ("berclaz.horizontal-resolution",
+            ("n-stage.edge-weight-threshold",
+             boost::program_options::value<double>(&n_stage_params.edge_weight_threshold)
+                     ->default_value(1.0),
+             "(n-stage) the maximum weight an edge can have in the initial graph, edges with"
+                     "higher edge weights are discarded")
+            ("berclaz.h-res",
              boost::program_options::value<int>(&berclaz_params.h_res)
              boost::program_options::value<int>(&berclaz_params.h_res)
                      ->default_value(10),
                      ->default_value(10),
              "(berclaz) the number of horizontal grid cells")
              "(berclaz) the number of horizontal grid cells")
-            ("berclaz.vertical-resolution",
+            ("berclaz.v-res",
              boost::program_options::value<int>(&berclaz_params.v_res)
              boost::program_options::value<int>(&berclaz_params.v_res)
                      ->default_value(10),
                      ->default_value(10),
              "(berclaz) the number of vertical grid cells")
              "(berclaz) the number of vertical grid cells")
@@ -314,10 +325,12 @@ void Run(int argc, char const * const * argv)
     {
     {
         if (header.size() > 0)
         if (header.size() > 0)
         {
         {
+            util::Logger::LogDebug("header specified");
             util::FileIO::ReadCSV(values, header, input_file, input_delimiter);
             util::FileIO::ReadCSV(values, header, input_file, input_delimiter);
         }
         }
         else
         else
         {
         {
+            util::Logger::LogDebug("read header from file");
             util::FileIO::ReadCSV(values, input_file, input_delimiter);
             util::FileIO::ReadCSV(values, input_file, input_delimiter);
         }
         }
     }
     }
@@ -368,14 +381,23 @@ void Run(int argc, char const * const * argv)
     // Running the specified algorithm
     // Running the specified algorithm
     std::vector<core::TrackletPtr> tracks;
     std::vector<core::TrackletPtr> tracks;
     time_t begin_time, end_time;
     time_t begin_time, end_time;
+    std::string output_file_name = algorithm + "_";
     util::Logger::LogInfo("Start time measurement");
     util::Logger::LogInfo("Start time measurement");
     begin_time = time(0);
     begin_time = time(0);
     if (algorithm == "n-stage")
     if (algorithm == "n-stage")
     {
     {
+        //TODO set the output file name
+
         RunNStage(sequence, tracks);
         RunNStage(sequence, tracks);
     }
     }
     else if (algorithm == "berclaz")
     else if (algorithm == "berclaz")
     {
     {
+        output_file_name += std::to_string(berclaz_params.h_res) + "x"
+                            + std::to_string(berclaz_params.v_res) + "_"
+                            + std::to_string(berclaz_params.vicinity_size) + "_"
+                            + std::to_string(berclaz_params.max_track_count) + "_"
+                            + std::to_string(berclaz_params.batch_size);
+
         berclaz_params.filter = util::Filter2D(berclaz_filter, ',');
         berclaz_params.filter = util::Filter2D(berclaz_filter, ',');
         RunBerclaz(sequence, tracks);
         RunBerclaz(sequence, tracks);
     }
     }
@@ -385,6 +407,7 @@ void Run(int argc, char const * const * argv)
         std::cout << opts << std::endl;
         std::cout << opts << std::endl;
         exit(0);
         exit(0);
     }
     }
+    output_file_name += ".csv";
 
 
     end_time = time(0);
     end_time = time(0);
     util::Logger::LogInfo("Time measurement stopped");
     util::Logger::LogInfo("Time measurement stopped");
@@ -395,7 +418,7 @@ void Run(int argc, char const * const * argv)
     // Write the output file
     // Write the output file
     if (output)
     if (output)
     {
     {
-        util::FileIO::WriteTracks(tracks, output_path + "/tracks.csv", output_delimiter);
+        util::FileIO::WriteTracks(tracks, output_path + "/" + output_file_name, output_delimiter);
     }
     }
 
 
     // Display the tracking data
     // Display the tracking data
@@ -404,10 +427,12 @@ void Run(int argc, char const * const * argv)
         util::Visualizer vis;
         util::Visualizer vis;
 
 
         if (algorithm == "berclaz")
         if (algorithm == "berclaz")
-            vis.Display(tracks, images_folder, output_images, output_path, "Visualizer",
-                        0, 24, berclaz_params.h_res, berclaz_params.v_res);
+            vis.Display(tracks, sequence.GetFrameOffset(),
+                        images_folder, output_images, output_path, "Visualizer",
+                        0, 24, show_grid, berclaz_params.h_res, berclaz_params.v_res);
         else
         else
-            vis.Display(tracks, images_folder, output_images, output_path);
+            vis.Display(tracks, sequence.GetFrameOffset(),
+                        images_folder, output_images, output_path);
     }
     }
 }
 }
 
 
@@ -928,6 +953,7 @@ int main(int argc, char const * const * argv)
 {
 {
     //TODO load with frame offset
     //TODO load with frame offset
     //TODO check visualizer for offset errors
     //TODO check visualizer for offset errors
+    //TODO check why SEGFAULT is caused by some berclaz resolutions
 
 
     Run(argc, argv);
     Run(argc, argv);
 
 

+ 17 - 59
util/FileIO.cpp

@@ -220,6 +220,8 @@ namespace util
         in.close();
         in.close();
 
 
         ReadCSV(values, line, file_name, delimiter);
         ReadCSV(values, line, file_name, delimiter);
+
+        //TODO do not read the first line
     }
     }
 
 
     void FileIO::ReadCSV(ValueMapVector& values, const std::string& header,
     void FileIO::ReadCSV(ValueMapVector& values, const std::string& header,
@@ -310,8 +312,8 @@ namespace util
         in.close();
         in.close();
     }
     }
 
 
-    void FileIO::WriteTracks(std::vector<core::TrackletPtr>& tracks, const std::string& file_name,
-                             char delimiter)
+    void FileIO::WriteTracks(std::vector<core::TrackletPtr> & tracks,
+                             std::string const & file_name, char delimiter)
     {
     {
         // Get the frame range
         // Get the frame range
         size_t first_frame = tracks[0]->GetFirstFrameIndex();
         size_t first_frame = tracks[0]->GetFirstFrameIndex();
@@ -326,82 +328,38 @@ namespace util
 
 
         std::ofstream out(file_name, std::ios::out);
         std::ofstream out(file_name, std::ios::out);
 
 
+        // Check if the file is open
         if (!out.is_open())
         if (!out.is_open())
         {
         {
             util::Logger::LogError("Unable to open file: " + file_name);
             util::Logger::LogError("Unable to open file: " + file_name);
             return;
             return;
         }
         }
 
 
+        // Print every track, one detection per line, sorted by frame
         for (size_t frame = first_frame; frame <= last_frame; ++frame)
         for (size_t frame = first_frame; frame <= last_frame; ++frame)
         {
         {
             for (size_t i = 0; i < tracks.size(); ++i)
             for (size_t i = 0; i < tracks.size(); ++i)
             {
             {
-                core::ObjectData2DPtr obj =
-                        std::static_pointer_cast<core::ObjectData2D>(tracks[i]->GetFrameObject(frame));
+                core::ObjectDataPtr obj = tracks[i]->GetFrameObject(frame);
 
 
                 if (obj != nullptr)
                 if (obj != nullptr)
                 {
                 {
-                    out << obj->GetPosition().x << delimiter;
-                    out << obj->GetPosition().y;
-                }
-                else
-                {
-                    out << delimiter;
-                }
-
-                if (i < (tracks.size() - 1))
-                {
-                    out << delimiter;
-                }
-            }
-
-            out << std::endl;
-        }
-
-        out.close();
-    }
-
-    void FileIO::ReadTracks(std::vector<core::TrackletPtr>& tracks, const std::string& file_name,
-                            char delimiter)
-    {
-        std::ifstream in(file_name, std::ios::in);
-
-        if (!in.is_open())
-        {
-            util::Logger::LogError("Unable to open file: " + file_name);
-            return;
-        }
-
-        std::string line;
-        size_t line_index = 0;
-        while (in.good() && !in.eof())
-        {
-            getline(in, line);
-
-            if (line.size() == 0) continue;
-
-            std::vector<std::string> parts = Split(line, delimiter);
+                    std::string str = obj->ToString(delimiter);
+                    std::vector<std::string> parts = Split(str, delimiter);
+                    parts.insert(parts.begin() + 1, std::to_string(i + 1));
 
 
-            while (tracks.size() < (parts.size() / 2))
-            {
-                tracks.push_back(core::TrackletPtr(new core::Tracklet()));
-            }
-
-            for (size_t i = 1; i < parts.size(); i += 2)
-            {
-                if (!parts[i - 1].empty() && !parts[i].empty())
-                {
-                    cv::Point2d point(std::stod(parts[i - 1]), std::stod(parts[i]));
+                    out << parts[0];
+                    for (size_t j = 1; j < parts.size(); ++j)
+                    {
+                        out << delimiter << parts[j];
+                    }
 
 
-                    tracks[(i - 1) / 2]->AddPathObject(
-                            core::ObjectData2DPtr(new core::ObjectData2D(line_index, point)));
+                    out << std::endl;
                 }
                 }
             }
             }
-
-            line_index++;
         }
         }
 
 
-        in.close();
+        out.close();
     }
     }
 
 
     std::vector<std::string> FileIO::Split(const std::string& input, char delimiter)
     std::vector<std::string> FileIO::Split(const std::string& input, char delimiter)

+ 1 - 1
util/Filter2D.cpp

@@ -51,7 +51,7 @@ namespace util
 
 
     int Filter2D::Index(int x, int y) const
     int Filter2D::Index(int x, int y) const
     {
     {
-        return static_cast<int>(y * mask_.size() + x);
+        return y * dimension_ + x;
     }
     }
 
 
     int Filter2D::Vicinity(int count) const
     int Filter2D::Vicinity(int count) const

+ 8 - 8
util/Logger.h

@@ -35,29 +35,29 @@ namespace util
          * Logs the given message.
          * Logs the given message.
          * @param message The message to log
          * @param message The message to log
          */
          */
-        void LogMessage(const std::string& message);
+        void LogMessage(std::string const & message);
 
 
         /**
         /**
          * Logs the given error message.
          * Logs the given error message.
          * @param message The error message to log
          * @param message The error message to log
          */
          */
-        void LogErrorMessage(const std::string& message);
+        void LogErrorMessage(std::string const & message);
     public:
     public:
         /**
         /**
          * -> Singleton
          * -> Singleton
          */
          */
-        Logger(Logger const&) = delete;
+        Logger(Logger const &) = delete;
 
 
         /**
         /**
          * -> Singleton
          * -> Singleton
          */
          */
-        void operator=(Logger const&) = delete;
+        void operator=(Logger const &) = delete;
 
 
         /**
         /**
          * Gets THE instance of this singleton.
          * Gets THE instance of this singleton.
          * Creates a new instance if not already created.
          * Creates a new instance if not already created.
          */
          */
-        static Logger& Instance()
+        static Logger & Instance()
         {
         {
             static Logger instance;
             static Logger instance;
             return instance;
             return instance;
@@ -91,19 +91,19 @@ namespace util
          * Logs the given message as an info message.
          * Logs the given message as an info message.
          * @param message The info message to log
          * @param message The info message to log
          */
          */
-        static void LogInfo(const std::string& message);
+        static void LogInfo(std::string const & message);
 
 
         /**
         /**
          * Logs the given message as an error message.
          * Logs the given message as an error message.
          * @param message The error message to log
          * @param message The error message to log
          */
          */
-        static void LogError(const std::string& message);
+        static void LogError(std::string const & message);
 
 
         /**
         /**
          * Logs the given message as an debug message.
          * Logs the given message as an debug message.
          * @param message The debug message to log
          * @param message The debug message to log
          */
          */
-        static void LogDebug(const std::string& message);
+        static void LogDebug(std::string const & message);
     };
     };
 }
 }
 
 

+ 9 - 6
util/Parser.cpp

@@ -10,12 +10,14 @@
 
 
 namespace util
 namespace util
 {
 {
+    //TODO sigmoid function for detection score smoothing
+
     //TODO rename if necessary
     //TODO rename if necessary
     const std::string Parser::KEY_FRAME = "frame";
     const std::string Parser::KEY_FRAME = "frame";
     const std::string Parser::KEY_ID = "id";
     const std::string Parser::KEY_ID = "id";
     const std::string Parser::KEY_SCORE = "score";
     const std::string Parser::KEY_SCORE = "score";
-    const std::string Parser::KEY_X = "x";
-    const std::string Parser::KEY_Y = "y";
+    const std::string Parser::KEY_X = "xc";
+    const std::string Parser::KEY_Y = "yc";
     const std::string Parser::KEY_WIDTH = "width";
     const std::string Parser::KEY_WIDTH = "width";
     const std::string Parser::KEY_HEIGHT = "height";
     const std::string Parser::KEY_HEIGHT = "height";
     const std::string Parser::KEY_ANGLE = "angle";
     const std::string Parser::KEY_ANGLE = "angle";
@@ -72,6 +74,7 @@ namespace util
         }
         }
 
 
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
+        util::Logger::LogDebug("frame offset " + std::to_string(sequence.GetFrameOffset()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
     }
     }
 
 
@@ -138,6 +141,7 @@ namespace util
         }
         }
 
 
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
+        util::Logger::LogDebug("frame offset " + std::to_string(sequence.GetFrameOffset()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
     }
     }
 
 
@@ -183,13 +187,11 @@ namespace util
             cv::Point2d point(x, y);
             cv::Point2d point(x, y);
             cv::Point2d size(width, height);
             cv::Point2d size(width, height);
 
 
-            core::ObjectDataBoxPtr object(
-                    new core::ObjectDataBox(frame, point, size));
+            core::ObjectDataBoxPtr object(new core::ObjectDataBox(frame, point, size));
 
 
             object->SetTemporalWeight(temporal_weight);
             object->SetTemporalWeight(temporal_weight);
             object->SetSpatialWeight(spatial_weight);
             object->SetSpatialWeight(spatial_weight);
-            object->SetDetectionScore(
-                    util::MyMath::InverseLerp(min_score, max_score, score));
+            object->SetDetectionScore(util::MyMath::InverseLerp(min_score, max_score, score));
 
 
             sequence.AddObject(object);
             sequence.AddObject(object);
 
 
@@ -197,6 +199,7 @@ namespace util
         }
         }
 
 
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
         util::Logger::LogDebug("objects parsed " + std::to_string(obj_count));
+        util::Logger::LogDebug("frame offset " + std::to_string(sequence.GetFrameOffset()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
         util::Logger::LogDebug("frame count " + std::to_string(sequence.GetFrameCount()));
     }
     }
 
 

+ 7 - 6
util/Visualizer.cpp

@@ -15,10 +15,10 @@ namespace util
                 std::chrono::system_clock::now().time_since_epoch()).count();
                 std::chrono::system_clock::now().time_since_epoch()).count();
     }
     }
 
 
-    void Visualizer::Display(std::vector<core::TrackletPtr>& tracks,
+    void Visualizer::Display(std::vector<core::TrackletPtr> & tracks, size_t frame_offset,
                              std::string image_folder, bool output,
                              std::string image_folder, bool output,
                              std::string output_path, std::string title, size_t first_frame,
                              std::string output_path, std::string title, size_t first_frame,
-                             int play_fps, int grid_width, int grid_height)
+                             int play_fps, bool show_grid, int grid_width, int grid_height)
     {
     {
         util::Logger::LogInfo("Displaying data");
         util::Logger::LogInfo("Displaying data");
 
 
@@ -32,6 +32,7 @@ namespace util
         std::vector<cv::Scalar> colors;
         std::vector<cv::Scalar> colors;
         std::random_device rd;
         std::random_device rd;
         std::mt19937 gen(rd());
         std::mt19937 gen(rd());
+        //TODO find better colors (more colors)
         colors.push_back(cv::Scalar(0, 255, 0));
         colors.push_back(cv::Scalar(0, 255, 0));
         colors.push_back(cv::Scalar(0, 0, 255));
         colors.push_back(cv::Scalar(0, 0, 255));
         colors.push_back(cv::Scalar(0, 255, 255));
         colors.push_back(cv::Scalar(0, 255, 255));
@@ -75,8 +76,8 @@ namespace util
             // Display image
             // Display image
             cv::Mat image = cv::imread(image_folder + "/" + image_files[current_frame], 1);
             cv::Mat image = cv::imread(image_folder + "/" + image_files[current_frame], 1);
 
 
-            // Draw grid
-            if (grid_width > 0 && grid_height > 0)
+            // Draw grid if resolution is specified
+            if (show_grid && grid_width > 0 && grid_height > 0)
             {
             {
                 cv::Scalar gridColor(255, 255, 255);
                 cv::Scalar gridColor(255, 255, 255);
                 double cellWidth = image.cols / grid_width;
                 double cellWidth = image.cols / grid_width;
@@ -93,10 +94,10 @@ namespace util
                 }
                 }
             }
             }
 
 
-            //Visualize the tracklets
+            // Visualize the tracklets
             for (size_t i = 0; i < tracks.size(); ++i)
             for (size_t i = 0; i < tracks.size(); ++i)
             {
             {
-                tracks[i]->Visualize(image, colors[i], current_frame, 0, 0);
+                tracks[i]->Visualize(image, colors[i], current_frame + frame_offset, 0, 0);
             }
             }
 
 
             cv::imshow(title, image);
             cv::imshow(title, image);

+ 5 - 3
util/Visualizer.h

@@ -31,23 +31,25 @@ namespace util
          * Displays the given tracks in an window.
          * Displays the given tracks in an window.
          * Use D for next frame, A for previous frame, F to toggle auto play and
          * Use D for next frame, A for previous frame, F to toggle auto play and
          * ESC to exit.
          * ESC to exit.
-         * If a grid size greater zero is specified a grid will be overlayed.
+         * If a grid size greater zero is specified a grid will be drawn.
          *
          *
          * @param tracks The tracks to display
          * @param tracks The tracks to display
+         * @param frame_offset The offset of the first frame
          * @param image_folder The images to use
          * @param image_folder The images to use
          * @param output If the frames with the visualized tracks should be stored
          * @param output If the frames with the visualized tracks should be stored
          * @param output_path The path to store the images into (will need an images folder)
          * @param output_path The path to store the images into (will need an images folder)
          * @param title The window title
          * @param title The window title
          * @param first_frame The frame to start at
          * @param first_frame The frame to start at
          * @param play_fps The FPS to use when auto play is activated
          * @param play_fps The FPS to use when auto play is activated
+         * @param If a grid should be shown
          * @param grid_width The number of cells in a row
          * @param grid_width The number of cells in a row
          * @param grid_height The number of cells in a column
          * @param grid_height The number of cells in a column
          */
          */
-        void Display(std::vector<core::TrackletPtr>& tracks,
+        void Display(std::vector<core::TrackletPtr> & tracks, size_t frame_offset,
                      std::string image_folder, bool output,
                      std::string image_folder, bool output,
                      std::string output_path, std::string title = "Visualizer",
                      std::string output_path, std::string title = "Visualizer",
                      size_t first_frame = 0, int play_fps = 24,
                      size_t first_frame = 0, int play_fps = 24,
-                     int grid_width = 0, int grid_height = 0);
+                     bool show_grid = false, int grid_width = 0, int grid_height = 0);
     };
     };
 }
 }