<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          單應(yīng)性矩陣應(yīng)用-基于特征的圖像拼接

          共 4732字,需瀏覽 10分鐘

           ·

          2021-05-30 01:49

          點擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時間送達

          本文轉(zhuǎn)自:深度學(xué)習(xí)這件小事


          前言


          前面寫了一篇關(guān)于單應(yīng)性矩陣的相關(guān)文章,結(jié)尾說到基于特征的圖像拼接跟對象檢測中單應(yīng)性矩陣應(yīng)用場景。得到很多人留言反饋,讓我繼續(xù)寫,于是就有這篇文章。這里有兩張照片(我手機拍的),背景是我老家的平房,周圍是一片開闊地帶,都是麥子。有圖為證:

          圖一:

          圖二:


          思路


          這里是兩張圖像的拼接,多張圖像與此類似。主要是應(yīng)用特征提取模塊的AKAZE圖像特征點與描述子提取,當(dāng)然你也可以選擇ORB、SIFT、SURF等特征提取方法。匹配方法主要是基于暴力匹配/FLANN+KNN完成,圖像對齊與配準通過RANSAC跟透視變換實現(xiàn),最后通過簡單的權(quán)重圖像疊加實現(xiàn)融合、得到拼接之后得全景圖像。這個其中單應(yīng)性矩陣發(fā)現(xiàn)是很重要的一步,如果不知道這個是什么請看這里:

          OpenCV單應(yīng)性矩陣發(fā)現(xiàn)參數(shù)估算方法詳解


          基本流程

          1.加載輸入圖像

          2.創(chuàng)建AKAZE特征提取器

          3.提取關(guān)鍵點跟描述子特征

          4.描述子匹配并提取匹配較好的關(guān)鍵點

          5.單應(yīng)性矩陣圖像對齊

          6.創(chuàng)建融合遮罩層,準備開始融合

          7.圖像透視變換與融合操作

          8.輸出拼接之后的全景圖


          關(guān)鍵代碼


          在具體代碼實現(xiàn)步驟之前,先說一下軟件版本

          -VS2015-OpenCV4.2-Windows 10 64位

          代碼實現(xiàn):提取特征與描述子

          1// 提取特征點與描述子
          2vector<KeyPoint> keypoints_right, keypoints_left;
          3Mat descriptors_right, descriptors_left;
          4auto detector = AKAZE::create();
          5detector->detectAndCompute(left, Mat(), keypoints_left, descriptors_left);
          6detector->detectAndCompute(right, Mat(), keypoints_right, descriptors_right);


          提取好的匹配描述子

           1// 暴力匹配
          2vector<DMatch> matches;
          3auto matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);
          4
          5// 發(fā)現(xiàn)匹配
          6std::vectorstd::vector<DMatch> > knn_matches;
          7matcher->knnMatch(descriptors_left, descriptors_right, knn_matches, 2);
          8const float ratio_thresh = 0.7f;
          9std::vector<DMatch> good_matches;
          10for (size_t i = 0; i < knn_matches.size(); i++)
          11{
          12      if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)
          13      {
          14              good_matches.push_back(knn_matches[i][0]);
          15      }
          16}
          17printf("total good match points : %d\n", good_matches.size());
          18std::cout << std::endl;
          19
          20Mat dst;
          21drawMatches(left, keypoints_left, right, keypoints_right, good_matches, dst);


          創(chuàng)建mask對象

           1// create mask
          2int win_size = 800;
          3int h1 = left.rows;
          4int w1 = left.cols;
          5int h2 = right.rows;
          6int w2 = right.cols;
          7int h = max(h1, h2);
          8int w = w1 + w2;
          9Mat mask1 = Mat::ones(Size(w, h), CV_32FC1);
          10Mat mask2 = Mat::ones(Size(w, h), CV_32FC1);
          11Rect roi;
          12roi.height = h;
          13roi.width = win_size;
          14roi.y = 0;
          15roi.x = w1 - win_size;
          16
          17// left mask
          18Mat temp = mask1(roi);
          19linspace(temp, 10, win_size);
          20
          21// right mask
          22temp = mask2(roi);
          23linspace(temp, 01, win_size);


          對齊生成全景圖像

           1// generate panorama
          2Mat panorama_01 = Mat::zeros(Size(w, h), CV_8UC3);
          3roi.x = 0;
          4roi.y = 0;
          5roi.width = w1;
          6roi.height = h1;
          7left.copyTo(panorama_01(roi));
          8Mat m1;
          9vector<Mat> mv;
          10mv.push_back(mask1);
          11mv.push_back(mask1);
          12mv.push_back(mask1);
          13merge(mv, m1);
          14panorama_01.convertTo(panorama_01, CV_32F);
          15multiply(panorama_01, m1, panorama_01);
          16
          17
          18Mat panorama_02;
          19warpPerspective(right, panorama_02, H, Size(w, h));
          20mv.clear();
          21mv.push_back(mask2);
          22mv.push_back(mask2);
          23mv.push_back(mask2);
          24Mat m2;
          25merge(mv, m2);
          26panorama_02.convertTo(panorama_02, CV_32F);
          27multiply(panorama_02, m2, panorama_02);

          上述代碼中panorama_01實現(xiàn)對第一張圖像內(nèi)容提取與mask權(quán)重生成混合,panorama_02完成對第二張圖的內(nèi)容透視變換與mask權(quán)重生成混合。特別注意的是順序很重要。單應(yīng)性矩陣發(fā)現(xiàn)代碼可以看之前文章即可,這里不再贅述。


          合并全景圖像

          1// 合并全景圖
          2Mat panorama;
          3add(panorama_01, panorama_02, panorama);
          4panorama.convertTo(panorama, CV_8U);
          5imwrite("D:/panorama.png", panorama);


          程序運行->特征點匹配如下:

          最終拼接的全景圖如下:

          想知道如何改進這個輸出結(jié)果,讓輸出結(jié)果融合的根據(jù)自然與真實,請聽下回再說吧!過年了終于有點時間寫點干貨回報一下大家!請大家多多支持!多多反饋!


          下載1:OpenCV-Contrib擴展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實戰(zhàn)項目52講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實戰(zhàn)項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機視覺。

          下載3:OpenCV實戰(zhàn)項目20講
          小白學(xué)視覺公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進階。

          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩黄视频 | 亚洲欧美精品久久久久 | 亚洲无码免费观看 | 人人草人人干人人 | 日韩一级A片免费 |