Cv2.Polylines / Cv2.FillPoly の使い方【OpenCV/C#(OpenCvSharp)】〜多角形を描画・塗りつぶす〜

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

Cv2.Polylines / Cv2.FillPoly の使い方【OpenCV/C#(OpenCvSharp)】〜多角形を描画・塗りつぶす〜

Cv2.Polylines は頂点座標の配列を受け取り、多角形の輪郭線を画像に描画します。Cv2.FillPoly は同じ頂点配列を内部まで塗りつぶします。検出領域のマスク生成・可視化・アノテーションなど、実務で頻繁に使う描画系の基本関数です。

// 輪郭描画
Cv2.Polylines(img, new[] { pts }, isClosed: true, Scalar.Red, thickness: 2);
// 塗りつぶし
Cv2.FillPoly(img, new[] { pts }, Scalar.Green);

動作環境

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

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


基本の使い方

using OpenCvSharp;

// 描画先の黒いキャンバスを用意
using var img = new Mat(400, 600, MatType.CV_8UC3, Scalar.Black);

// 五角形の頂点座標を定義
Point[] pts =
{
    new Point(300, 50),
    new Point(450, 160),
    new Point(390, 330),
    new Point(210, 330),
    new Point(150, 160),
};

// 輪郭だけ描画(赤・太さ 2px・閉じたポリライン)
Cv2.Polylines(img, new[] { pts }, isClosed: true, Scalar.Red, thickness: 2);

// 別キャンバスに塗りつぶし描画
using var filled = new Mat(400, 600, MatType.CV_8UC3, Scalar.Black);
Cv2.FillPoly(filled, new[] { pts }, Scalar.LimeGreen);

// 結果を保存
Cv2.ImWrite("polylines.png", img);
Cv2.ImWrite("fillpoly.png", filled);

Console.WriteLine("polylines.png / fillpoly.png を保存しました");

実行すると polylines.png(赤い五角形の輪郭)と fillpoly.png(緑で塗りつぶされた五角形)の 2 ファイルが生成されます。

コードのポイント

行の概要 補足
new Mat(400, 600, ...) キャンバスは using で必ず解放
new[] { pts } 引数は Point[][] 相当の配列の配列。複数ポリゴンをまとめて渡せる
isClosed: true false にすると最後の頂点と最初の頂点をつなぐ辺が省略される
Scalar.Red BGR 順。new Scalar(0, 0, 255) と等価

引数と戻り値

Cv2.Polylines

引数 型 説明
img Mat 描画先画像(in-place 変更)
pts IEnumerable<IEnumerable<Point>> ポリゴンごとの頂点配列(配列の配列)
isClosed bool true で閉じた多角形、false で折れ線
color Scalar 線の色(BGR)
thickness int 線の太さ(px)。省略時 1
lineType LineTypes LineTypes.Link8(既定)/ LineTypes.AntiAlias 等
shift int 座標のビットシフト数(通常 0)

戻り値: なし(void)

Cv2.FillPoly

引数 型 説明
img Mat 描画先画像(in-place 変更)
pts IEnumerable<IEnumerable<Point>> ポリゴンごとの頂点配列
color Scalar 塗りつぶし色(BGR)
lineType LineTypes 境界線のレンダリング方式
shift int 座標のビットシフト数(通常 0)
offset Point 全頂点に加算するオフセット(省略時 (0,0))

戻り値: なし(void)


実践例

① 複数ポリゴンを一括描画

Cv2.Polylines / Cv2.FillPoly は 複数のポリゴンを配列ごとまとめて渡せるのが便利です。物体検出結果の輪郭を一括で可視化するケースに対応できます。

using OpenCvSharp;

using var img = new Mat(500, 700, MatType.CV_8UC3, Scalar.White);

// 三角形と四角形を同時に定義
Point[][] polygons =
{
    // 三角形
    new[]
    {
        new Point(100, 400),
        new Point(200, 200),
        new Point(300, 400),
    },
    // 平行四辺形
    new[]
    {
        new Point(380, 400),
        new Point(480, 200),
        new Point(620, 200),
        new Point(520, 400),
    },
};

// 輪郭を一括描画(アンチエイリアス付き)
Cv2.Polylines(img, polygons, isClosed: true, Scalar.DarkBlue,
              thickness: 3, lineType: LineTypes.AntiAlias);

Cv2.ImWrite("multi_polylines.png", img);
Console.WriteLine("multi_polylines.png を保存しました");

② FillPoly でマスク画像を生成する

画像の任意領域にマスクを作り、その領域だけ処理を適用するパターンです。ConnectedComponentsWithStats や InRange と組み合わせる実務シナリオで定番の手法です。

using OpenCvSharp;

// 元画像を読み込む(存在するパスに変更してください)
using var src = Cv2.ImRead("input.png");
if (src.Empty()) { Console.WriteLine("画像が読み込めません"); return; }

// マスク(8UC1 黒で初期化)
using var mask = new Mat(src.Size(), MatType.CV_8UC1, Scalar.Black);

// 注目領域を多角形で定義
Point[] roi =
{
    new Point(100, 80),
    new Point(400, 60),
    new Point(450, 280),
    new Point(80, 300),
};

// マスク領域を白で塗りつぶす
Cv2.FillPoly(mask, new[] { roi }, Scalar.White);

// マスクを適用して領域外を黒にする
using var result = new Mat();
src.CopyTo(result, mask);

Cv2.ImWrite("masked.png", result);
Console.WriteLine("masked.png を保存しました");

実行すると masked.png に、指定した多角形内の画像だけが残り、外側が黒になった結果が保存されます。


つまずきポイント

⚠️ 引数が「配列の配列」である点を見落とす

Cv2.Polylines / Cv2.FillPoly の頂点引数は Point[] ではなく Point[][] 相当の「ポリゴンの配列」 です。単一ポリゴンでも new[] { pts } のように一段ラップする必要があります。

// NG: Point[] をそのまま渡す(コンパイルエラー)
Cv2.Polylines(img, pts, true, Scalar.Red, 2);

// OK: 配列の配列でラップする
Cv2.Polylines(img, new[] { pts }, true, Scalar.Red, 2);

⚠️ Mat の Dispose 漏れ

new Mat(...) で生成したキャンバスや中間 Mat はネイティブメモリを保持します。using を付け忘れると GC タイミング次第でメモリリークが発生します。本記事のサンプルのように すべての Mat を using で管理するを徹底してください。

✅ isClosed の挙動を確認する

isClosed: false にすると最後の頂点と最初の頂点をつなぐ辺が描画されません。閉じた多角形を期待しているのに線が繋がらない場合は true になっているか確認しましょう。FillPoly は内部的に常に閉じた輪郭として扱うため、このフラグは持ちません。


関連する関数


まとめ

  • Cv2.Polylines は閉じた・開いた多角形の輪郭線を、Cv2.FillPoly は内部まで塗りつぶして描画する。
  • 頂点引数は必ず「配列の配列」形式で渡す。複数ポリゴンを一括処理できるのが両関数の強み。
  • FillPoly でマスク画像を生成し、任意領域だけに処理を適用するパターンは実務で特に頻出。

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

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

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

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