Renforcer l'adéquation de la fonction de points avec OpenCV
Je veux correspondre à la fonctionnalité de points dans les images stéréo. Je l'ai déjà trouvé et extrait la fonctionnalité de points avec différents algorithmes et maintenant j'ai besoin d'une bonne correspondance. Dans ce cas, je suis en utilisant les algorithmes RAPIDES pour la détection et l'extraction, et la BruteForceMatcher
pour la mise en correspondance de la fonction de points.
Le code correspondant:
vector< vector<DMatch> > matches;
//using either FLANN or BruteForce
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(algorithmName);
matcher->knnMatch( descriptors_1, descriptors_2, matches, 1 );
//just some temporarily code to have the right data structure
vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
good_matches2.push_back(matches[i][0]);
}
Parce qu'il y a beaucoup de faux matchs je caluclated le min et le max de distance et de supprimer tous les matches sont trop mauvais:
//calculation of max and min distances between keypoints
double max_dist = 0; double min_dist = 100;
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = good_matches2[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
//find the "good" matches
vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{
if( good_matches2[i].distance <= 5*min_dist )
{
good_matches.push_back( good_matches2[i]);
}
}
Le problème, c'est que soit je reçois beaucoup de fausses correspondances ou seulement un peu de droit (voir les images ci-dessous).
(source: codemax.de)
(source: codemax.de)
Je pense que ce n'est pas un problème de programmation, mais plus d'un correspondant de chose. Que j'ai compris le BruteForceMatcher
ne concerne que la distance visuelle de la fonctionnalité de points (ce qui est stocké dans le FeatureExtractor
), pas le local distance (x&position y), qui est dans mon cas aussi un rôle important. Personne n'a aucune expérience avec ce problème ou une bonne idée pour améliorer l'adéquation entre les résultats?
MODIFIER
J'ai changé le code, qu'il me donne les 50 meilleurs matchs. Après cela, je passe par le premier match à vérifier, si c'est dans une zone spécifiée. Si elle ne l'est pas, je prends le prochain match jusqu'à ce que j'ai trouvé une correspondance à l'intérieur de la zone donnée.
vector< vector<DMatch> > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(algorithmName);
matcher->knnMatch( descriptors_1, descriptors_2, matches, 50 );
//look if the match is inside a defined area of the image
double tresholdDist = 0.25 * sqrt(double(leftImageGrey.size().height*leftImageGrey.size().height + leftImageGrey.size().width*leftImageGrey.size().width));
vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
for (int j = 0; j < matches[i].size(); j++)
{
//calculate local distance for each possible match
Point2f from = keypoints_1[matches[i][j].queryIdx].pt;
Point2f to = keypoints_2[matches[i][j].trainIdx].pt;
double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));
//save as best match if local distance is in specified area
if (dist < tresholdDist)
{
good_matches2.push_back(matches[i][j]);
j = matches[i].size();
}
}
Je pense que je n'ai pas plus de matches, mais avec ce que je suis capable de supprimer plus de fausses correspondances:
(source: codemax.de)
- Une des meilleures façons que j'ai trouvé est d'ignorer les fonctionnalités qui sont trop semblable à d'autres fonctions, c'est à dire, ne conservez que les plus spécifiques
- Par le chemin, considérez-vous à l'aide de ORBE? Il a invariance de rotation et de l'invariance d'échelle, qui RAPIDEMENT ne semble pas avoir
Vous devez vous connecter pour publier un commentaire.
Une autre méthode de détermination de haute qualité fonction de matches est le rapport de test proposé par David Lowe, dans son article sur TAMISER (à la page 20 pour une explication). Ce test rejette pas bons matchs en calculant le ratio entre le meilleur et deuxième meilleur match. Si le ratio est inférieur à un certain seuil, le match est donc pas considéré comme étant de faible qualité.
En comparant toutes disposent d'algorithmes de détection, j'ai trouvé une bonne combinaison, ce qui me donne beaucoup plus de matches. Maintenant, je suis RAPIDE pour la détection de fonctionnalité, TAMISER pour l'extraction de caractéristiques et de BruteForce pour la mise en correspondance. Combiné avec le chèque, si les matchs est à l'intérieur d'une région définie, je reçois beaucoup de matchs, voir l'image:
(source: codemax.de)
Le code:
D'ailleurs ratio de test, vous pouvez:
Utiliser uniquement symétrique des correspondances:
et depuis sa une image stéréo utiliser ransac test: