前回、前々回と画像特徴点の抽出関数を「手習ひ」。今回は抽出した特徴点(位置)から記述子を計算し、一方の画像に一致する可能性の高い別な画像(回転しているので単純画像比較は不可)を見つける操作を行ってみます。といってHelpファイルに書かれている方法そのままなんだけれども。やっぱアルゴリズムによって結果は違うみたい。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上の Scilab2024.0.0およびScilab上のScilab IPCVツールボックスを使用させていただいております。
画像の「一致」を見つけるためのステップ
画像Srefと画像Strgの「一致」を求める方法、ツールボックスのHelpファイルに書かれている通りのもの、をお惚け老人がかいつまんだものが以下に。
-
- 画像Srefと画像Strgを読み込む
- 画像特徴点の抽出関数を使いSrefとStrgの特徴点をそれぞれ抽出
- それぞれの特徴点の周りの記述子(descriptor)を計算
- 計算した記述子をマッチング(Brute-Force matcher)
- 結果を元画像上に表示
2のところで、前回まで練習した
imdetect_ほにゃらら
「ほにゃらら」にはアルゴリズム名が入ります、を使用。
3では同様な以下の関数を使用。
imextract_Descriptorほにゃらら
4には、
immatch_BruteForce
を使い、さらにマッチの上位点のみに以下関数で絞りこみます。
imbestmatches
そして5の表示は以下関数です。
imdrawmatches
対象画像
対象画像は以下としました。以下の交通標識、徐行っすね、を45度傾けた画像を準備してあります。
そして以下の交通標識群と比べる、というものです。
うまく、「徐行」の標識どおしのマッチングがとれれば万歳、とれなければションボリという感じであります。
特徴点抽出にORB使用の場合
以下は特徴点を見つけるのにORB(Oriented FAST and Rotated BRIEF)を使った場合の処理コード(HELPファイル通りだけれども)です。
まず画像の準備が以下に。
Sref = imread("image/TrafficSignRef.png"); S0 = imread("image/Joko.png"); Strg = imrotate(S0,45);
つづいて特徴点の抽出からマッチングと結果表示まで。
fref = imdetect_ORB(Sref) ftrg = imdetect_ORB(Strg) descRef = imextract_DescriptorORB(Sref,fref); descTrg = imextract_DescriptorORB(Strg,ftrg); m = immatch_BruteForce(descRef,descTrg,4); [fout1,fout2,mout] = imbestmatches(fref,ftrg,m,10); Smatches = imdrawmatches(Sref,Strg,fref,ftrg,mout); imshow(Smatches);
「上位10傑」のうち、2点は「はみだし追い越し禁止)に騙されているみたいだけれども、8点は期待通りの一致を示してくれているみたい。まあまあ「徐行」標識だという判断は可能?知らんけど。
特徴点抽出にSIFT使用の場合
以下は特徴点を見つけるのに古典的なSIFT(Scale-Invariant Feature Transformation)をつかった場合。
frefSIFT = imdetect_SIFT(Sref) ftrgSIFT = imdetect_SIFT(Strg) descRefSIFT = imextract_DescriptorSIFT(Sref,frefSIFT); descTrgSIFT = imextract_DescriptorSIFT(Strg,ftrgSIFT); mSIFT = immatch_BruteForce(descRefSIFT,descTrgSIFT,4); [fout1SIFT,fout2SIFT,moutSIFT] = imbestmatches(frefSIFT,ftrgSIFT,mSIFT,10); SmatchesSIFT = imdrawmatches(Sref,Strg,frefSIFT,ftrgSIFT,moutSIFT); imshow(SmatchesSIFT);
半分くらい「車両通行止め」の標識に騙されている感じ。半分は徐行だけれども。これだと判断つかんな。
特徴点抽出にBRISK使用の場合
BRISK(Binary Robust Invariant Sclable Keypoints) を使った場合。
frefBRISK = imdetect_BRISK(Sref) ftrgBRISK = imdetect_BRISK(Strg) descRefBRISK = imextract_DescriptorBRISK(Sref,frefBRISK); descTrgBRISK = imextract_DescriptorBRISK(Strg,ftrgBRISK); mBRISK = immatch_BruteForce(descRefBRISK,descTrgBRISK,4); [fout1BRISK,fout2BRISK,moutBRISK] = imbestmatches(frefBRISK,ftrgBRISK,mBRISK,10); SmatchesBRISK = imdrawmatches(Sref,Strg,frefBRISK,ftrgBRISK,moutBRISK); imshow(SmatchesBRISK);
ぜんぜんダメじゃん。BRISKは回転に弱いの?