質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2599閲覧

opencv 動画でのマッチングを行いたい(画像でのマッチングは可能)

yezyez

総合スコア13

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/30 04:39

画像でのマッチング

C++

1include <opencv2/highgui/highgui.hpp> 2include <opencv2/imgproc/imgproc.hpp> 3include <opencv2/features2d/features2d.hpp> 4include <opencv2/calib3d/calib3d.hpp> 5include <opencv2/xfeatures2d/nonfree.hpp> 6include <iostream> 7 8using namespace cv; 9using namespace std; 10 11int main(void) 12{ 13 14 int idx[2000]; 15 int x,y,i = 0; 16 int x2,y2,i2 = 0; 17 int x3,y3 = 0; 18 int x4,y4 = 0; 19 int i5 = 0; 20 double dis,ave = 0; 21 int distance = 0; 22 int i6 = 0; 23 int y5 = 0; 24 int y6 = 0; 25 int focus = 330; 26 double camera = 0.005; 27 int cameradistance = 50; 28 29 //動画読み込み 30 Mat img_src1; 31 Mat img_src2; 32 33 //keypoint用のMat 34 Mat dst; 35 Mat dst2; 36 37 VideoCapture cap("r1.mp4"); 38 VideoCapture cap2("r2.mp4"); 39 40 //動画の表示 41 int max_frame = cap.get(CV_CAP_PROP_FRAME_COUNT); //フレーム数 42 for(int i = 0; i < max_frame; i++){ 43 cap >> img_src1 ; 44 cap2 >> img_src2 ; 45 46 auto akaze = AKAZE::create(AKAZE::DESCRIPTOR_MLDB,0,3,0.001f); 47 48 vector<KeyPoint> keypoints1,keypoints2; 49 akaze->detect(img_src1,keypoints1); 50 akaze->detect(img_src2,keypoints2); 51 52 Mat descriptor1, descriptor2; 53 akaze->compute(img_src1, keypoints1, descriptor1); 54 akaze->compute(img_src2, keypoints2, descriptor2); 55 56 drawKeypoints(img_src1,keypoints1,dst);//原画像に特徴点記述 57 drawKeypoints(img_src2,keypoints2,dst2);//原画像に特徴点記述 58 imshow( "leftcamerakey", dst);//特徴点記述後の動画表示 59 imshow( "rightcamerakey", dst2);//特徴点記述後の動画表示 60 61 //DescriptorMatcherオブジェクトの生成 62 Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");//BruteForce-Hamming 63 64 // 特徴点のマッチング情報を格納する変数 65 vector<DMatch> dmatch, match; 66 67 //特徴点マッチングの実行 68 matcher->match(descriptor1, descriptor2, match);// 最小距離の取得 69 double min_dist = DBL_MAX;//double の最大値ß 70 71 for(int i = 0; i < (int)match.size(); i++){ 72 double dist = match[i].distance;//画像間の特徴点距離 73 74 //特徴点間の最小距離を求める 75 if(dist < min_dist){ 76 min_dist = dist; 77 78 cout << "min_distance" << " " << min_dist << "\n"; 79 80 /* 81 //特徴量の表示descriptor1 82 Mat d(descriptor1,Rect(0,kppp1_idx,descriptor1.cols,1)); 83 cout << "descriptor1 " << kppp1_idx+1 << ": " << d << endl; 84 //特徴量の表示descriptor2 85 Mat d2(descriptor2,Rect(0,kppp2_idx,descriptor2.cols,1)); 86 cout << "descriptor2 " << kppp2_idx+1 << ": " << d2 << endl; 87 88 //cout << "min_distance" << " " << min_dist << "\n"; 89 */ 90 } 91 92 } 93 // しきい値を設定する 94 const double threshold = 3.0 * min_dist; 95 cout << "threshold"<< " "<< threshold << "\n"; 96 for(int i = 0; i < (int)match.size(); i++){ 97 int kpp1_idx = match[i].queryIdx; // keypoint1 のインデックス 98 int kpp2_idx = match[i].trainIdx; // keypoint2 のインデックス 99 /* 画像1の対応点座標 */ 100 y5 = keypoints1[kpp1_idx].pt.y; 101 /* 画像2の対応点座標 */ 102 y6 = keypoints2[kpp2_idx].pt.y; 103 if(match[i].distance < threshold && y5 < y6+10 && y5 > y6-10){ 104 idx[i] = 1; 105 dmatch.push_back(match[i]); 106 107 }else{ 108 idx[i] = -1; 109 110 } 111 112 } 113 for(int i = 0; i < (int)match.size(); i++){ 114 int kp1_idx = match[i].queryIdx; // keypoint1 のインデックス 115 int kp2_idx = match[i].trainIdx; // keypoint2 のインデックス 116 117 if(idx[i] != -1){ 118 // 画像1の対応点座標 119 x3 = keypoints1[kp1_idx].pt.x; 120 y3 = keypoints1[kp1_idx].pt.y; 121 // 画像2の対応点座標 122 x4 = keypoints2[kp2_idx].pt.x; 123 y4 = keypoints2[kp2_idx].pt.y; 124 125 i5++; 126 cout << "dmatch " << i5 << " \n"; 127 128 //座標表示 129 cout << "keypoint1 "<< kp1_idx+1 << " x=" << x3 << " y=" << y3 << " " << "keypoint2 "<< kp2_idx+1 << " x=" << x4 << " y=" << y4 << "\n"; 130 dis += (x3-x4); 131 ave = dis/i5; 132 } 133 } 134 135 //cout << "x軸の特徴点座標差異の平均値は" << ave << "です\n"; 136 cout << "対象までの距離は" << ((cameradistance*focus)/(camera*ave))/1000 << "cmです\n"; 137 138 Mat dest; 139 drawMatches(img_src1, keypoints1, img_src2, keypoints2, dmatch, dest,DrawMatchesFlags::DEFAULT); 140 //DrawMatchesFlags::DEFAULT 141 142 imshow("result",dest); 143 waitKey( 0 ); 144 } 145 return 0; 146} 147

VideoCapture cap("r1.mp4");
VideoCapture cap2("r2.mp4");より読み込んだ同画像に対して、
//動画の表示
int max_frame = cap.get(CV_CAP_PROP_FRAME_COUNT); //フレーム数
for(int i = 0; i < max_frame; i++){
cap >> img_src1 ;
cap2 >> img_src2 ;
の箇所で動画のフレームごとに画像としてimg_src1,img_src2として処理を行っております。
descriptor1,descriptor2には画像の特徴量が検出されていることは確認していますがマッチングを行った際の特徴点間の類似度などの値が計算されません。

実行結果

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

最後がinfと表示されているのは,aveの値が0であるために0-divideになったのでしょう.

"対象までの距離は"

というコードの雰囲気的にステレオ法かな?と思うのですが,
もうもそうであれば,
座標が一致する(距離が0になる)遠方の点の視差を用いる処理ではダメだろうと思います.
「対象」の像の上に検出された特徴点を対象とした処理を行うべきです.

投稿2020/06/30 04:55

編集2020/06/30 04:57
fana

総合スコア11656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問