2017-07-05 8 views
0

Ich habe ein Programm erstellt, das mehrere Bilder zusammenfügen kann und jetzt die Effizienz zu verbessern sucht. Abhängig von der Größe des zusammengesetzten Bildes ist es möglicherweise zu groß und enthält zu viele Schlüsselpunkte, so dass der Maschine nicht mehr zuweisbarer Speicher zur Verfügung steht. Um dies zu kompensieren, ist es mein Ziel, alle gefundenen Schlüsselpunkte und Deskriptoren so zu speichern, dass ich sie nicht mehr im gesampelten Hauptbild finden muss und sie nur im neu zu stitchenden Bild finden muss. Ich hatte diesen Prozess in Python, aber hatte nicht das gleiche Glück in C++. Um dies zu tun, muss ich einen perspectiveTransform() auf den Schlüsselpunkten durchführen und daher von vector<keypoint> zu vector<point2f> und zurück zu vector<keypoint> konvertieren. Ich konnte dies erreichen und kann bestätigen, dass es funktioniert (wählen Sie, um zu folgen). Ich bin nicht sicher, ob der gleiche Prozess zu den Deskriptoren getan werden muss (derzeit habe ich es aber entweder falsch oder nicht wirksam).OpenCV C++ erstellen wiederverwendbare Reihe von Keypoints und Deskriptoren zum Zusammenfügen mehrerer Bilder

Problem: Wenn ich das ausführe, scheinen die Schlüsselpunkte und Deskriptoren nicht zu funktionieren und ich erstelle einen Fehler, den ich erstellt habe: "Nicht genug Übereinstimmungen gefunden" obwohl ich weiß, dass zumindest die Schlüsselpunkte zur Funktion kommen .

Hier ist der Code für die Schlüsselpunkt- und Deskriptortransformationen. Der Code berechnet zuerst die WarpPerspektive, die auf Bild eins angewendet wird, da Homographie nur das zweite Bild verzerrt. Der Rest des Codds befasst sich mit Schlüsselpunkten und Deskriptoren.

tuple<Mat, vector<KeyPoint>, Mat> stitchMatches(Mat image1,Mat image2, Mat homography, vector<KeyPoint> kp1, vector<KeyPoint> kp2 , Mat desc1, Mat desc2){ 
    Mat result, destination, descriptors_updated; 
    vector<Point2f> fourPoint; 
    vector<KeyPoint> keypoints_updated; 

    //-Get the four corners of the first image (master) 
    fourPoint.push_back(Point2f (0,0)); 
    fourPoint.push_back(Point2f (image1.size().width,0)); 
    fourPoint.push_back(Point2f (0, image1.size().height)); 
    fourPoint.push_back(Point2f (image1.size().width, image1.size().height)); 
    //perspectiveTransform(Mat(fourPoint), destination, homography); 


    //- Get points used to determine Htr 
    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(fourPoint.at(0).x, fourPoint.at(1).x); 
    min_x2 = min(fourPoint.at(2).x, fourPoint.at(3).x); 
    min_y1 = min(fourPoint.at(0).y, fourPoint.at(1).y); 
    min_y2 = min(fourPoint.at(2).y, fourPoint.at(3).y); 
    max_x1 = max(fourPoint.at(0).x, fourPoint.at(1).x); 
    max_x2 = max(fourPoint.at(2).x, fourPoint.at(3).x); 
    max_y1 = max(fourPoint.at(0).y, fourPoint.at(1).y); 
    max_y2 = max(fourPoint.at(2).y, fourPoint.at(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); 

    //- Htr use to map image one to result in line with the alredy warped image 1 
    Mat Htr = Mat::eye(3,3,CV_64F); 
    if (min_x < 0){ 
     tam_x = image2.size().width - min_x; 
     Htr.at<double>(0,2)= -min_x; 
    } 
    if (min_y < 0){ 
     tam_y = image2.size().height - min_y; 
     Htr.at<double>(1,2)= -min_y; 
    } 

    result = Mat(Size(tam_x*2,tam_y*2), CV_8UC3,cv::Scalar(0,0,0)); 
    warpPerspective(image2, result, Htr, result.size(), INTER_LINEAR, BORDER_TRANSPARENT, 0); 
    warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0); 



    //-- Variables to hold the keypoints at the respective stages 
    vector<Point2f> kp1Local,kp2Local; 
    vector<KeyPoint> kp1updated, kp2updated; 


    //Localize the keypoints to allow for perspective change 
    KeyPoint::convert(kp1, kp1Local); 
    KeyPoint::convert(kp2, kp2Local); 

    //perform persepctive transform on the keypoints of type vector<point2f> 
    perspectiveTransform(kp1Local, kp1Local, (Htr)); 
    perspectiveTransform(kp2Local, kp2Local, (Htr*homography)); 


    //convert keypoints back to type vector<keypoint> 
    for(size_t i = 0; i < kp1Local.size(); i++) { 
     kp1updated.push_back(KeyPoint(kp1Local[i], 1.f)); 
    } 
    for(size_t i = 0; i < kp2Local.size(); i++) { 
     kp2updated.push_back(KeyPoint(kp2Local[i], 1.f)); 
    } 

    //Add to master of list of keypoints to be passed along during next iteration of image 
    keypoints_updated.reserve(kp1updated.size() + kp2updated.size()); 
    keypoints_updated.insert(keypoints_updated.end(),kp1updated.begin(),kp1updated.end()); 
    keypoints_updated.insert(keypoints_updated.end(),kp2updated.begin(),kp2updated.end()); 

    //WarpPerspective of decriptors to match that of the images and cooresponding keypoints 
    Mat desc1New, desc2New; 
    warpPerspective(desc2, desc2New, Htr, result.size(), INTER_LINEAR, BORDER_TRANSPARENT, 0); 
    warpPerspective(desc1, desc1New, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0); 

    //create a new Mat including the descriports from desc1 and desc2 
    descriptors_updated.push_back(desc1New); 
    descriptors_updated.push_back(desc2New); 


    //------------TEST TO see if keypoints have moved 

    Mat img_keypoints; 
    drawKeypoints(result, keypoints_updated, img_keypoints, Scalar::all(-1), DrawMatchesFlags::DEFAULT); 

    imshow("Keypoints 1", img_keypoints); 
    waitKey(); 
    destroyAllWindows(); 



    return {result, keypoints_updated, descriptors_updated}; 
} 

Der folgende Code ist mein Master-Stitching-Programm, das das eigentliche Stitching ausführt.

Zuletzt ist hier das Bild der Schlüsselpunkte, die auf das genähte Bild umgewandelt werden. Jede Hilfe wird so sehr geschätzt!

enter image description here

Antwort

1

Nachdem man durch das Kämmen ich zufällig die falsche Variable an einem Punkt, den ich finden wurde mit! :)

Verwandte Themen