ORBでホモグラフィー行列推定

SIFTとかSURFでよくあるサンプルをORBで動かしてみました。

↓ここのやつですね。
http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html

十分な対応点が得られない場合や、ホモグラフィー行列がうまく推定できなかった場合のエラー処理が入っていなかったので追加しています。

#include <opencv2/opencv.hpp>

// --------------------------------------------------------------------------
// main(Number of arguments, Argument values)
// Description : This is the entry point of the program.
// Return value : SUCCESS:0 ERROR:-1
// --------------------------------------------------------------------------
int main(int argc, char **argv)
{
// ORB
cv::OrbFeatureDetector detector;
cv::OrbDescriptorExtractor extractor;

// 読み込み
cv::Mat image1 = cv::imread("box.png");
cv::Mat image2 = cv::imread("box_in_scene.png");

// 特徴点1
std::vector<cv::KeyPoint> keypointsA;
cv::Mat descriptorsA;
detector.detect(image1, keypointsA);
extractor.compute(image1, keypointsA, descriptorsA);

// 特徴点2
std::vector<cv::KeyPoint> keypointsB;
cv::Mat descriptorsB;
detector.detect(image2, keypointsB);
extractor.compute(image2, keypointsB, descriptorsB);

// マッチング
cv::BFMatcher matcher(cv::NORM_HAMMING, true);
std::vector<cv::DMatch> matches;
matcher.match(descriptorsA, descriptorsB, matches);

// 最小距離
double min_dist = DBL_MAX;
for (int i = 0; i < (int)matches.size(); i++) {
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
}

// 良いペアのみ残す
std::vector<cv::DMatch> good_matches;
for (int i = 0; i < (int)matches.size(); i++) {
if (matches[i].distance < 3.0 * min_dist) good_matches.push_back(matches[i]);
}

// 対応点の表示
cv::Mat img_matches;
cv::drawMatches(image1, keypointsA, image2, keypointsB, good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

// 十分な対応点がある
if (good_matches.size() > 10) {
std::vector<cv::Point2f> obj, scene;
for (int i = 0; i < (int)good_matches.size(); i++) {
obj.push_back(keypointsA[good_matches[i].queryIdx].pt);
scene.push_back(keypointsB[good_matches[i].trainIdx].pt);
}

// ホモグラフィー行列を計算
cv::Mat H = cv::findHomography(obj, scene, cv::RANSAC);
//std::cout << H << std::endl;

// 行列が空ではない
if (!H.empty()) {
std::vector<cv::Point2d> obj_corners(4), scene_corners(4);
obj_corners[0] = scene_corners[0] = cv::Point2d(0, 0);
obj_corners[1] = scene_corners[1] = cv::Point2d(image1.cols, 0);
obj_corners[2] = scene_corners[2] = cv::Point2d(image1.cols, image1.rows );
obj_corners[3] = scene_corners[3] = cv::Point2d(0, image1.rows);

// ホモグラフィ行列の推定
cv::perspectiveTransform(obj_corners, scene_corners, H);

// 緑の線で囲む (開始点を元画像が左にあるので右にオフセット)
cv::line(img_matches, scene_corners[0] + cv::Point2d(image1.cols, 0), scene_corners[1] + cv::Point2d(image1.cols, 0), cv::Scalar(0, 255, 0), 4);
cv::line(img_matches, scene_corners[1] + cv::Point2d(image1.cols, 0), scene_corners[2] + cv::Point2d(image1.cols, 0), cv::Scalar(0, 255, 0), 4);
cv::line(img_matches, scene_corners[2] + cv::Point2d(image1.cols, 0), scene_corners[3] + cv::Point2d(image1.cols, 0), cv::Scalar(0, 255, 0), 4);
cv::line(img_matches, scene_corners[3] + cv::Point2d(image1.cols, 0), scene_corners[0] + cv::Point2d(image1.cols, 0), cv::Scalar(0, 255, 0), 4);
}
}

// 表示
cv::imshow("camera", img_matches);
cv::waitKey(0);

return 0;
}

結果はこんな感じです。
orb_homography.jpg

うん、いいんじゃない?
関連記事

コメントの投稿

非公開コメント

プロフィール

puku

Author:puku
暇な時はゲームかプログラミングしてる人だよ。
だいたい月1更新。
CV Drone はこちら(GitHub)

最近はQiitaでOnsenUI2で遊んでいる。

最新記事
最新コメント
最新トラックバック
検索フォーム
カレンダー
04 | 2023/05 | 06
- 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 - - -
月別アーカイブ
カテゴリ
スポンサードリンク
RSSリンクの表示
FC2カウンター
リンク
ブロとも申請フォーム

この人とブロともになる

アクセスランキング
[ジャンルランキング]
コンピュータ
822位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
152位
アクセスランキングを見る>>
FC2ブログランキング

FC2Blog Ranking

QRコード
QR