OpenCV Javaライブラリを使って2枚の画像の特徴点をマッチングする方法
OpenCVのorg.opencv.features2d.Feature2Dクラス(抽象クラス)が提供するdetect()メソッドを使用すると、指定した画像から特徴点(キーポイント)を検出できます。このメソッドには、元画像を表すMatオブジェクトと、検出した特徴点を格納するための空のMatOfKeyPointオブジェクトを渡します。
さらに、org.opencv.features2d.Features2dクラスのdrawMatches()メソッドを使うと、2つの画像の特徴点同士の対応関係(マッチング)を計算し、その結果を描画できます。このメソッドは以下のパラメータを受け取ります。
- src1 − 1つ目の元画像を表すMatクラスのオブジェクト
- keypoints1 − 1つ目の画像の特徴点を表すMatOfKeyPointクラスのオブジェクト
- src2 − 2つ目の元画像を表すMatクラスのオブジェクト
- keypoints2 − 2つ目の画像の特徴点を表すMatOfKeyPointクラスのオブジェクト
- matches1to2 − 1つ目の画像から2つ目の画像へのマッチング結果。keypoints1[i]に対応する点がkeypoints2[matches[i]]に存在することを示します
- dst − 出力画像を表すMatクラスのオブジェクト
以上を踏まえると、2つの画像の特徴点をマッチングさせる基本的な流れは次の3ステップです。
- imread()メソッドで2枚の元画像を読み込む
- detect()メソッドで両画像の特徴点を検出する
- drawMatches()メソッドでマッチングを求めて描画する
サンプルコード
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.features2d.FastFeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
public class MatchingKeypoints {
public static void main(String args[]) throws Exception {
//OpenCVのコアライブラリを読み込む
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
//元画像を読み込む
String file1 ="D:\\Images\\feature1.jpg";
Mat src1 = Imgcodecs.imread(file1);
String file2 ="D:\\Images\\feature2.jpg";
Mat src2 = Imgcodecs.imread(file2);
//出力画像を格納するための空の行列を作成
Mat dst = new Mat();
//FAST特徴点検出器を作成
FastFeatureDetector detector = FastFeatureDetector.create();
//両画像の特徴点を検出する
MatOfKeyPoint keyPoints1 = new MatOfKeyPoint();
detector.detect(src1, keyPoints1);
MatOfKeyPoint keyPoints2 = new MatOfKeyPoint();
detector.detect(src2, keyPoints2);
//マッチング結果を描画する
MatOfDMatch matof1to2 = new MatOfDMatch();
Features2d.drawMatches(src1, keyPoints1, src2, keyPoints2, matof1to2, dst);
HighGui.imshow("Feature Matching", dst);
HighGui.waitKey();
}
}
入力画像
画像1

画像2

出力結果

なお、実際のアプリケーションで正確な対応点を求める場合は、ORBやAKAZEなどで記述子を抽出し、DescriptorMatcherによるマッチング処理を組み合わせるのが一般的です。上記のサンプルは、特徴点検出から描画までの一連の基本フローを確認するためのものです。
-
JavaとOpenCVで2つの画像にビット単位のOR演算(bitwise_or)を行う方法
JavaでOpenCVを利用すれば、org.opencv.core.Coreクラスが提供するbitwise_or()メソッドを使って、2つの画像間でビット単位のOR(論理和)演算を簡単に実行できます。 このメソッドは、演算対象となる2つのソース画像と、結果を格納する出力先として、合計3つのMatオブジェクトを引数に取ります。処理では各要素(ピクセル)ごとにビット単位の論理和が計算され、その結果が出力先のMatオブジェクトに格納されます。OR演算では、対応するビットのどちらか一方でも1であれば結果が1になるため、2つの画像を重ね合わせたような効果が得られます。 サンプルコード 以下のJavaの例
-
JavaとOpenCVライブラリを使って画像を保存(書き出し)する方法
OpenCVライブラリを利用すると、画像フィルタリング、幾何学的変換、色空間の変換、ヒストグラム処理など、さまざまな画像処理操作を行うことができます。本記事では、その中でも基本的な操作である「画像の読み込みと保存(書き出し)」の方法を解説します。画像を書き出す(保存する)方法Imgcodecsクラスのimread()メソッドを使って画像を読み込むと、その内容はMat(Matrix)オブジェクトに格納されます。読み込んだ画像をファイルとして保存するには、imwrite()メソッドを使用します。imwrite()メソッドは、以下の2つの引数を受け取ります。file:保存先のファイルパスを表す文字列