Cv2.Ellipse の使い方【OpenCV/C#(OpenCvSharp)】〜楕円を描画する〜

OpenCV for C#
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイド / C#(OpenCvSharp)セットアップ

Cv2.Ellipse の使い方【OpenCV/C#(OpenCvSharp)】〜楕円を描画する〜

Cv2.Ellipse は、指定した中心・軸長・角度で楕円(または楕円弧)を Mat 上に描画する関数です。円・斜め楕円・扇形弧まで1つの関数でカバーできます。最小の呼び出しは次のとおりです。

Cv2.Ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness);

動作環境

  • OpenCvSharp4(OpenCV 4.x 系)
  • NuGet: OpenCvSharp4 / OpenCvSharp4.runtime.win(Windows 実行時)
  • .NET 8 コンソールアプリ想定

環境構築がまだの方は環境構築ガイドを先にどうぞ。


基本の使い方

using OpenCvSharp;

// 黒背景の画像を作成
using var img = new Mat(400, 600, MatType.CV_8UC3, Scalar.Black);

// 基本の楕円(水平)
Cv2.Ellipse(
    img,
    center: new Point(150, 200),   // 中心座標
    axes: new Size(120, 70),       // 長軸・短軸の半径
    angle: 0,                      // 楕円自体の傾き(度)
    startAngle: 0,                 // 描画開始角度(度)
    endAngle: 360,                 // 描画終了角度(度)
    color: Scalar.Lime,            // 描画色(BGR)
    thickness: 2                   // 線幅(-1 で塗りつぶし)
);

// 45度傾けた楕円
Cv2.Ellipse(
    img,
    center: new Point(400, 200),
    axes: new Size(120, 60),
    angle: 45,                     // 45度傾ける
    startAngle: 0,
    endAngle: 360,
    color: Scalar.Orange,
    thickness: 2
);

// 下半分だけ描画した楕円弧
Cv2.Ellipse(
    img,
    center: new Point(270, 320),
    axes: new Size(100, 50),
    angle: 0,
    startAngle: 0,                 // 0〜180度 = 下半分
    endAngle: 180,
    color: Scalar.Cyan,
    thickness: 3
);

Cv2.ImWrite("ellipse_basic.png", img);
Console.WriteLine("保存完了: ellipse_basic.png");

実行すると ellipse_basic.png が生成されます。黒背景に緑の水平楕円・オレンジの斜め楕円・シアンの半弧が描かれた画像が確認できます。

コード解説

行 ポイント
new Mat(400, 600, ...) 高さ × 幅の順。BGR 3チャネルで作成
axes: new Size(120, 70) 長軸半径・短軸半径(直径ではない)を指定
angle: 45 楕円全体を時計回りに45度回転させる
startAngle / endAngle 0〜360 で全周、0〜180 で下半弧など部分弧を指定可
thickness: -1 負値を渡すと内部を塗りつぶす
Cv2.ImWrite 描画結果をファイルに保存

引数と戻り値

Cv2.Ellipse には主に2つのオーバーロードがあります。

オーバーロード①(中心+軸長指定)

引数 型 説明
img Mat 描画先の画像(変更される)
center Point 楕円の中心座標
axes Size 長軸・短軸それぞれの半径
angle double 楕円の傾き(度・時計回り)
startAngle double 弧の開始角度(度)
endAngle double 弧の終了角度(度)
color Scalar 描画色(BGR)
thickness int 線幅(-1 で塗りつぶし)省略時 1
lineType LineTypes 線の種類(LineTypes.Link8 など)省略時 Link8
shift int 座標のビットシフト量。省略時 0

戻り値: なし(void)

オーバーロード②(RotatedRect 指定)

Cv2.Ellipse(Mat img, RotatedRect box, Scalar color, int thickness = 1, LineTypes lineType = LineTypes.Link8);

Cv2.FitEllipse の戻り値(RotatedRect)をそのまま渡せるため、輪郭フィッティング結果の可視化に便利です。


実践例

例1: FitEllipse の結果を重ねて描画する

輪郭検出で取得したコンターに楕円をフィッティングし、結果を元画像上に描画する典型パターンです。

using OpenCvSharp;

// サンプル:白背景に傾いた楕円を描いてから輪郭を検出→再フィッティング
using var src = new Mat(400, 400, MatType.CV_8UC3, Scalar.White);
Cv2.Ellipse(src, new Point(200, 200), new Size(130, 70), 30, 0, 360, Scalar.Black, -1);

using var gray = new Mat();
using var binary = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
Cv2.Threshold(gray, binary, 128, 255, ThresholdTypes.BinaryInv);

Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(binary, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

using var result = src.Clone();
if (contours.Length > 0 && contours[0].Length >= 5)
{
    // FitEllipse は RotatedRect を返す
    RotatedRect ellipseRect = Cv2.FitEllipse(contours[0]);

    // RotatedRect をそのまま Ellipse に渡す
    Cv2.Ellipse(result, ellipseRect, Scalar.Red, 2);
    Console.WriteLine($"中心: {ellipseRect.Center}, 軸: {ellipseRect.Size}, 角度: {ellipseRect.Angle:F1}°");
}

Cv2.ImWrite("ellipse_fit.png", result);
Console.WriteLine("保存完了: ellipse_fit.png");

RotatedRect をそのまま Cv2.Ellipse に渡せる点が C# らしい書き方です。Cv2.FitEllipse と組み合わせると、輪郭の形状分析に即使えます。


例2: 塗りつぶし楕円でアノテーション画像を生成する

検出物体の領域を楕円マスクで可視化するケースです。

using OpenCvSharp;

using var img = new Mat(300, 500, MatType.CV_8UC3, Scalar.FromRgb(40, 40, 40));

// 複数の塗りつぶし楕円をアノテーションとして描画
var items = new (Point center, Size axes, double angle, Scalar color)[]
{
    (new Point(120, 150), new Size(90, 50),  0,  Scalar.FromRgb(255, 80,  80)),
    (new Point(300, 150), new Size(70, 110), 20, Scalar.FromRgb(80,  200, 80)),
    (new Point(420, 150), new Size(55, 55),  0,  Scalar.FromRgb(80,  80,  255)),
};

foreach (var (center, axes, angle, color) in items)
{
    // thickness = -1 で塗りつぶし
    Cv2.Ellipse(img, center, axes, angle, 0, 360, color, thickness: -1);
    // 輪郭線を白で重ねる
    Cv2.Ellipse(img, center, axes, angle, 0, 360, Scalar.White, thickness: 1);
}

Cv2.ImWrite("ellipse_annotation.png", img);
Console.WriteLine("保存完了: ellipse_annotation.png");

つまずきポイント

⚠️ axes は半径・直径ではない

axes: new Size(120, 70) の値は「半径」です。直径を渡すと想定の2倍の大きさになります。cv::ellipse の公式ドキュメントも axes half-length(半軸長)と明記しているため注意してください。

⚠️ angle の回転方向と startAngle/endAngle の基準

angle(楕円の傾き)は時計回りです。startAngle/endAngle の0度は画像座標系の「右方向(X軸正方向)」を基準とし、こちらも時計回りに増加します。数学的な反時計回りとは逆なので、弧の範囲を指定するときに向きが想定と逆になりがちです。

⚠️ FitEllipse を使う場合は点数チェックが必須

Cv2.FitEllipse は輪郭点が 5点以上ないと例外を投げます。contours[i].Length >= 5 を必ず確認してから呼び出してください。Cv2.ApproxPolyDP で輪郭を近似した後に点数が減って5点を割るケースは実務でよく起こります。


関連する関数


まとめ

Cv2.Ellipse は中心・半軸長・傾き・弧の範囲を指定するだけで楕円・円弧・扇形弧を描画できます。FitEllipse の戻り値(RotatedRect)を直接渡すオーバーロードが用意されており、輪郭フィッティング結果の可視化がそのまま書けます。axes が半径指定である点と FitEllipse 使用時の5点チェックを忘れなければ、実務での混乱はほぼ防げます。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。

→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました