2017-05-07 17 views
0

J'utilise OpenCV 3.2OpenCV - Utilisation FLANN avec des descripteurs ORB pour correspondre à des caractéristiques

Je suis en train d'utiliser FLANN pour identifier des éléments descripteurs d'une manière plus rapide que la force brutale.

// Ratio to the second neighbor to consider a good match. 
#define RATIO 0.75 

void matchFeatures(const cv::Mat &query, const cv::Mat &target, 
        std::vector<cv::DMatch> &goodMatches) { 
    std::vector<std::vector<cv::DMatch>> matches; 
    cv::Ptr<cv::FlannBasedMatcher> matcher = cv::FlannBasedMatcher::create(); 
    // Find 2 best matches for each descriptor to make later the second neighbor test. 
    matcher->knnMatch(query, target, matches, 2); 
    // Second neighbor ratio test. 
    for (unsigned int i = 0; i < matches.size(); ++i) { 
     if (matches[i][0].distance < matches[i][1].distance * RATIO) 
      goodMatches.push_back(matches[i][0]); 
    } 
} 

Ce code fonctionne avec les descripteurs SURF et SIFT, mais pas avec ORB.

OpenCV Error: Unsupported format or combination of formats (type=0) in buildIndex 

Comme il est dit here, FLANN a besoin des descripteurs pour être de type CV_32F donc nous avons besoin de les convertir.

if (query.type() != CV_32F) query.convertTo(query, CV_32F); 
if (target.type() != CV_32F) target.convertTo(target, CV_32F); 

Toutefois, ce correctif censé me retourne une erreur dans la fonction convertTo.

OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in create 

Cette affirmation est dans le fichier opencv/modules/core/src/matrix.cpp, ligne 2277.

Qu'est-ce qui se passe?


Code pour répliquer le problème.

#include <opencv2/opencv.hpp> 

int main(int argc, char **argv) { 
    // Read both images. 
    cv::Mat image1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE); 
    if (image1.empty()) { 
     std::cerr << "Couldn't read image in " << argv[1] << std::endl; 
     return 1; 
    } 
    cv::Mat image2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE); 
    if (image2.empty()) { 
     std::cerr << "Couldn't read image in " << argv[2] << std::endl; 
     return 1; 
    } 
    // Detect the keyPoints and compute its descriptors using ORB Detector. 
    std::vector<cv::KeyPoint> keyPoints1, keyPoints2; 
    cv::Mat descriptors1, descriptors2; 
    cv::Ptr<cv::ORB> detector = cv::ORB::create(); 
    detector->detectAndCompute(image1, cv::Mat(), keyPoints1, descriptors1); 
    detector->detectAndCompute(image2, cv::Mat(), keyPoints2, descriptors2); 
    // Match features. 
    std::vector<cv::DMatch> matches; 
    matchFeatures(descriptors1, descriptors2, matches); 
    // Draw matches. 
    cv::Mat image_matches; 
    cv::drawMatches(image1, keyPoints1, image2, keyPoints2, matches, image_matches); 
    cv::imshow("Matches", image_matches); 
} 

Répondre

1

Avez-vous ajusté les paramètres FLANN?

Taken de http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html

Lors de l'utilisation ORB, vous pouvez passer ce qui suit. Les valeurs commentées sont recommandées selon les documents, mais elles n'ont pas fourni les résultats requis dans certains cas. D'autres valeurs ont fonctionné très bien .:

index_params = dict (algorithme = FLANN_INDEX_LSH, table_number = 6, # 12 key_size = 12, # 20 multi_probe_level = 1) # 2

Probablement vous pouvez le convertir à C++ api?

+2

Vraiment travaillé. L'appel était 'cv :: FlannBasedMatcher matcher = cv :: FlannBasedMatcher (cv :: makePtr (12, 20, 2));' –

+1

En plus, tous les correspondances n'ont pas de correspondance en utilisant ORB et FLANN (peut-être avec d'autres descripteurs cela arrive aussi, mais pas pour l'instant). Ensuite, dans le test du second voisin, j'ai ajouté une condition de sécurité 'if (correspond à [i] .size()> = 2)'. –