2013-01-06 226 views
9

我試圖實現以下效果,這裏使用GIMP中的透視工具顯示。OpenCV圖像轉換和透視變化

原始圖像(620x466個像素)

original image (620x466 pixels)

變換圖像

transforming the image

什麼我是一個固定的網絡攝像頭,並想插件上述變換矩陣圖形,從而形成梯形形狀不失真的輸出。

我知道有可用在OpenCV中以undistort圖像其他選擇,但我真的想手動提供變換矩陣數字,同時具有梯形形狀的圖像結束了。

從閱讀圍繞我有一種感覺warpPerspectivefindHomographygetPerspectiveTransform可能是有用的,但不知道如何去這在C++

任何有用的建議,將不勝感激。


試着用下面的代碼運行,但我只得到一個窗口顯示1像素。

也許我已經在指定的像素點的方式,這是正確的?

#include <opencv2/core/core.hpp> 
    #include <opencv2/opencv.hpp> 
    #include <cv.h> 
    #include <opencv2/highgui/highgui.hpp> 
    #include <iostream> 

    using namespace cv; 
    using namespace std; 

      cv::Mat OpenWarpPerspective(const cv::Mat& _image 
       , const cv::Point2f& _lu 
       , const cv::Point2f& _ru 
       , const cv::Point2f& _rd 
       , const cv::Point2f& _ld 
       , const cv::Point2f& _lu_result 
       , const cv::Point2f& _ru_result 
       , const cv::Point2f& _rd_result 
       , const cv::Point2f& _ld_result 
       , cv::Mat& _transform_matrix) 
      { 
       // todo do some checks on input. 

       cv::Point2f source_points[4]; 
       cv::Point2f dest_points[4]; 


       source_points[0] = _lu; 
       source_points[1] = _ru; 
       source_points[2] = _rd; 
       source_points[3] = _ld; 

       dest_points[0] = _lu_result; 
       dest_points[1] = _ru_result; 
       dest_points[2] = _rd_result; 
       dest_points[3] = _ld_result; 

       cv::Mat dst; 
       _transform_matrix = cv::getPerspectiveTransform(source_points, dest_points); 
       cv::warpPerspective(_image, dst, _transform_matrix, dst.size()); 

       return dst; 
      } 

    int main(int argc, char** argv) 
    { 

     Mat image; 
     Mat edited; 

     image = imread("c:/org.png", CV_LOAD_IMAGE_COLOR); // Read the file 

     namedWindow("Display window", CV_WINDOW_AUTOSIZE);// Create a window for display. 

      Point2f one = (0.0, 0.0); 
      Point2f two = (317.0, 0.0); 
      Point2f three = (317.0, 240.0); 
      Point2f four = (0.0, 240.0); 

      Point2f five = (-100.0, 0.0); 
      Point2f six = (617.0, 0.0); 
      Point2f seven = (317.0, 240.0); 
      Point2f eight = (0.0, 240.0); 

      OpenWarpPerspective(image,one,two,three,four,five,six,seven,eight,edited); 

     imshow("Display window", edited);     // Show our image inside it. 

     waitKey(0);           // Wait for a keystroke in the window 
     return 0; 
} 

回答

14

如果您有三個角點使用扭曲仿射變換。如果您有四個角點使用扭曲透視變換。這裏是你應該如何使用Warp Perspective轉換。選擇圖像的四個角點。然後選擇所需矩形的四個對應點。經變換將完成剩下的工作。

cv::Mat OpenWarpPerspective(const cv::Mat& _image 
    , const cv::Point2f& _lu 
    , const cv::Point2f& _ru 
    , const cv::Point2f& _rd 
    , const cv::Point2f& _ld 
    , const cv::Point2f& _lu_result 
    , const cv::Point2f& _ru_result 
    , const cv::Point2f& _rd_result 
    , const cv::Point2f& _ld_result 
    , cv::Mat& _transform_matrix) 
{ 
    // todo do some checks on input. 

    cv::Point2f source_points[4]; 
    cv::Point2f dest_points[4]; 


    source_points[0] = _lu; 
    source_points[1] = _ru; 
    source_points[2] = _rd; 
    source_points[3] = _ld; 

    dest_points[0] = _lu_result; 
    dest_points[1] = _ru_result; 
    dest_points[2] = _rd_result; 
    dest_points[3] = _ld_result; 

    cv::Mat dst; 
    _transform_matrix = cv::getPerspectiveTransform(source_points, dest_points); 
    cv::warpPerspective(_image, dst, _transform_matrix, cv::Size(_width, _height)); 

    return dst; 
} 
+0

非常感謝您的回覆,稍後會檢查此事以查看我得到的結果 – winterDream

-1

添加DST的初始化: 墊DST = _image.clone();

0

以下工作: 請正確輸入圖像的座標,我did'nt得到線索。

  #include <opencv2/core/core.hpp> 
      #include <opencv2/opencv.hpp> 
      //#include "cv.hpp" 
      #include <opencv2/highgui/highgui.hpp> 
      #include <iostream> 

      using namespace cv; 
      using namespace std; 

      cv::Mat OpenWarpPerspective(const cv::Mat& _image 
       , const cv::Point2f& _lu 
       , const cv::Point2f& _ru 
       , const cv::Point2f& _rd 
       , const cv::Point2f& _ld 
       , const cv::Point2f& _lu_result 
       , const cv::Point2f& _ru_result 
       , const cv::Point2f& _rd_result 
       , const cv::Point2f& _ld_result 
       ) 
      { 
       // todo do some checks on input. 

       cv::Point2f source_points[4]; 
       cv::Point2f dest_points[4]; 
       cv::Mat _transform_matrix; 

       source_points[0] = _lu; 
       source_points[1] = _ru; 
       source_points[2] = _rd; 
       source_points[3] = _ld; 

       dest_points[0] = _lu_result; 
       dest_points[1] = _ru_result; 
       dest_points[2] = _rd_result; 
       dest_points[3] = _ld_result; 

       cv::Mat dst = _image.clone(); 
       _transform_matrix = cv::getPerspectiveTransform(source_points, dest_points); 
       cv::warpPerspective(_image, dst, _transform_matrix, dst.size()); 

       return dst; 
      } 

      int main(int argc, char** argv) 
      { 

       Mat image; 
       Mat edited; 

       image = imread("img.png", CV_LOAD_IMAGE_COLOR); // Read the file // original image(620x466 pixels) 
       imshow("InputImage", image); 
       waitKey(0); 


       Point2f one = (0.0, 0.0); 
       Point2f two = (500.0, 0.0); 
       Point2f three = (500.0, 100.0); 
       Point2f four = (250.0, 100.0); 

       Point2f five = (250.0, 0.0); 
       Point2f six = (500.0, 0.0); 
       Point2f seven = (500.0, 1000.0); 
       Point2f eight = (250.0, 100.0); 



       edited= OpenWarpPerspective(image, one, two, three, four, five, six, seven, eight); 

       namedWindow("Display window", CV_WINDOW_AUTOSIZE);// Create a window for display. 
       imshow("Display window", edited);     // Show our image inside it. 

       waitKey(0);           // Wait for a keystroke in the window 
       return 0; 
      }