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.FitEllipse— 輪郭点群に最小二乗楕円をフィッティングしRotatedRectを返す。本記事の実践例①で使用Cv2.Circle— 真円を描画。楕円の特殊ケースとして覚えておくCv2.Rectangle— 矩形描画。thickness: -1の塗りつぶし挙動は共通- Cv2.BoundingRect / Cv2.MinAreaRect の使い方【OpenCV/C#(OpenCvSharp)】〜外接矩形を求める〜 —
RotatedRectを返すMinAreaRectはFitEllipseと同じ型で扱いやすい - Cv2.ApproxPolyDP の使い方【OpenCV/C#(OpenCvSharp)】〜輪郭を多角形近似する〜 — 輪郭を間引いてから FitEllipse にかけるフローで使う
- Cv2.ContourArea / Cv2.ArcLength の使い方【OpenCV/C#(OpenCvSharp)】〜輪郭の面積・周長を求める〜 — 輪郭の絞り込みに面積・周長を使う場合に参照
まとめ
Cv2.Ellipse は中心・半軸長・傾き・弧の範囲を指定するだけで楕円・円弧・扇形弧を描画できます。FitEllipse の戻り値(RotatedRect)を直接渡すオーバーロードが用意されており、輪郭フィッティング結果の可視化がそのまま書けます。axes が半径指定である点と FitEllipse 使用時の5点チェックを忘れなければ、実務での混乱はほぼ防げます。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。
→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

