Cv2.Laplacian の使い方【OpenCV/C#(OpenCvSharp)】〜ラプラシアンフィルタでエッジを検出する〜

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

Cv2.Laplacian の使い方【OpenCV/C#(OpenCvSharp)】〜ラプラシアンフィルタでエッジを検出する〜

Cv2.Laplacian は画像の二次微分(ラプラシアン)を計算し、エッジを検出する関数です。一次微分ベースの Sobel と異なり、すべての方向のエッジを一度に取り出せます。最小限の呼び出しは次のとおりです。

Cv2.Laplacian(src, dst, MatType.CV_64F);

動作環境

項目 内容
OpenCV 4.x 系(OpenCvSharp4)
NuGet OpenCvSharp4 + OpenCvSharp4.runtime.win(Windows 実行時)
ターゲット .NET 8 コンソールアプリ

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


基本の使い方

using OpenCvSharp;

// グレースケールで読み込む
using var src = Cv2.ImRead("input.jpg", ImreadModes.Grayscale);
if (src.Empty()) throw new Exception("画像を読み込めませんでした");

// ノイズ除去(ラプラシアンはノイズに敏感なため前処理推奨)
using var blurred = new Mat();
Cv2.GaussianBlur(src, blurred, new Size(3, 3), 0);

// ラプラシアンフィルタ適用(CV_64F で計算して負値を保持)
using var lap64 = new Mat();
Cv2.Laplacian(blurred, lap64, MatType.CV_64F, ksize: 3);

// 絶対値を取って 8bit に変換
using var dst = new Mat();
Cv2.ConvertScaleAbs(lap64, dst);

Cv2.ImWrite("output.jpg", dst);
Console.WriteLine("output.jpg を保存しました");

実行すると output.jpg にエッジが白く浮かび上がった画像が保存されます。

コードの解説

行 説明
Cv2.ImRead(..., Grayscale) ラプラシアンはグレースケール画像に対して適用するのが基本
Cv2.GaussianBlur 微分演算前のノイズ低減。省略するとノイズがエッジとして検出される
Cv2.Laplacian(..., MatType.CV_64F) 出力を 64bit 浮動小数点にして負値(暗→明の変化)を捨てない
Cv2.ConvertScaleAbs 絶対値を取りつつ 8bit に変換。Mat.ConvertTo だけでは負値がクリップされる

引数と戻り値

Cv2.Laplacian(Mat src, Mat dst, MatType ddepth,
              int ksize = 1, double scale = 1, double delta = 0,
              BorderTypes borderType = BorderTypes.Reflect101);
引数 型 説明
src Mat 入力画像(シングルチャンネル推奨)
dst Mat 出力画像(src と同サイズ)
ddepth MatType 出力の深度。CV_64F または CV_32F を推奨
ksize int ラプラシアンカーネルのサイズ(1 または 奇数。デフォルト: 1)
scale double 計算結果にかけるスケール係数(デフォルト: 1)
delta double 結果に加算するオフセット(デフォルト: 0)
borderType BorderTypes 境界処理の方法(デフォルト: Reflect101)

戻り値: なし(結果は dst に書き込まれる)

ksize の選び方

ksize = 1 のとき、内部では次の 3×3 カーネルが使われます。

 0  1  0
 1 -4  1
 0  1  0

ksize = 3 以上にすると Sobel ベースの計算に切り替わり、より平滑化された結果が得られます。細いエッジを拾いたい場合は ksize = 1、ノイズを抑えたい場合は ksize = 3 が出発点です。


実践例

1. カラー画像に適用してエッジカラーマップを生成する

using OpenCvSharp;

using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像を読み込めませんでした");

// グレースケールに変換してラプラシアンを計算
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

using var blurred = new Mat();
Cv2.GaussianBlur(gray, blurred, new Size(3, 3), 0);

using var lap64 = new Mat();
Cv2.Laplacian(blurred, lap64, MatType.CV_64F, ksize: 3);

using var lapAbs = new Mat();
Cv2.ConvertScaleAbs(lap64, lapAbs);

// エッジ画像にカラーマップを適用して可視化
using var colored = new Mat();
Cv2.ApplyColorMap(lapAbs, colored, ColormapTypes.Jet);

Cv2.ImWrite("edge_colormap.jpg", colored);
Console.WriteLine("edge_colormap.jpg を保存しました");

エッジの強弱を色で確認したい場合に便利です。強いエッジが赤~黄、弱いエッジが青で表示されます。


2. ラプラシアンでシャープネス(ボケ検出)を定量評価する

using OpenCvSharp;

// シャープネス評価したい画像を読み込む
using var src = Cv2.ImRead("target.jpg", ImreadModes.Grayscale);
if (src.Empty()) throw new Exception("画像を読み込めませんでした");

using var lap = new Mat();
Cv2.Laplacian(src, lap, MatType.CV_64F);

// 分散を求める(値が大きいほどエッジが多い=シャープ)
Cv2.MeanStdDev(lap, out Scalar mean, out Scalar stddev);
double variance = stddev.Val0 * stddev.Val0;

Console.WriteLine($"ラプラシアン分散: {variance:F2}");
Console.WriteLine(variance < 100 ? "⚠️ ブレ・ボケの可能性あり" : "✅ 十分なシャープネス");

ラプラシアン分散はカメラのオートフォーカス評価や、撮影画像の品質フィルタリングでよく使われる手法です(閾値は対象画像に応じて調整してください)。


つまずきポイント

⚠️ ddepth を CV_8U にすると負値がクリップされる

// NG: 負の微分値(暗→明の方向)が 0 にクリップされてエッジが欠ける
Cv2.Laplacian(src, dst, MatType.CV_8U);

ラプラシアンの出力には正負両方の値が含まれます。CV_8U で出力すると負値がすべて 0 になり、エッジが半分しか検出されません。必ず CV_64F か CV_32F で受けてから Cv2.ConvertScaleAbs で変換してください。

⚠️ ノイズ除去なしで適用するとノイズがエッジとして大量検出される

ラプラシアンは二次微分なので、一次微分の Sobel よりもノイズの影響を受けやすいです。実務では Cv2.GaussianBlur でのスムージングをほぼ必須と考えてください。ノイズが多い環境では Cv2.BilateralFilter でエッジを保ちながら平滑化する選択肢もあります。

⚠️ Mat の Dispose 漏れに注意

中間 Mat(blurred、lap64 など)を複数作る処理ではネイティブメモリリークが起きやすいです。各 Mat を using var で宣言し、確実に解放する習慣をつけてください。


関連する関数


まとめ

Cv2.Laplacian は全方向のエッジを一度に検出できる二次微分フィルタです。出力は必ず CV_64F で受けて ConvertScaleAbs で変換し、事前に GaussianBlur でノイズ除去しておくのが実務の基本パターンです。シャープネス評価など定量用途にも活用できます。

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

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

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

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