Cv2.Add は2枚の画像をピクセル単位で加算し、Cv2.AddWeighted は重み付きでブレンド合成します。透過合成・オーバーレイ表示など実務でよく使う2つの関数を、動くコードで一気に押さえましょう。
// 2枚を均等にブレンド
Cv2.AddWeighted(src1, 0.5, src2, 0.5, 0.0, dst);
動作環境
- OpenCV 4.x(OpenCvSharp4)
- .NET 8 コンソールアプリ
- NuGet:
OpenCvSharp4+OpenCvSharp4.runtime.win(Windows 実行時)
環境構築がまだの方は環境構築ガイドを先にどうぞ。
基本の使い方
Cv2.Add — 飽和加算
using OpenCvSharp;
// 2枚の画像を加算合成する(飽和加算)
using var src1 = Cv2.ImRead("photo1.jpg");
using var src2 = Cv2.ImRead("photo2.jpg");
using var dst = new Mat();
// サイズ・チャンネル数が一致している必要がある
Cv2.Add(src1, src2, dst);
Cv2.ImWrite("add_result.jpg", dst);
Console.WriteLine("加算完了: add_result.jpg");
Cv2.Add はピクセル値を単純に足し合わせ、255 を超えた値は 255 にクリップ(飽和演算)します。露出オーバーで白飛びするような効果になります。
Cv2.AddWeighted — 重み付きブレンド
using OpenCvSharp;
// 2枚の画像を重み付きでブレンドする
using var src1 = Cv2.ImRead("photo1.jpg");
using var src2 = Cv2.ImRead("photo2.jpg");
using var dst = new Mat();
// dst = src1 × alpha + src2 × beta + gamma
double alpha = 0.6;
double beta = 0.4;
double gamma = 0.0; // 輝度オフセット
Cv2.AddWeighted(src1, alpha, src2, beta, gamma, dst);
Cv2.ImWrite("blend_result.jpg", dst);
Console.WriteLine("ブレンド完了: blend_result.jpg");
計算式は dst = src1 × alpha + src2 × beta + gamma です。alpha + beta = 1.0 にすれば輝度を保ったまま自然なブレンドになります。gamma で全体の明るさをオフセットできます。
実行すると blend_result.jpg が生成されます。alpha=0.6 なので photo1 が 60%、photo2 が 40% の比率で合成された画像になります。
引数と戻り値
Cv2.Add
| 引数 | 型 | 説明 |
|---|---|---|
| src1 | InputArray | 入力画像1 |
| src2 | InputArray | 入力画像2(src1 と同サイズ・同チャンネル) |
| dst | OutputArray | 出力画像 |
| mask | InputArray | 処理対象マスク(省略可、null で全体) |
| dtype | int | 出力の深度(省略可、-1 で src1 に合わせる) |
戻り値: なし(dst に書き込まれる)
Cv2.AddWeighted
| 引数 | 型 | 説明 |
|---|---|---|
| src1 | InputArray | 入力画像1 |
| alpha | double | src1 の重み |
| src2 | InputArray | 入力画像2(src1 と同サイズ・同チャンネル) |
| beta | double | src2 の重み |
| gamma | double | 結果に加算するスカラーオフセット |
| dst | OutputArray | 出力画像 |
| dtype | int | 出力の深度(省略可、-1 で src1 に合わせる) |
戻り値: なし(dst に書き込まれる)
実践例
実践例1: フェードイン・フェードアウトアニメーション
動画のトランジションや UI 演出で、2枚の画像を徐々に切り替えるパターンです。
using OpenCvSharp;
// アルファ値を 0.0 → 1.0 に変化させてフェード画像を連続生成
using var src1 = Cv2.ImRead("scene_a.jpg");
using var src2 = Cv2.ImRead("scene_b.jpg");
for (int i = 0; i <= 10; i++)
{
double alpha = i / 10.0; // 0.0 〜 1.0
double beta = 1.0 - alpha; // 1.0 〜 0.0
using var frame = new Mat();
Cv2.AddWeighted(src1, alpha, src2, beta, 0.0, frame);
Cv2.ImWrite($"fade_{i:D2}.jpg", frame);
}
Console.WriteLine("フェード画像 11 枚を生成しました。");
alpha を 0.0→1.0 に変化させると scene_a から scene_b へのフェードアウト/インが実現できます。ループ内で Mat を using で確実に解放しているのがポイントです。
実践例2: マスクを使った部分合成
特定領域だけを合成したい場合は Cv2.Add の mask 引数を活用します。
using OpenCvSharp;
using var background = Cv2.ImRead("background.jpg");
using var overlay = Cv2.ImRead("overlay.jpg"); // 同サイズ
// 合成したい領域のマスクを作成(白=合成対象)
using var mask = new Mat(background.Size(), MatType.CV_8UC1, Scalar.Black);
Cv2.Rectangle(mask, new Rect(100, 100, 300, 200), Scalar.White, -1);
using var dst = background.Clone();
// マスク領域だけ overlay を加算
Cv2.Add(overlay, dst, dst, mask);
Cv2.ImWrite("masked_add.jpg", dst);
Console.WriteLine("マスク合成完了: masked_add.jpg");
mask を渡すと白い領域だけ演算が適用され、黒い領域は元の dst の値が保たれます。色抽出でマスクを作る場合は Cv2.InRange の使い方 も参照してください。
つまずきポイント
⚠️ サイズ・チャンネル数・深度が一致しないと例外が出る
Cv2.Add / Cv2.AddWeighted は src1 と src2 のサイズ、チャンネル数、ビット深度がすべて一致している必要があります。カラー画像(3ch)とグレースケール画像(1ch)をそのまま渡すと cv::Exception になります。事前に Cv2.CvtColor でチャンネルを揃えてから渡しましょう。
// NG: チャンネル数が違う
Cv2.Add(colorMat, grayMat, dst); // 例外
// OK: 揃えてから渡す
using var gray3ch = new Mat();
Cv2.CvtColor(grayMat, gray3ch, ColorConversionCodes.GRAY2BGR);
Cv2.Add(colorMat, gray3ch, dst);
⚠️ ループ内の Mat を using で解放しないとメモリが膨らむ
Cv2.AddWeighted をループで繰り返し呼ぶ実装では、出力 Mat の解放漏れがネイティブメモリのリークにつながります。Mat は C# の GC 管理外のネイティブメモリを保持しているため、using または明示的な Dispose() が必須です。上記フェードイン例のようにループ内で using var frame = new Mat() とするのが確実です。
⚠️ alpha + beta ≠ 1.0 にすると輝度が変化する
AddWeighted で alpha=0.7, beta=0.7 のように合計が 1.0 を超えると、出力が明るくなりすぎて白飛びします。意図しない場合は合計を 1.0 に揃えましょう。逆に、合計を 1.0 未満にすると全体が暗くなります。gamma で補正することも可能です。
関連する関数
- Cv2.Subtract — ピクセル単位の減算。差分検出によく使われます
- Cv2.BitwiseAnd / BitwiseOr — ビット演算による合成・マスク処理
- Cv2.InRange の使い方【OpenCV/C#(OpenCvSharp)】〜色範囲でマスクを作る(色抽出)〜 —
Addの mask 引数と組み合わせて色領域合成に活用できます - Cv2.EqualizeHist / CLAHE の使い方【OpenCV/C#(OpenCvSharp)】〜ヒストグラム平坦化で画像のコントラストを改善する〜 — 合成前に輝度を揃えたいときに役立ちます
まとめ
Cv2.Addは飽和加算、Cv2.AddWeightedは重み付きブレンド合成に使うalpha + beta = 1.0にすると輝度を保ったまま自然な合成が得られる- サイズ・チャンネル・深度の不一致と Mat の Dispose 漏れに注意すれば、実務で安定して使える
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。
→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

