u014173467 于 2016.01.21 10:28 提问

``````  Mat img1 = imread( "q.jpg", CV_LOAD_IMAGE_GRAYSCALE );

//-- Step 1: Detect the keypoints using Sift Detector
SiftFeatureDetector  detector( hessian );

vector<KeyPoint> queryKeypoints, trainKeypoints;

detector.detect( img1, queryKeypoints );
detector.detect( img2, trainKeypoints );

//-- Step 2: Extract the keypoints using Sift Extractor
Mat queryDescriptor,trainDescriptor;// extract keypoints
SiftDescriptorExtractor extractor;  //Create Descriptor Extractor
extractor.compute( img1, queryKeypoints, queryDescriptor );
extractor.compute( img2, trainKeypoints, trainDescriptor );

//--Step3: Match
vector<vector<DMatch>> m_knnMatches;
vector<DMatch>m_Matches;
vector<DMatch>n_Matches;
const float minRatio = 1.f / 1.5f;

matcher.knnMatch(queryDescriptor,trainDescriptor,m_knnMatches,3);
for (size_t i=0; i<m_knnMatches.size(); i++)
{
const cv::DMatch& bestMatch = m_knnMatches[i][0];
const cv::DMatch& betterMatch = m_knnMatches[i][1];
const cv::DMatch& betterrMatch = m_knnMatches[i][2];
float distanceRatio = bestMatch.distance / betterMatch.distance;
float distanceRatio1 = betterMatch.distance / betterrMatch.distance;
if (distanceRatio < minRatio)
{
m_Matches.push_back(bestMatch);
}
if (distanceRatio1 < minRatio)
{
n_Matches.push_back(betterMatch);
}
}

Mat img_matches;
drawMatches( img1,queryKeypoints,img2,trainKeypoints,m_Matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

Mat img_matches2;
drawMatches( img1,queryKeypoints,img2,trainKeypoints,n_Matches, img_matches2, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

``````

3个回答

wangyaninglm      2016.01.21 10:46

u014173467 感谢您的解答！ 已附上代码望指教~

wangyaninglm      2016.01.21 17:19

surf是尺度不变的啊，你这个有仿射变换问题应该也不是很大，你这个knn就找前三个？是不是有点少了

u014173467 Hi~ 感谢您的回复！我去试下滤波

wangyaninglm      2016.02.29 10:42

`````` //-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
//-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{
if( matches[i].distance < 0.6*max_dist )
{
good_matches.push_back( matches[i]);
}
}

Mat img_matches;
drawMatches(img_1, keyPoints_1, img_2, keyPoints_2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
``````