OpenCVとJavaで画像をアフィン変換する方法:warpAffine()の使い方と実装例
OpenCVのImgprocクラスが提供するwarpAffine()メソッドを使用すると、指定した画像に対してアフィン変換(Affine Transformation)を適用できます。このメソッドは、以下の引数を受け取ります。
- ソース画像・出力先画像・変換行列を表す3つのMatオブジェクト
- 出力画像のサイズを表す整数値(Sizeオブジェクト)
画像を移動(トランスレート)させたい場合は、あらかじめ変換行列を作成しておき、その行列を他のパラメータと一緒にこのメソッドへ渡します。
サンプルコード
以下は、OpenCVのJavaラッパーとJavaFXを組み合わせて、画像にアフィン変換を適用して表示する完全な例です。
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class TranslatingAnImage extends Application {
public void start(Stage stage) throws IOException {
// OpenCVのコアライブラリを読み込む
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
// 画像データを読み込む
String file ="D:\\Images\\elephant.jpg";
Mat src = Imgcodecs.imread(file);
// 出力先のMatオブジェクトを作成する
Mat dst = new Mat(src.rows(), src.cols(), src.type());
Point p1 = new Point( 0,0 );
Point p2 = new Point( src.cols() - 1, 0 );
Point p3 = new Point( 0, src.rows() - 1 );
Point p4 = new Point( src.cols()*0.0, src.rows()*0.33 );
Point p5 = new Point( src.cols()*0.85, src.rows()*0.25 );
Point p6 = new Point( src.cols()*0.15, src.rows()*0.7 );
MatOfPoint2f ma1 = new MatOfPoint2f(p1,p2,p3);
MatOfPoint2f ma2 = new MatOfPoint2f(p4,p5,p6);
// 変換行列を作成する
Mat tranformMatrix = Imgproc.getAffineTransform(ma1,ma2);
// Sizeクラスのオブジェクトを作成する
Size size = new Size(src.cols(), src.cols());
// アフィン変換を適用する
Imgproc.warpAffine(src, dst, tranformMatrix, size);
// 行列をJavaFXのWritableImageに変換する
Image img = HighGui.toBufferedImage(dst);
WritableImage writableImage= SwingFXUtils.toFXImage((BufferedImage) img, null);
// ImageViewを設定する
ImageView imageView = new ImageView(writableImage);
imageView.setX(10);
imageView.setY(10);
imageView.setFitWidth(575);
imageView.setPreserveRatio(true);
// Sceneオブジェクトを設定する
Group root = new Group(imageView);
Scene scene = new Scene(root, 595, 400);
stage.setTitle("Image Translation example");
stage.setScene(scene);
stage.show();
}
public static void main(String args[]) {
launch(args);
}
}入力画像
このプログラムでは、以下の画像を入力として使用します。

実行結果
上記のプログラムを実行すると、次のような出力が得られます。元の画像が変換行列に基づいて歪められ、新しい位置へ移動していることが確認できます。

処理のポイント
- getAffineTransform():変換前の3点と変換後の3点を対応付けることで、アフィン変換行列を自動的に算出します。
- warpAffine():算出した変換行列をもとに、実際のピクセル変換を行います。
- HighGui.toBufferedImage():OpenCVのMat形式をJavaのBufferedImageへ変換し、JavaFX上で表示できるようにします。
-
JavaとOpenCVライブラリを使って画像内の顔を検出する方法
JavaでOpenCVを使用して画像から顔を検出するには、CascadeClassifierクラスを利用します。このクラスは、分類器ファイル(カスケードファイル)を読み込み、画像内から目的のオブジェクト(ここでは顔)を検出する役割を担います。 CascadeClassifierクラスとは CascadeClassifierは、OpenCVが提供する物体検出用のクラスです。事前に学習済みのカスケード分類器(XMLファイル)を読み込むことで、顔や人など特定のパターンを画像から認識できます。 detectMultiScale()メソッドについて このクラスが持つdetectMultiScale(
-
JavaとOpenCVライブラリを使って画像を保存(書き出し)する方法
OpenCVライブラリを利用すると、画像フィルタリング、幾何学的変換、色空間の変換、ヒストグラム処理など、さまざまな画像処理操作を行うことができます。本記事では、その中でも基本的な操作である「画像の読み込みと保存(書き出し)」の方法を解説します。画像を書き出す(保存する)方法Imgcodecsクラスのimread()メソッドを使って画像を読み込むと、その内容はMat(Matrix)オブジェクトに格納されます。読み込んだ画像をファイルとして保存するには、imwrite()メソッドを使用します。imwrite()メソッドは、以下の2つの引数を受け取ります。file:保存先のファイルパスを表す文字列