質問: keypoints; compute_0(nativeObj, image.nativeObj, keypoints_mat.nativeObj, descriptors.nativeObj);<<<<<ここで例外処理が起きています。 return; } ### 補足情報(FW/ツールのバージョンなど) 環境 Oxygen.2 Release (4.7.2) JavaSE*1.8 同じ環境で、OpenCVのライブラリの”画像に描画を実行する”メソッドは 正常に動作していますので、OpenCVのパスの設定が原因ではないと思っています。..
回答: NPEが発生したところまで突き止めておられますが、もう一歩踏み込んでNPEの原因を見ると原因にたどり着けただろうと思います。 ### NPEの原因についてもう一歩踏み込んでみる 質問文にある通り実際に発生しているのはcomputeメソッドの内部にある以下の行ですが、 `compute_0(nativeObj, image.nativeObj, keypoints_mat.nativeObj, descriptors.nativeObj);` 第一引数ではNPEは起き得ません。これはAlgorithmクラスのフィールドですがその値がなんであろうとcompute_0メソッドにそのままわたるだけです。 よってNPEが起きる可能性があるのは`image`, `keypoints_mat`, `descriptors`のいずれかがnullの場合であることはこの行から明らかです。 さて、**IDEを使ってデバッグすると便利な点はbreak pointを設定したりstep inしたりすることで、「その時点の変数の値」が確認できる**ことです。それを最大限活用して**デバッグしましょう**。**computeを呼び出す行にbreak pointを設定してそこまで到達したらstep inしてみてください**。 そうすれば`descriptors`がnullであることがわかると思います。それが分かったら今度はなぜそれがnullなのか原因をさかのぼりましょう。`descriptors`はcomputeメソッドの第三引数に渡したものです。mainメソッドに戻ってそれが何かを確認すると第三引数は`my_descriptors`であり、それは変数宣言の際にnullを設定した以降何も設定してないことがわかります。 こうやって「どの値がまずかったのか」をさかのぼっていってください。 ここまでで、my_descriptorsがnullのままではいけないらしいことがわかります。 ### 対処 自分はOpenCVに暗いので対策としてどうするのが一番適切かはわかりません。想像できるのは「JavaラッパーではJavaオブジェクトにC++のオブジェクトのハンドル(アドレス)が記録されていてJavaからC++を呼び出す際にそのハンドルを介して情報をやりとりしているのだろう」という点だけです。 OpenCVのJavaDocを見てみましたが案の定computeメソッドの説明は空欄です。C++ライブラリーのラッパーだとこういうことはよくありますね。C++のAPIリファレンスもチラミしてみましたがその程度では当然ながらJava側でどう書くべきかはすぐに分かりません。本来ならばJavaラッパーの(必要に応じてC++ライブラリーのAPI仕様も)ドキュメントを一通り見て作法などを知る必要があるのだろうと思いますが、自分はそこまで詳しく見てないです。 自分の場合「とりあえずMatインスタンスを生成してそれ渡してみたら結果をそこに格納してくれるのではあるまいか」という非常に大雑把な推測をたてやってみました。 具体的にはcomputeを呼び出す直前で `my_descriptors = new Mat();` としてみました。 本件の場合はたまたまそれで期待動作してくれるみたいでした。対策方法を考える例としてはいささかよくない例ですがたまたまうまくいったということでご容赦を。