diff --git a/include/core/processor/track_matrix.h b/include/core/processor/track_matrix.h
index 62a6a548edd037bf1f9dfd91c8cdf7014f4de70d..7ccf8a73fbdf7df6d4e69f9e8fcc4bbf1d2e3909 100644
--- a/include/core/processor/track_matrix.h
+++ b/include/core/processor/track_matrix.h
@@ -78,6 +78,7 @@ class TrackMatrix
         TrackMatrix();
         virtual ~TrackMatrix();
 
+        // tracks across all Captures
         void            newTrack    (CaptureBasePtr _cap, FeatureBasePtr _ftr);
         void            add         (size_t _track_id, CaptureBasePtr _cap, FeatureBasePtr _ftr);
         void            remove      (FeatureBasePtr _ftr);
@@ -97,15 +98,23 @@ class TrackMatrix
         FeatureBasePtr  feature     (size_t _track_id, CaptureBasePtr _cap);
         CaptureBasePtr  firstCapture(size_t _track_id);
 
+        // tracks across captures that belong to keyframe
+        SizeStd         numKeyframeTracks();
+        Track           trackAtKeyframes(size_t _track_id);
+        bool            markKeyframe(CaptureBasePtr _capture);
+        bool            unmarkKeyframe(FrameBasePtr _keyframe);
+
     private:
 
         static SizeStd track_id_count_;
 
         // Along track: maps of Feature pointers indexed by time stamp.
+        // tracks across all Captures
         map<size_t, Track > tracks_;       // map indexed by track_Id   of ( maps indexed by TimeStamp  of ( features ) )
+        // tracks across captures that belong to keyframe
+        map<size_t, Track > tracks_kf_;    // map indexed by track_Id   of ( maps indexed by TimeStamp  of ( features ) )
 
         // Across track: maps of Feature pointers indexed by track_Id.
-//        map<size_t, Snapshot > snapshots_; // map indexed by capture_Id of ( maps indexed by track_Id of ( features ) )
         map<CaptureBasePtr, Snapshot > snapshots_; // map indexed by capture_ptr of ( maps indexed by track_Id of ( features ) )
 };
 
diff --git a/src/processor/track_matrix.cpp b/src/processor/track_matrix.cpp
index 8ab0c78822a4cd5dc2462b4a413e0a9e95a222af..56e87f15e3b94fb94705e909cbc928f39b701a31 100644
--- a/src/processor/track_matrix.cpp
+++ b/src/processor/track_matrix.cpp
@@ -53,6 +53,8 @@ void TrackMatrix::add(size_t _track_id, CaptureBasePtr _cap, FeatureBasePtr _ftr
         _ftr->setCapture(_cap);
     tracks_[_track_id].emplace(_cap->getTimeStamp(), _ftr);
     snapshots_[_cap].emplace(_track_id, _ftr);        // will create new snapshot if _cap_id   is not present
+    if (_cap->getFrame() && _cap->getFrame()->isKey())
+        tracks_kf_[_track_id].emplace(_cap->getTimeStamp(), _ftr);
 }
 
 void TrackMatrix::remove(size_t _track_id)
@@ -62,13 +64,6 @@ void TrackMatrix::remove(size_t _track_id)
     {
         for (auto const& pair_time_ftr : tracks_.at(_track_id))
         {
-//            SizeStd cap_id = pair_time_ftr.second->getCapture()->id();
-//            snapshots_.at(cap_id).erase(_track_id);
-//            if (snapshots_.at(cap_id).empty())
-//                snapshots_.erase(cap_id);
-
-
-
             CaptureBasePtr cap = pair_time_ftr.second->getCapture();
             snapshots_.at(cap).erase(_track_id);
             if (snapshots_.at(cap).empty())
@@ -79,6 +74,9 @@ void TrackMatrix::remove(size_t _track_id)
         // Remove track
         tracks_.erase(_track_id);
     }
+    if (tracks_kf_.count(_track_id))
+        // Remove track
+        tracks_kf_.erase(_track_id);
 }
 
 void TrackMatrix::remove(CaptureBasePtr _cap)
@@ -93,6 +91,12 @@ void TrackMatrix::remove(CaptureBasePtr _cap)
             tracks_.at(trk_id).erase(ts);
             if (tracks_.at(trk_id).empty())
                 tracks_.erase(trk_id);
+            if (_cap->getFrame() && _cap->getFrame()->isKey())
+            {
+                tracks_kf_.at(trk_id).erase(ts);
+                if (tracks_kf_.at(trk_id).empty())
+                    tracks_kf_.erase(trk_id);
+            }
         }
 
         // remove snapshot
@@ -107,10 +111,17 @@ void TrackMatrix::remove(FeatureBasePtr _ftr)
     {
         if (auto cap = _ftr->getCapture())
         {
-            tracks_   .at(_ftr->trackId()).erase(cap->getTimeStamp());
+            tracks_    .at(_ftr->trackId()).erase(cap->getTimeStamp());
             if (tracks_.at(_ftr->trackId()).empty())
                 tracks_.erase(_ftr->trackId());
 
+            if (cap->getFrame() && cap->getFrame()->isKey())
+            {
+                tracks_kf_    .at(_ftr->trackId()).erase(cap->getTimeStamp());
+                if (tracks_kf_.at(_ftr->trackId()).empty())
+                    tracks_kf_.erase(_ftr->trackId());
+            }
+
             snapshots_.at(cap)      .erase(_ftr->trackId());
             if (snapshots_.at(cap).empty())
                 snapshots_.erase(cap);
@@ -123,6 +134,11 @@ size_t TrackMatrix::numTracks()
     return tracks_.size();
 }
 
+size_t TrackMatrix::numKeyframeTracks()
+{
+    return tracks_kf_.size();
+}
+
 size_t TrackMatrix::trackSize(size_t _track_id)
 {
     return track(_track_id).size();
@@ -202,4 +218,50 @@ CaptureBasePtr TrackMatrix::firstCapture(size_t _track_id)
     return firstFeature(_track_id)->getCapture();
 }
 
+Track TrackMatrix::trackAtKeyframes(size_t _track_id)
+{
+    if (tracks_kf_.count(_track_id) > 0)
+        return tracks_kf_.at(_track_id);
+    else
+        return Track();
+}
+
+bool TrackMatrix::markKeyframe(CaptureBasePtr _capture)
+{
+    if (_capture->getFrame() && _capture->getFrame()->isKey())
+    {
+        auto snap = snapshot(_capture);
+
+        if (snap.empty())
+            return false;
+
+        for (auto pair_trkid_ftr : snap)
+        {
+            auto track_id = pair_trkid_ftr.first;
+            auto ftr      = pair_trkid_ftr.second;
+            auto ts       = _capture->getFrame()->getTimeStamp();
+            tracks_kf_[track_id][ts] = ftr;
+        }
+        return true;
+    }
+    return false;
+}
+
+bool TrackMatrix::unmarkKeyframe(FrameBasePtr _keyframe)
+{
+    bool removed = false;
+    auto ts = _keyframe->getTimeStamp();
+    for (auto pair_id_trk : tracks_kf_)
+    {
+        if (pair_id_trk.second.erase(ts))
+        {
+            if (pair_id_trk.second.empty())
+                tracks_kf_.erase(pair_id_trk.first);
+            removed = true;
+        }
+    }
+    return removed;
+}
+
+
 }
diff --git a/test/gtest_track_matrix.cpp b/test/gtest_track_matrix.cpp
index ff930b512b8f8da960b3921f81bc2bd73eac03b5..1b84496eb1b3c49138ffbc9f97666558617133f5 100644
--- a/test/gtest_track_matrix.cpp
+++ b/test/gtest_track_matrix.cpp
@@ -19,11 +19,18 @@ class TrackMatrixTest : public testing::Test
         Eigen::Vector2s m;
         Eigen::Matrix2s m_cov = Eigen::Matrix2s::Identity()*0.01;
 
+        FrameBasePtr   F0, F1, F2, F3, F4;
         CaptureBasePtr C0, C1, C2, C3, C4;
         FeatureBasePtr f0, f1, f2, f3, f4;
 
         virtual void SetUp()
         {
+            F0 = std::make_shared<FrameBase>(0.0, nullptr);
+            F1 = std::make_shared<FrameBase>(1.0, nullptr);
+            F2 = std::make_shared<FrameBase>(2.0, nullptr);
+            F3 = std::make_shared<FrameBase>(3.0, nullptr);
+            F4 = std::make_shared<FrameBase>(4.0, nullptr);
+
             C0 = std::make_shared<CaptureBase>("BASE", 0.0);
             C1 = std::make_shared<CaptureBase>("BASE", 1.0);
             C2 = std::make_shared<CaptureBase>("BASE", 2.0);
@@ -35,6 +42,17 @@ class TrackMatrixTest : public testing::Test
             f2 = std::make_shared<FeatureBase>("BASE", m, m_cov);
             f3 = std::make_shared<FeatureBase>("BASE", m, m_cov);
             f4 = std::make_shared<FeatureBase>("BASE", m, m_cov);
+
+            // F0 and F4 are keyframes
+            F0->setKey();
+            F4->setKey();
+
+            // link captures
+            C0->link(F0);
+            C1->link(F1);
+            C2->link(F2);
+            C3->link(F3);
+            C4->link(F4);
         }
 };
 
@@ -42,30 +60,58 @@ TEST_F(TrackMatrixTest, newTrack)
 {
     track_matrix.newTrack(C0, f0);
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 
     track_matrix.newTrack(C0, f1);
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
+
+    track_matrix.newTrack(C1, f2);
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 3);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
+
+    track_matrix.newTrack(C1, f3);
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 4);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
 }
 
 TEST_F(TrackMatrixTest, add)
 {
     track_matrix.newTrack(C0, f0);
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 
     track_matrix.add(f0->trackId(), C1, f1);
-    /*  C0   C1   C2   snapshots
+    /* KC0   C1   C2   snapshots
      *
      *  f0---f1        trk 0
      */
     ASSERT_EQ(track_matrix.trackSize(f1->trackId()), (unsigned int) 2);
     ASSERT_EQ(f1->trackId(), f0->trackId());
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 
     track_matrix.add(f0->trackId(), C2, f2);
-    /*  C0   C1   C2   snapshots
+    /* KC0   C1   C2   snapshots
      *
      *  f0---f1---f2   trk 0
      */
     ASSERT_EQ(track_matrix.trackSize(f2->trackId()), (unsigned int) 3);
     ASSERT_EQ(f2->trackId(), f0->trackId());
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
+
+    track_matrix.add(f0->trackId(), C2, f2);
+    /* KC0   C1   C2   snapshots
+     *
+     *  f0---f1---f2   trk 0
+     *       f3        trk 1
+     */
+    track_matrix.add(1, C1, f3);
+    ASSERT_EQ(track_matrix.trackSize(f3->trackId()), (unsigned int) 1);
+    ASSERT_NE(f3->trackId(), f0->trackId());
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 }
 
 TEST_F(TrackMatrixTest, numTracks)
@@ -136,6 +182,7 @@ TEST_F(TrackMatrixTest, remove_ftr)
      */
 
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
 
     track_matrix.remove(f0);
     /*  C0   C1   C2   snapshots
@@ -151,10 +198,23 @@ TEST_F(TrackMatrixTest, remove_ftr)
     ASSERT_EQ(track_matrix.snapshot(C0).at(f2->trackId()), f2);
     ASSERT_EQ(track_matrix.snapshot(C1).size(), (unsigned int) 1);
     ASSERT_EQ(track_matrix.snapshot(C1).at(f0->trackId()), f1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 
     track_matrix.remove(f1);
+    /*  C0   C1   C2   snapshots
+     *
+     *  f2             trk 1
+     */
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
     ASSERT_EQ(track_matrix.firstFeature(f2->trackId()), f2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
+
+    track_matrix.remove(f2);
+    /*  C0   C1   C2   snapshots
+     *
+     */
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 0);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 0);
 }
 
 TEST_F(TrackMatrixTest, remove_trk)
@@ -171,13 +231,16 @@ TEST_F(TrackMatrixTest, remove_trk)
      */
 
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
 
     track_matrix.remove(f0->trackId());
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
     ASSERT_EQ(track_matrix.firstFeature(f2->trackId()), f2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
 
     track_matrix.remove(f2->trackId());
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 0);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 0);
 }
 
 TEST_F(TrackMatrixTest, remove_snapshot)
@@ -194,6 +257,7 @@ TEST_F(TrackMatrixTest, remove_snapshot)
      */
 
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
 
     track_matrix.remove(C0);
     /*  C1   C2   snapshots
@@ -202,9 +266,11 @@ TEST_F(TrackMatrixTest, remove_snapshot)
      */
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1);
     ASSERT_EQ(track_matrix.firstFeature(f1->trackId()), f1);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 0);
 
     track_matrix.remove(C1);
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 0);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 0);
 }
 
 TEST_F(TrackMatrixTest, track)
@@ -321,6 +387,88 @@ TEST_F(TrackMatrixTest, matches)
     ASSERT_EQ(pairs.size(), (unsigned int) 0);
 }
 
+TEST_F(TrackMatrixTest, trackAtKeyframes)
+{
+    track_matrix.newTrack(C0, f0);
+    track_matrix.add(f0->trackId(), C1, f1);
+    track_matrix.add(f0->trackId(), C2, f2);
+    track_matrix.add(f0->trackId(), C4, f4);
+    track_matrix.newTrack(C1, f3);
+    /* KC0   C1   C2   C3  KC4 snapshots
+     *
+     *  f0---f1---f2--------f4 trk 0
+     *       |
+     *       f3                trk 1
+     */
+
+    wolf::Track trk_kf_0 = track_matrix.trackAtKeyframes(f0->trackId());
+    ASSERT_EQ(trk_kf_0.size(), 2);
+
+    wolf::Track trk_kf_1 = track_matrix.trackAtKeyframes(f3->trackId());
+    ASSERT_EQ(trk_kf_1.size(), 0);
+}
+
+TEST_F(TrackMatrixTest, markKeyframe)
+{
+    track_matrix.newTrack(C0, f0);
+    track_matrix.add(f0->trackId(), C1, f1);
+    track_matrix.add(f0->trackId(), C2, f2);
+    track_matrix.add(1, C1, f3);
+    /* KC0   C1   C2   C3   snapshots
+     *
+     *  f0---f1---f2        trk 0
+     *       |
+     *       f3             trk 1
+     */
+
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
+
+    C1->getFrame()->setKey();
+    track_matrix.markKeyframe(C1);
+    /* KC0  KC1   C2   C3   snapshots
+     *
+     *  f0---f1---f2        trk 0
+     *       |
+     *       f3             trk 1
+     */
+
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 2);
+
+}
+
+TEST_F(TrackMatrixTest, unmarkKeyframe)
+{
+    track_matrix.newTrack(C0, f0);
+    track_matrix.add(f0->trackId(), C1, f1);
+    track_matrix.add(f0->trackId(), C2, f2);
+    track_matrix.add(1, C1, f3);
+    /* KC0   C1   C2   C3   snapshots
+     *
+     *  f0---f1---f2        trk 0
+     *       |
+     *       f3             trk 1
+     */
+
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 1);
+
+    F0->setNonEstimated();
+    track_matrix.unmarkKeyframe(F0);
+    /*  C0   C1   C2   C3   snapshots
+     *
+     *  f0---f1---f2        trk 0
+     *       |
+     *       f3             trk 1
+     */
+
+    ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2);
+    ASSERT_EQ(track_matrix.numKeyframeTracks(), (unsigned int) 0);
+
+
+}
+
 int main(int argc, char **argv)
 {
     testing::InitGoogleTest(&argc, argv);