Bonjour,

Travaillant actuellement sur la détection de point d'intérêt, j'ai constaté un problème sur le traitement des points d'intérêts trouvé avec la méthode SIFT (OpenCV).
Lors de différents tests, j'obtiens 1000 points sur chaque image.
J'apparie les points en faisant une recherche croisée du voisin le plus proche (FLANN) : j'obtiens environ 300-400 appariements.
Mais lorsque je souhaite filtrer les appariements en utilisant RANSAC (sur le modèle de la matrice d'homographie) je tombe à 20-30 appariements. J'ai essayé avec RANSAC basé sur le modèle de la matrice fondamentale mais il n'y a pas de grande différence sur le résultat final.

L'erreur de reprojection utilisée pour RANSAC correspond à l'erreur obtenue lors de la calibration (erreur d'1 pixel en moyenne). Ma recherche de point s'effectue sur des images rectifiées.

Avez-vous une idée de pourquoi mon nombre final d'appariement chute comme ça ? De plus, j'ai pu constaté que les appariements obtenus avec FLANN (ou une autre méthode) n'étaient pas corrects pour un bon nombre d'entre eux.

voici mon code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
		//Zone d'intérêt
        Mat imageLeft, imageRight;
        cvtColor(matLeftImage, imageLeft, CV_BGR2GRAY);
        cvtColor(matRightImage, imageRight, CV_BGR2GRAY);
 
        /* Test taille de l'image */
        int ratioCols = 0.5+(imageLeft.cols/1024);
        int ratioRows = 0.5+(imageRight.rows/1024);
 
        if(ratioCols%2 != 0 || ratioCols == 0) ratioCols = ratioCols + 1;
        if(ratioRows%2 != 0 || ratioRows == 0) ratioRows = ratioRows + 1;
 
 
		//déclaration et allocation des differens parametres
        vector<KeyPoint> keypointsSiftRight, keypointsSiftLeft;
        Mat descriptorsSiftRight, descriptorsSiftLeft;
        vector<Point2f> points_sift_imgLeft, points_sift_imgRight;
 
        /* On découpe l'image tel que le détecteur ne s'applique pas sur une dimension > 1024 pixels */
        feature_detector = new GridAdaptedFeatureDetector(new SIFT(nFeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma), maximumCorners,ratioRows,ratioCols);
        feature_detector->detect(imageLeft, keypointsSiftLeft);
        feature_detector->detect(imageRight, keypointsSiftRight);
 
        /* On détermine les descripteurs (dimension 128) pour chaque points d'intérêts */
        Ptr<DescriptorExtractor> featureExtractor = DescriptorExtractor::create("SIFT");
        featureExtractor->compute(imageLeft, keypointsSiftLeft, descriptorsSiftLeft);
        featureExtractor->compute(imageRight, keypointsSiftRight, descriptorsSiftRight);
 
 
        /* Appariements des points d'intérêts par FLANN */
		Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create("FlannBased");
		int knn = 1;
 
		vector<vector<DMatch> > matches12, matches21;
		vector<DMatch> filteredMatches;
 
		descriptorMatcher->knnMatch( descriptorsSiftLeft, descriptorsSiftRight, matches12, knn );
		descriptorMatcher->knnMatch( descriptorsSiftRight, descriptorsSiftLeft, matches21, knn );
 
		for( size_t m = 0; m < matches12.size(); m++ )
		{
			bool findCrossCheck = false;
			for( size_t fk = 0; fk < matches12[m].size(); fk++ )
			{
				DMatch forward = matches12[m][fk];
 
				for( size_t bk = 0; bk < matches21[forward.trainIdx].size(); bk++ )
				{
					DMatch backward = matches21[forward.trainIdx][bk];
					if( backward.trainIdx == forward.queryIdx )
					{
						filteredMatches.push_back(forward);
						findCrossCheck = true;
						break;
					}
				}
				if( findCrossCheck ) break;
			}
		}
 
		vector<int> queryIdxs( filteredMatches.size() ), trainIdxs( filteredMatches.size() );
		for( size_t i = 0; i < filteredMatches.size(); i++ )
		{
			queryIdxs[i] = filteredMatches[i].queryIdx;
			trainIdxs[i] = filteredMatches[i].trainIdx;
		}
 
		// Convertit les Keypoints en Point2f
		KeyPoint::convert(keypointsSiftLeft, pointsLeft, queryIdxs);
		KeyPoint::convert(keypointsSiftRight, pointsRight, trainIdxs);
 
 
        /* Filtrage des outliers */
		vector<uchar> status(pointsLeft.size(),0);
		findHomography(Mat(pointsLeft), Mat(pointsRight), CV_FM_RANSAC, distance, status);
 
		vector<Point2f> inliers_imgLeft, inliers_imgRight;
		for(unsigned int j=0;j<status.size();j++)
		{
			if((int)status[j] == 1) //inliers
			{
			   inliers_imgLeft.push_back(pointsLeft[j]);
			   inliers_imgRight.push_back(pointsRight[j]);
			}
		}
 
		pointsLeft.clear();
		pointsRight.clear();
		pointsLeft = inliers_imgLeft;
		pointsRight = inliers_imgRight;