OpenCV Javaで画像内のオブジェクトに楕円をフィットさせる方法
OpenCVでは、org.opencv.imgproc.Imgprocクラスが提供するfitEllipse()メソッドを使用することで、図形に楕円をフィットさせることができます。このメソッドはMatOfPoint2f型のオブジェクトを受け取り、与えられた点群に最も適合する楕円を最小二乗法によって計算し、その結果をRotatedRectオブジェクトとして返します。
この機能を利用すると、画像内の候補となるオブジェクト(形状)の周囲に自動的に楕円を描画できます。具体的な手順は以下の通りです。
imread()メソッドを使って画像を読み込みます。
cvtColor()メソッドを使って画像をグレースケールに変換します。
threshold()メソッドを使ってグレー画像を二値化します。
findContours()メソッドを使って画像内の輪郭を検出します。
各輪郭をMatOfPoint2fとしてfitEllipse()メソッドに渡し、対応するRotatedRectオブジェクトを取得します。
最後に、ellipse()メソッドを使って検出した形状の周囲に楕円を描画します。
注意: 楕円を正しくフィットさせるためには、対象のオブジェクトが少なくとも5つの点を含んでいる必要があります。点数が5未満の輪郭に対してfitEllipse()を呼び出すとエラーになるため、事前に点数をチェックしておきましょう。
サンプルコード
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class FitEllipseExample {
public static void main(String args[]) throws Exception {
//OpenCVのコアライブラリを読み込む
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//画像ファイルを読み込む
String file = "D:\\Images\\javafx_graphical.jpg";
Mat src = Imgcodecs.imread(file);
//ソース画像をグレースケールに変換し、さらに二値化する
Mat gray = new Mat(src.rows(), src.cols(), src.type());
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
Mat binary = new Mat(src.rows(), src.cols(), src.type(), new Scalar(0));
Imgproc.threshold(gray, binary, 100, 255, Imgproc.THRESH_BINARY_INV);
//輪郭を検出する
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(binary, contours, hierarchy,
Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
//各輪郭に対して楕円をフィットさせる
RotatedRect[] rec = new RotatedRect[contours.size()];
for (int i = 0; i < contours.size(); i++) {
rec[i] = new RotatedRect();
if (contours.get(i).rows() > 5) {
rec[i] = Imgproc.fitEllipse(
new MatOfPoint2f(contours.get(i).toArray()));
}
Scalar color_elli = new Scalar(190, 0, 0);
Imgproc.ellipse(src, rec[i], color_elli, 5);
}
//結果を表示する
HighGui.imshow("Contours operation", src);
HighGui.waitKey();
}
}
入力画像

出力結果

このように、二値化と輪郭検出を組み合わせて得られた各輪郭にfitEllipse()を適用することで、画像内の複数のオブジェクトを一度に楕円で囲むことができます。物体検出や形状解析の前処理として非常に有用なテクニックなので、ぜひ活用してみてください。
-
JavaのOpenCVライブラリでカラー画像をグレースケールに変換する方法
カラー画像をグレースケールに変換する基本OpenCVのImgprocクラスが提供するcvtColor()メソッドを使うと、画像の色空間を別の色空間へ変換できます。このメソッドは以下の3つのパラメータを受け取ります。src – 変換元の画像を表すMatオブジェクト(ソース)dst – 変換結果を格納するMatオブジェクト(出力先)code – 変換後の色空間を指定する整数値(カラーコード)カラー画像をグレースケールに変換する場合は、第3パラメータにImgproc.COLOR_RGB2GRAYを指定します。このコードはRGB形式の画像をグレースケール(白黒の濃淡表現)へ変換することを意味しています
-
JavaとOpenCVライブラリを使って画像を保存(書き出し)する方法
OpenCVライブラリを利用すると、画像フィルタリング、幾何学的変換、色空間の変換、ヒストグラム処理など、さまざまな画像処理操作を行うことができます。本記事では、その中でも基本的な操作である「画像の読み込みと保存(書き出し)」の方法を解説します。画像を書き出す(保存する)方法Imgcodecsクラスのimread()メソッドを使って画像を読み込むと、その内容はMat(Matrix)オブジェクトに格納されます。読み込んだ画像をファイルとして保存するには、imwrite()メソッドを使用します。imwrite()メソッドは、以下の2つの引数を受け取ります。file:保存先のファイルパスを表す文字列