電腦視覺CV 之 CMT跟蹤演算法分析3

來源:互聯網
上載者:User

標籤:電腦視覺   演算法   cmt   

1 前言

在上一篇blog中,我們分析了CMT的整體演算法流程及前面幾步的實現分析,接下來我們繼續分析後面的幾步。

2 Step 4,5,6 特徵點匹配與資料融合

這幾步就是通過跟蹤和特徵匹配來擷取這一幀的特徵點,將兩者融合在一起。

上一篇文章分析了光流,這裡再分析一下特徵匹配。原始碼如下:

    //Detect keypoints, compute descriptors 計算當前映像的關鍵點    vector<KeyPoint> keypoints;    detector->detect(im_gray, keypoints);    // 計算當前映像特徵點的描述    Mat descriptors;    descriptor->compute(im_gray, keypoints, descriptors);    //Match keypoints globally 在全域和之前的資料庫匹配特徵點,計算出匹配的特徵點    vector<Point2f> points_matched_global;    vector<int> classes_matched_global;    matcher.matchGlobal(keypoints, descriptors, points_matched_global, classes_matched_global);

主要過程在matchGlobal函數中,分析如下:

void Matcher::matchGlobal(const vector<KeyPoint> & keypoints, const Mat descriptors,        vector<Point2f> & points_matched, vector<int> & classes_matched){    if (keypoints.size() == 0)    {        return;    }    vector<vector<DMatch> > matches;    // 使用knnMatch進行特徵匹配,每一個特徵描述匹配最佳的2個特徵    bfmatcher->knnMatch(descriptors, database, matches, 2);    for (size_t i = 0; i < matches.size(); i++)    {        vector<DMatch> m = matches[i];        // 這裡的distance是兩個特徵描述之間的距離不是點與點的距離,距離越大,匹配度越低        float distance1 = m[0].distance / desc_length;        float distance2 = m[1].distance / desc_length;        int matched_class = classes[m[0].trainIdx];        // 如果匹配的是背景,則跳過        if (matched_class == -1) continue;        // 距離要小於一個閾值0.25,表示匹配程度高,大了則跳過        if (distance1 > thr_dist) continue;        // 比率也要小於閾值0.8,表示匹配1比匹配2好很多,從而可以將匹配1作為首選。        if (distance1/distance2 > thr_ratio) continue;        points_matched.push_back(keypoints[i].pt);        classes_matched.push_back(matched_class);    }}

上面的距離是Hamming距離:

距離越小,表示匹配程度越高。

接下來是融合跟蹤和匹配的點,分析代碼如下:

    //Fuse tracked and globally matched points    //融合跟蹤和匹配的點 將兩種點都放在一起,並且不重複    vector<Point2f> points_fused;    vector<int> classes_fused;    fusion.preferFirst(points_tracked, classes_tracked, points_matched_global, classes_matched_global,            points_fused, classes_fused);

核心代碼在preferFirst函數中,目的就是不重複添加相同的特徵點,很好理解:

void Fusion::preferFirst(const vector<Point2f> & points_first, const vector<int> & classes_first,    const vector<Point2f> & points_second, const vector<int> & classes_second,    vector<Point2f> & points_fused, vector<int> & classes_fused){    points_fused = points_first;    classes_fused = classes_first;    // 目的是不重複添加相同的特徵點    for (size_t i = 0; i < points_second.size(); i++)    {        int class_second = classes_second[i];        bool found = false;        for (size_t j = 0; j < points_first.size(); j++)        {            int class_first = classes_first[j];            if (class_first == class_second) found = true;        }        if (!found)        {            points_fused.push_back(points_second[i]);            classes_fused.push_back(class_second);        }    }}
3 Step 8,9 估計縮放比率和旋轉角度

首先就如何計算的問題,這個其實原理非常簡單,就是一開始我們已經儲存了初始的特徵點,而且是正規化的特徵點points_normalized,先計算兩兩之間的相對距離和相對角度,具體思想見上一篇blog的圖,初始的代碼如下:

    for (size_t i = 0; i < num_points; i++)    {        for (size_t j = 0; j < num_points; j++)        {            Point2f v = points_normalized[i] - points_normalized[j];            float distance = norm(v);            float angle = atan2(v.y,v.x);            distances_pairwise.at<float>(i,j) = distance;            angles_pairwise.at<float>(i,j) = angle;        }    }

那麼對於新的特徵點,同樣也是計算他們的相對距離和相對角度,並與初始的資料相除或相減,就得到變化。
最後取他們的中位元作為整體的縮放比率和旋轉。
代碼如下:

void Consensus::estimateScaleRotation(const vector<Point2f> & points, const vector<int> & classes,        float & scale, float & rotation){    //Compute pairwise changes in scale/rotation    // 從縮放和旋轉尺度上計算Pairwise改變    vector<float> changes_scale;    if (estimate_scale) changes_scale.reserve(points.size()*points.size());    vector<float> changes_angles;    if (estimate_rotation) changes_angles.reserve(points.size()*points.size());    for (size_t i = 0; i < points.size(); i++)    {        for (size_t j = 0; j < points.size(); j++)        {            if (classes[i] != classes[j])            {                // 計算任何兩個特徵點的相對位置                Point2f v = points[i] - points[j];                if (estimate_scale)                {                    // 計算距離                    float distance = norm(v);                    // 擷取特徵點的初始距離                    float distance_original = distances_pairwise.at<float>(classes[i],classes[j]);                    // 相除得到改變的比率                    float change_scale = distance / distance_original;                    changes_scale.push_back(change_scale);                }                if (estimate_rotation)                {                    // 計算相對角度                    float angle = atan2(v.y,v.x);                    // 計算初始角度                    float angle_original = angles_pairwise.at<float>(classes[i],classes[j]);                    // 計算角度改變                    float change_angle = angle - angle_original;                    //Fix long way angles                    if (fabs(change_angle) > M_PI) {                        change_angle = sgn(change_angle) * 2 * M_PI + change_angle;                    }                    changes_angles.push_back(change_angle);                }            }        }    }    //Do not use changes_scale, changes_angle after this point as their order is changed by median()    // 計算中位元作為結果    if (changes_scale.size() < 2) scale = 1;    else scale = median(changes_scale);    if (changes_angles.size() < 2) rotation = 0;    else rotation = median(changes_angles);}

時間關係,先分析到縮放和旋轉這一步,下一篇文章分析CMT最後幾步。

本文為原創文章,轉載請註明出處:47830463

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.