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

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

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

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

1回答

995閲覧

BFMatcherクラスのマッチングのメソッドでunknown exceptionエラーが表示します

oka_99

総合スコア11

OpenCV

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2018/04/19 07:56

編集2018/04/20 01:33

前提・実現したいこと

JAVA/OpenCVを用いて2枚の画像の特徴点マッチングのプログラムを書いています。
2枚の画像の特徴点を抽出するところまでは来たのですが
マッチングクラスのマッチングメソッドで必ずunknown exceptionのエラーが表示します。。
コード的に問題があるところをご指摘いただけたら助かります。

発生している問題・エラーメッセージ

必ずmatch()メソッドを実行するタイミングで以下のエラーが表示されます。

Exception in thread "main" java.lang.Exception: unknown exception at org.opencv.features2d.DescriptorMatcher.match_1(Native Method) at org.opencv.features2d.DescriptorMatcher.match(DescriptorMatcher.java:223) at opencv_test1.ImgConv.main(ImgConv.java:63) [ INFO:0] Initialize OpenCL runtime...

該当のソースコード

package opencv_test1; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfDMatch; import org.opencv.core.MatOfKeyPoint; import org.opencv.features2d.BFMatcher; import org.opencv.features2d.Features2d; import org.opencv.features2d.ORB; import org.opencv.imgcodecs.Imgcodecs; //-------------------------------------------------------------- //画像処理 特徴点の抽出 特徴点同士のマッチング //-------------------------------------------------------------- public class ImgConv{ public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat im_src1; //元画像1(グレイスケール) Mat im_src2; //元画像2(グレイスケール) MatOfKeyPoint my_keypoints1; //特徴点の位置やパラメータを保存する変数 MatOfKeyPoint my_keypoints2; //特徴点の位置やパラメータを保存する変数 Mat my_descriptors1; //特徴量 Mat my_descriptors2; //特徴量 ORB my_orb; //特徴点抽出クラス my_orb = ORB.create(); //1枚目の画像から特徴点を抽出 im_src1 = Imgcodecs.imread("C:\WORK\20180411\img_grayscale\DSC_0021.jpg"); //作業ファイルの読み込み my_keypoints1 = new MatOfKeyPoint(); my_descriptors1 = new Mat(); my_orb.detect(im_src1, my_keypoints1); // 特徴点抽出処理 my_orb.compute(im_src1, my_keypoints1, my_descriptors1); //2枚目の画像から特徴点を抽出 im_src2 = Imgcodecs.imread("C:\WORK\20180411\img_grayscale\DSC_0022.jpg"); //作業ファイルの読み込み my_keypoints2 = new MatOfKeyPoint(); my_descriptors2 = new Mat(); my_orb.detect(im_src2, my_keypoints2); // 特徴点抽出処理 my_orb.compute(im_src2, my_keypoints2, my_descriptors2); //特徴点の対応を調べる BFMatcher matcher = new BFMatcher(NORM_HAMMING,true); //特徴点の対応を調べるクラス MatOfDMatch result_matches = new MatOfDMatch(); //マッチング結果保存用行列     result_matches.create(my_descriptors1.rows(), my_descriptors1.cols(),my_descriptors1.type()); //出力先の型を決める? //特徴点のマッチング matcher.match(my_descriptors1, my_descriptors2, result_matches);<<<<<ここで必ずエラーが発生します** //新規画像を作成し結果をファイルに書き込み     Mat outImg = new Mat(); //結果画像保存用行列 Features2d.drawMatches(my_descriptors1, my_keypoints1, my_descriptors2, my_keypoints2, result_matches, outImg); //結果をデータ化 Imgcodecs.imwrite("C:\WORK\20180411\find_feature_points\result.jpg", outImg); //書き込み //後処理 im_src1.release(); im_src2.release();     outImg.release(); } }

試したこと

1)それぞれの画像から特徴点を抽出できているか→それぞれの画像にデータを書き込むことで正常に動作していることと確認。
→my_descriptors1,my_descriptors2ともどもデータは保存されています。

2)match()メソッドをコメントしてプログラムを実行すると結果の書き込み部分Features2d.drawMatchesを実行し画像が結合して出力しているので画像だけの部分に関してはコード自体は正しい?と思っています。

3)問題は、matcher.match(my_descriptors1, my_descriptors2, result_matches);で必ず例外エラーが発生することです。

Exception in thread "main" java.lang.Exception: unknown exception
at org.opencv.features2d.DescriptorMatcher.match_1(Native Method)
at org.opencv.features2d.DescriptorMatcher.match(DescriptorMatcher.java:223)
at opencv_test1.ImgConv.main(ImgConv.java:63)
[ INFO:0] Initialize OpenCL runtime...

ドキュメントやプログラムサイトをみると基本的な流れは
1)ORBクラスでの特徴点検出
2)ORBクラスでつくった特徴点データはNORM_HAMMING/相互確認はTRUEでマッチャーを作成し、match()メソッドを呼ぶ
→matchメソッドのパラメータのMatOfDMatchにマッチング結果が保存される

ということだと理解しています。

デバッカーで追ってみましたがmatch()メソッドは
public void match(Mat queryDescriptors, Mat trainDescriptors, MatOfDMatch matches)
と定義されていますが、以下パラメータ
Mat queryDescriptors
Mat trainDescriptors
MatOfDMatch matches
とも、デバッカで中身をみるとnativeOBJ変数の値があり、計算処理に渡すメモリの保持はしているみたいです。

2018/04/20追加
opencvのパッケージの中の
\opencv\sources\modules\calib3d\test\test_homography.cpp
に同じ内容をC++で書いたコードがあります。
Step3までが同じ内容ですのでこれを自分の環境で動作するか確認するしかないでしょうか...

TEST(Calib3d_Homography, fromImages)
{
Mat img_1 = imread(cvtest::TS::ptr()->get_data_path() + "cv/optflow/image1.png", 0);
Mat img_2 = imread(cvtest::TS::ptr()->get_data_path() + "cv/optflow/image2.png", 0);

Ptr<ORB> orb = ORB::create(); vector<KeyPoint> keypoints_1, keypoints_2; Mat descriptors_1, descriptors_2; orb->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1, false ); orb->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2, false ); //-- Step 3: Matching descriptor vectors using Brute Force matcher BFMatcher matcher(NORM_HAMMING,false); std::vector< DMatch > matches; matcher.match( descriptors_1, descriptors_2, matches );     <<<<ここで落ちるか確認

++++++++ここから先のコードは関連がないので割愛します

}

補足情報(FW/ツールのバージョンなど)

OpenCV 3.41
JAVA version10
Eclipse Oxygen.2 Release (4.7.2)

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

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

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

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

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

guest

回答1

0

ベストアンサー

Exception in thread "main" java.lang.Exception: unknown exception

BFMatcher

Brute-force matcher constructor (obsolete). Please use BFMatcher.create()

◇適当和訳
ブルートフォースマッチャーコンストラクター(廃止)。 BFMatcher.create()を使用してください

よって原因は以下の行です。

Java

1BFMatcher matcher = new BFMatcher(DescriptorMatcher.BRUTEFORCE_HAMMING, true);

Java

1import org.opencv.features2d.DescriptorMatcher; 2 3DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

もしくは以下のように修正してください。

Java

1BFMatcher matcher = BFMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING, true);

Java

1import org.opencv.core.Core; 2import org.opencv.core.Mat; 3import org.opencv.core.MatOfDMatch; 4import org.opencv.core.MatOfKeyPoint; 5import org.opencv.features2d.BFMatcher; 6import org.opencv.features2d.DescriptorMatcher; 7import org.opencv.features2d.Features2d; 8import org.opencv.features2d.ORB; 9import org.opencv.imgcodecs.Imgcodecs; 10 11public class ImgConv { 12 static { 13 // opencvのライブラリを読み込む 14 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 15 } 16 17 public static void main(String[] args) { 18 final String base_path = "C:\z\"; 19 20 // 元画像1と2を読み込み、Mat配列に格納 21 Mat[] images = { loadImage(base_path + "DSC_0021.jpg"), loadImage(base_path + "DSC_0022.jpg") }; 22 ORB my_orb = ORB.create(); // 特徴点抽出クラス 23 24 MatOfKeyPoint[] keypoints = new MatOfKeyPoint[images.length]; 25 Mat[] descriptors = new Mat[images.length]; 26 for (int i = 0; i < images.length; i++) { 27 keypoints[i] = new MatOfKeyPoint(); 28 descriptors[i] = new Mat(); 29 my_orb.detect(images[i], keypoints[i]); 30 my_orb.compute(images[i], keypoints[i], descriptors[i]); 31 } 32 33 // 特徴点の対応を調べる 34 MatOfDMatch result_matches = match(descriptors); 35 Mat outImg = new Mat(); // 結果画像保存用行列 36 // 引数を変更 37 Features2d.drawMatches(images[0], keypoints[0], images[1], keypoints[1], result_matches, outImg); // 結果をデータ化 38 // Features2d.drawMatches(my_descriptors1, my_keypoints1, my_descriptors2, 39 // my_keypoints2, result_matches, outImg); //結果をデータ化 40 Imgcodecs.imwrite(base_path + "result.jpg", outImg); // 書き込み 41 42 // 後処理 43 release(images); 44 release(new Mat[] { outImg }); 45 } 46 47 public static Mat loadImage(String path) { 48 // Mat src = Imgcodecs.imread(path); 49 // ※グレースケールで読み込むなら以下の行でも。 50 Mat src = Imgcodecs.imread(path, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 51 if (src.empty()) { 52 // ファイルが読み込めなかった時 53 throw new RuntimeException(path); 54 } 55 return src; 56 } 57 58 public static MatOfDMatch match(Mat[] descriptors) { 59 DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 60 // DescriptorMatcher matcher = new 61 // BFMatcher(DescriptorMatcher.BRUTEFORCE_HAMMING, true); // 特徴点の対応を調べるクラス 62 MatOfDMatch result_matches = new MatOfDMatch(); // マッチング結果保存用行列 63 // ※↓の行はC++の公式サンプルには存在しませんが、どこのサンプルに記述されてましたか? 64 // result_matches.create(descriptors[0].rows(), 65 // descriptors[0].cols(),descriptors[0].type()); 66 // 特徴点のマッチング 67 matcher.match(descriptors[0], descriptors[1], result_matches); 68 return result_matches; 69 } 70 71 public static void release(Mat[] images) { 72 for (Mat m : images) { 73 m.release(); 74 } 75 } 76} 77

勝手ながらソースを改造しました。

1,変数は先頭でまとめて宣言せずに適切な値で初期化するように。
2,ファイルが存在しない時にImgcodecs.imreadの戻り値のMatオブジェクトがemptyで無いかをチェックし例外を発生させるように(loadImageメソッド)。
Imgcodecs.imreadは画像が読み取れなかった時に例外を発生せず、後続の処理で例外が発生します。
3,detectcomputeを連続して行うなら、Feature2D#detectAndComputeが使えます。
→上記ソースでは未対応
4,imageskeypointsdescriptorsは配列で管理するように。
5,imwriteの書き出しパスを入力ファイルと同一パスに。
6,matchメソッドとreleaseメソッドを追加

◇参考情報
cv::BFMatcher::BFMatcher

投稿2018/04/20 01:51

編集2018/04/20 09:46
umyu

総合スコア5846

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

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

oka_99

2018/04/23 07:38

umyuさん: どうもご指摘ありがとうございます。 BFMatcherの初期化に問題があるとのご指摘と コードに対してもご指摘どうもありがとうございます。 書き直しているのですが ご指摘どおりcreate()に変更しましたがまだ別途エラーがでているので 画像データ自体も問題があるのか検討しています。 ちゃんと動作確認してから再度コメントさせていただきます。 どうもありがとうございます。
umyu

2018/04/23 08:16

>oka_99さんへ matcher.matchでは質問文のエラーが発生しなくなったと認識してもよいでしょうか? あと考えられる事としては、 1,Lena画像で問題が再現するかどうかを確かめて見た方がよいかと。 2,画像のファイルパスを日本語を含まない形にしても再現するかどうか。 3,OpenCVのライブラリのバージョンを落として、問題が再現するかどうか。 こういう点でしょうか。
oka_99

2018/04/24 03:48

umyuさん: どうもありがとうございます。 クラス/メソッドの変更だけのみを試しましたらば match()でunknown...のエラーは表示しなくなりましたが別のエラーが表示されています。 umyuさんの書いていただいた全体のコードで試したところ こちらでは問題が出ませんでした。 やはり自分のコードに問題/見落としがあるのだと思います。 もうちょっとコードを分析をします。 自分のレスポンスが遅れがちななか、どうもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問