2013-01-06 23 views
9

Próbuję osiągnąć następujący efekt, pokazany tutaj za pomocą narzędzia perspektywy w GIMP.Transformacja obrazu i zmiana perspektywy OpenCV

oryginalny obraz

(620x466 pikseli)

original image (620x466 pixels)

przekształcania obrazu

transforming the image

Co mam jest stała kamera i chciałby plugin powyższy transformacji figury matrycowe, w wyniku czego otrzymuje się pozbawione zniekształceń wyjście w kształcie trapezu.

Jestem świadomy, że istnieją inne opcje, które pozwolą rozproszyć obrazy w OpenCV, ale naprawdę chciałbym ręcznie dostarczyć dane z matrycy transformacji, a jednocześnie uzyskać obraz w kształcie trapezu.

Od czytania wokół Mam wrażenie warpPerspective, findHomography lub getPerspectiveTransform mogą być przydatne, ale nie wiem, jak go o to w C++

Wszelkie pomocne porady będą bardzo mile widziane.


Próbowałem z następującym kodem, ale mam tylko okno z 1 pikselem.

Może tak, jak określiłem punkty w pikselach, czy to prawda?

#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; 
} 

Odpowiedz

14

Jeśli masz trzy punkty narożne, użyj transformacji afinacji Warp. Jeśli masz cztery punkty narożne, użyj transformacji Perspective. Oto jak powinieneś użyć transformacji Perspective Warp. Wybierz cztery punkty narożne obrazu. Następnie wybierz cztery odpowiadające punkty żądanego prostokąta. Transformacja warp zajmie się resztą.

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

Dziękuję bardzo za odpowiedź, sprawdzę to później, aby zobaczyć, co otrzymuję – winterDream

-1

dodać inicjalizacji dst: Mata dst = _image.clone();

0

Następujące prace: Proszę poprawić współrzędne na obrazie wejściowym, nie dostałem pojęcia.

  #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; 
      }