ステレオ画像の特徴点を合わせたい。私はすでにさまざまなアルゴリズムで特徴点を見つけて抽出しましたが、今は適切に一致させる必要があります。この場合、検出と抽出、およびBruteForceMatcher
特徴点のマッチングに FAST アルゴリズムを使用しています。
一致するコード:
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]);
}
多くの誤った一致があるため、最小距離と最大距離を計算し、悪すぎるすべての一致を削除しました。
//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]);
}
}
問題は、多くの誤った一致が得られるか、正しい一致がわずかしか得られないことです (下の画像を参照)。
(出典: codemax.de )
(出典: codemax.de )
プログラミングの問題ではなく、マッチングの問題だと思います。私が理解している限りでは、ローカル距離 (x&y 位置) ではなく、BruteForceMatcher
特徴点の視覚的距離 (に保存されます) のみが考慮されます。これは、私の場合も重要です。FeatureExtractor
この問題を経験した人や、マッチング結果を改善するための良いアイデアはありますか?
編集
コードを変更して、50 個のベスト マッチが得られるようにしました。この後、指定されたエリアにあるかどうかを確認するために最初の一致を実行します。そうでない場合は、指定されたエリア内で一致が見つかるまで次の一致を行います。
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();
}
}
これ以上の一致は得られないと思いますが、これにより、より多くの誤った一致を削除できます。
(出典: codemax.de )