簡體   English   中英

Opencv圖像拼接或全景

[英]Opencv Image Stitching or Panorama

我在OpenCV(全景圖)中進行圖像拼接,但我有一個問題。

我不能使用OpenCV中的Stitching類,所以我必須創建它只有特征點和單應性。

OrbFeatureDetector detector( minHessian );

std::vector<KeyPoint> keypoints_1, keypoints_2;

Mat descriptors_1a, descriptors_2a;
detector.detect( img_1, keypoints_1 , descriptors_1a);
detector.detect( img_2, keypoints_2 , descriptors_2a);

//-- Step 2: Calculate descriptors (feature vectors)
OrbDescriptorExtractor extractor;

Mat descriptors_1, descriptors_2;
cout<<"La distancia es " <<endl;
extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 );

//-- Step 3: Matching descriptor vectors with a brute force matcher
BFMatcher matcher(NORM_HAMMING, true);
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );

在這里我獲得匹配中的特征點,但我需要過濾它:

 double max_dist = 0; double min_dist = 100;

  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < matches.size(); i++ )
  {
      double dist = matches[i].distance;

  //cout<<"La distancia es " << i<<endl;
    if( dist < min_dist && dist >3)
        {

            min_dist = dist;
        }
    if( dist > max_dist) max_dist = dist;
  }

  //-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
  std::vector< DMatch > good_matches;

  for( int i = 0; i < matches.size(); i++ )
  {
      //cout<<matches[i].distance<<endl;
      if( matches[i].distance < 3*min_dist && matches[i].distance > 3)
     {
          good_matches.push_back( matches[i]); }
  }

現在,我計算出Homography

vector<Point2f> p1, p2;
    for (unsigned int i = 0; i < matches.size(); i++) {
        p1.push_back(keypoints_1[matches[i].queryIdx].pt);
        p2.push_back(keypoints_2[matches[i].trainIdx].pt);
    }

    // Homografía
    vector<unsigned char> match_mask;
    Mat h = findHomography(Mat(p1),Mat(p2), match_mask,CV_RANSAC);

最后,獲得變換矩陣並應用warpPerspective以獲得兩個圖像的連接,但我的問題是在最終圖像中,出現在照片周圍的黑色區域,並且當我再次循環時,最終圖像將是難以辨認的。

// Transformar perspectiva para imagen 2
    vector<Point2f> cuatroPuntos;
    cuatroPuntos.push_back(Point2f (0,0));
    cuatroPuntos.push_back(Point2f (img_1.size().width,0));
    cuatroPuntos.push_back(Point2f (0, img_1.size().height));
    cuatroPuntos.push_back(Point2f (img_1.size().width, img_1.size().height));
    Mat MDestino;
    perspectiveTransform(Mat(cuatroPuntos), MDestino, h);

    // Calcular esquinas de imagen 2
    double min_x, min_y, tam_x, tam_y;
    float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2;
    min_x1 = min(MDestino.at<Point2f>(0).x, MDestino.at<Point2f>(1).x);
    min_x2 = min(MDestino.at<Point2f>(2).x, MDestino.at<Point2f>(3).x);
    min_y1 = min(MDestino.at<Point2f>(0).y, MDestino.at<Point2f>(1).y);
    min_y2 = min(MDestino.at<Point2f>(2).y, MDestino.at<Point2f>(3).y);
    max_x1 = max(MDestino.at<Point2f>(0).x, MDestino.at<Point2f>(1).x);
    max_x2 = max(MDestino.at<Point2f>(2).x, MDestino.at<Point2f>(3).x);
    max_y1 = max(MDestino.at<Point2f>(0).y, MDestino.at<Point2f>(1).y);
    max_y2 = max(MDestino.at<Point2f>(2).y, MDestino.at<Point2f>(3).y);
    min_x = min(min_x1, min_x2);
    min_y = min(min_y1, min_y2);
    tam_x = max(max_x1, max_x2);
    tam_y = max(max_y1, max_y2);

    // Matriz de transformación
    Mat Htr = Mat::eye(3,3,CV_64F);
    if (min_x < 0){
        tam_x = img_2.size().width - min_x;
        Htr.at<double>(0,2)= -min_x;
    }
    if (min_y < 0){
        tam_y = img_2.size().height - min_y;
        Htr.at<double>(1,2)= -min_y;
    }

    // Construir panorama
    Mat Panorama;
    Panorama = Mat(Size(tam_x,tam_y), CV_32F);
    warpPerspective(img_2, Panorama,     Htr, Panorama.size(), INTER_LINEAR, BORDER_CONSTANT,   0);
    warpPerspective(img_1, Panorama, (Htr*h), Panorama.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);

誰知道我怎么能消除這個黑色區域? 是不是我做得不好? 任何人都知道我可以看到比較它的功能代碼嗎?

謝謝你的時間

編輯:

那是我的形象:

在此輸入圖像描述

我想消除黑色部分。

正如Micka建議的那樣,當您進行拼接時,全景圖通常是波浪狀的,因為單應性或其他投影方法不會將矩形映射到另一個矩形。 你可以通過使用一些“拉直”來補償這種效果,參考這篇文章:

M. Brown和DG Lowe。 使用不變特征自動全景圖像拼接。 IJCV,74(1):59-73,2007

至於裁剪黑色部分,我寫了這個你可以使用的類。 該類假定圖像是BGR,黑色像素具有值Vec3b(0,0,0)。 源代碼可以在這里訪問:

https://github.com/chmos/crop-images.git

最好,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM