2017-06-08 2 views
0

Bonjour et merci pour votre aide.OpenCV: Comment utiliser AffineTransformer

Je voudrais tester l'utilisation de formes pour l'appariement dans OpenCV et réussi à faire la partie correspondante. Pour localiser la forme tournée, je pensais que le AffineTransformer Class serait le bon choix. Comme je ne sais pas comment le jumelage fonctionnerait à l'interne, ce serait bien si quelqu'un a un lien où les procédures sont décrites. Comme shawshank a mentionné mon code suivant, une assertion a échoué car la variable correspondante est vide lorsqu'elle est passée à la fonction estimateTransformation. Est-ce que quelqu'un sait comment utiliser cette fonction de la bonne façon?

#include<opencv2/opencv.hpp> 
#include<algorithm> 
#include<iostream> 
#include<string> 
#include<opencv2/highgui/highgui.hpp> 

using namespace std; 
using namespace cv; 

bool rotateImage(Mat src, Mat &dst, double angle) 
{ 
    // get rotation matrix for rotating the image around its center 
    cv::Point2f center(src.cols/2.0, src.rows/2.0); 
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0); 
    // determine bounding rectangle 
    cv::Rect bbox = cv::RotatedRect(center,src.size(), angle).boundingRect(); 
    // adjust transformation matrix 
    rot.at<double>(0,2) += bbox.width/2.0 - center.x; 
    rot.at<double>(1,2) += bbox.height/2.0 - center.y; 

    cv::warpAffine(src, dst, rot, bbox.size()); 
    return 1; 
} 


static vector<Point> sampleContour(const Mat& image, int n=300) 
{ 

    vector<vector<Point>> contours;   
    vector<Point> all_points;      
    findContours(image, contours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE); 
    for (size_t i=0; i <contours.size(); i++) 
    { 
     for (size_t j=0; j<contours[i].size(); j++) 
     { 
      all_points.push_back(contours[i][j]); 
     } 
    } 

    int dummy=0; 
    for (int add=(int)all_points.size(); add<n; add++) 
    { 
     all_points.push_back(all_points[dummy++]); 
    } 

    // shuffel 
    random_shuffle(all_points.begin(), all_points.end()); 
    vector<Point> sampled; 
    for (int i=0; i<n; i++) 
    { 
     sampled.push_back(all_points[i]); 
    } 
    return sampled; 
} 


int main(void) 
{ 
    Mat img1, img2; 
    vector<Point> img1Points, img2Points; 
    float distSC, distHD; 

    // read images 
    string img1Path = "testimage.jpg"; 
    img1 = imread(img1Path, IMREAD_GRAYSCALE); 
    rotateImage(img1, img2, 45); 
    imshow("original", img1); 
    imshow("transformed", img2); 
    waitKey(); 

    // Contours 
    img1Points = sampleContour(img1); 
    img2Points = sampleContour(img2); 

    //Calculate Distances 
    Ptr<ShapeContextDistanceExtractor> mysc = createShapeContextDistanceExtractor(); 
    Ptr<HausdorffDistanceExtractor> myhd = createHausdorffDistanceExtractor(); 

    distSC = mysc->computeDistance(img1Points, img2Points); 
    distHD = myhd -> computeDistance(img1Points, img2Points); 

    cout << distSC << endl << distHD << endl; 
    vector<DMatch> matches; 
    Ptr<AffineTransformer> transformerHD = createAffineTransformer(0); 
    transformerHD -> estimateTransformation(img1Points, img2Points, matches); 
    return 0; 
} 
+0

Pouvez-vous indiquer quelle était l'erreur d'assertion? –

+0

bien sûr, j'obtiens cette erreur: Erreur OpenCV: Échec de l'assertion (src.cols> 0 && src.rows> 0) dans warpAffine, fichier /build/opencv/src/opencv-3.2.0/modules/imgproc/src/ imgwarp.cpp, ligne 5977 terminate appelée après avoir lancé une instance de 'cv :: Exception' what(): /build/opencv/src/opencv-3.2.0/modules/imgproc/src/imgwarp.cpp:5977: erreur: (-215) src.cols> 0 && src.rows> 0 dans la fonction warpAffine – FranzKaiser

+0

Cette assertion signifie que votre image d'entrée à 'warpAffine' est vide. Vous devez déboguer le code pour voir quelle image est transmise à la fonction. –

Répondre

0

J'ai utilisé la classe AffineTransformer sur une image 2D. Voici le code de base qui vous donnera une idée de ce qu'il fait.

// My OpenCv AffineTransformer demo code 
// I have tested this on a 500 x 500 resolution image 
#include <iostream> 
#include "opencv2/opencv.hpp" 
#include <vector> 
using namespace cv; 
using namespace std; 

int arrSize = 10; 
int sourcePx[]={154,155,159,167,182,209,238,265,295,316}; 
int sourcePy[]={190,222,252,285,314,338,344,340,321,290}; 
int tgtPx[]={120,127,137,150,188,230,258,285,305,313}; 
int tgtPy[]={207,245,275,305,336,345,342,332,305,274}; 

int main() 
{ 
    // Prepare 'vector of points' from above hardcoded points 
    int sInd=0, eInd=arrSize; 
    vector<Point2f> sourceP; for(int i=sInd; i<eInd; i++) sourceP.push_back(Point2f(sourcePx[i], sourcePy[i])); 
    vector<Point2f> tgtP; for(int i=sInd; i<eInd; i++) tgtP.push_back(Point2f(tgtPx[i], tgtPy[i])); 

    // Create object of AffineTransformer 
    bool fullAffine = true; // change its value and see difference in result 
    auto aft = cv::createAffineTransformer(fullAffine); 

    // Prepare vector<cv::DMatch> - this is just mapping of corresponding points indices 
    std::vector<cv::DMatch> matches; 
    for(int i=0; i<sourceP.size(); ++i) matches.push_back(cv::DMatch(i, i, 0)); 

    // Read image 
    Mat srcImg = imread("image1.jpg"); 
    Mat tgtImg; 

    // estimate points transformation 
    aft->estimateTransformation(sourceP, tgtP, matches); 
    // apply transformation 
    aft->applyTransformation(sourceP, tgtP); 
    // warp image 
    aft->warpImage(srcImg, tgtImg); 
    // show generated output 
    imshow("warped output", tgtImg); 
    waitKey(0); 

    return 0; 
}