Java
 Computer >> コンピューター >  >> プログラミング >> Java

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);
   }
}

入力画像

このプログラムでは、以下の画像を入力として使用します。

OpenCVとJavaで画像をアフィン変換する方法:warpAffine()の使い方と実装例

実行結果

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

OpenCVとJavaで画像をアフィン変換する方法:warpAffine()の使い方と実装例

処理のポイント

  • getAffineTransform():変換前の3点と変換後の3点を対応付けることで、アフィン変換行列を自動的に算出します。
  • warpAffine():算出した変換行列をもとに、実際のピクセル変換を行います。
  • HighGui.toBufferedImage():OpenCVのMat形式をJavaのBufferedImageへ変換し、JavaFX上で表示できるようにします。
  1. JavaとOpenCVライブラリを使って画像内の顔を検出する方法

    JavaでOpenCVを使用して画像から顔を検出するには、CascadeClassifierクラスを利用します。このクラスは、分類器ファイル(カスケードファイル)を読み込み、画像内から目的のオブジェクト(ここでは顔)を検出する役割を担います。 CascadeClassifierクラスとは CascadeClassifierは、OpenCVが提供する物体検出用のクラスです。事前に学習済みのカスケード分類器(XMLファイル)を読み込むことで、顔や人など特定のパターンを画像から認識できます。 detectMultiScale()メソッドについて このクラスが持つdetectMultiScale(

  2. JavaとOpenCVライブラリを使って画像を保存(書き出し)する方法

    OpenCVライブラリを利用すると、画像フィルタリング、幾何学的変換、色空間の変換、ヒストグラム処理など、さまざまな画像処理操作を行うことができます。本記事では、その中でも基本的な操作である「画像の読み込みと保存(書き出し)」の方法を解説します。画像を書き出す(保存する)方法Imgcodecsクラスのimread()メソッドを使って画像を読み込むと、その内容はMat(Matrix)オブジェクトに格納されます。読み込んだ画像をファイルとして保存するには、imwrite()メソッドを使用します。imwrite()メソッドは、以下の2つの引数を受け取ります。file:保存先のファイルパスを表す文字列