前提・実現したいこと
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)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/23 07:38
2018/04/23 08:16
2018/04/24 03:48