Opencv中文网

图像线性融合(叠加 / 混合 / 透明度调节)AddWeighted

Cv2.AddWeighted是 OpenCV 中专门用于两张图像线性混合的函数,效果和原理完全等价于:dst = src1*alpha + src2*beta + gamma。它 ConvertTo(单图调整亮度对比度)很像,但核心区别是:

AddWeighted = 2 张图 按权重混合 + 偏移

ConvertTo = 1 张图 × 系数 + 偏移

Cv2.AddWeighted = 两张图片按比例透明叠加

  • 可以做水印叠加
  • 可以做图像融合
  • 可以做曝光融合
  • 甚至可以替代 ConvertTo 做亮度对比度

数学公式:dst = src1 * alpha + src2 * beta + gamma

函数原型(C# OpenCVSharp)

void AddWeighted(
    InputArray src1,    // 第一张输入图像
    double alpha,       // 第一张图像的权重
    InputArray src2,    // 第二张输入图像
    double beta,        // 第二张图像的权重
    double gamma,       // 额外亮度偏移值
    OutputArray dst,    // 输出图像
    int dtype = -1      // 图像深度(默认-1,保持不变)
);

参数逐字详解

1. src1

第一张图像(Mat),可以是彩色 / 灰度。

2. alpha

第一张图的透明度 / 权重

  • 0 ~ 1.0 最常用
  • 越大,第一张图越明显

3. src2

第二张图像

必须和 src1 大小、通道数完全一样!

4. beta

第二张图的透明度 / 权重

  • 通常满足:alpha + beta = 1.0(标准混合)
  • 也可以大于 1,用于增强亮度

5. gamma

整体亮度增加值

  • 0 = 不调整
  • 正数 = 整体变亮
  • 负数 = 整体变暗

6. dst

输出融合后的图像

7. dtype = -1

保持图像深度不变,固定写 -1

最经典用法:两张图 50% 混合

Cv2.AddWeighted(
    img1, 0.5,   // 图1占50%
    img2, 0.5,   // 图2占50%
    0,           // 无亮度偏移
    result
);

公式:result = img10.5 + img20.5 + 0

AddWeighted 与 ConvertTo 的关系(超级重点)

src.ConvertTo(dst, -1, alpha, beta);
// 公式:dst = src*alpha + beta

Cv2.AddWeighted 完全可以实现一模一样效果:

Mat zero = Mat.Zeros(src.Size(), src.Type());
Cv2.AddWeighted(src, alpha, zero, 0, beta, dst);

结论:ConvertTo 是 AddWeighted 的特殊情况(第二张图全黑)

最常用的 4 大功能

  • 两张图淡入淡出、叠加效果:Cv2.AddWeighted(img1, 0.7, img2, 0.3, 0, dst);
  • 给图片加半透明水印:Cv2.AddWeighted(background, 1.0, logo, 0.2, 0, dst);
  • 亮度 + 对比度调节(和 ConvertTo 完全一样):Mat black = Mat.Zeros(src.Size(), src.Type()); Cv2.AddWeighted(src, 1.2, black, 0, 20, dst); // 等价于:src.ConvertTo(dst, -1, 1.2, 20);
  • 高动态范围 HDR 融合:多张不同曝光图片合成

示例代码:

Mat img1 = Cv2.ImRead("img1.jpg");
Mat img2 = Cv2.ImRead("img2.jpg");

// 确保两张图大小一样
Cv2.Resize(img2, img2, img1.Size());

Mat result = new Mat();

// 融合:70% img1 + 30% img2
Cv2.AddWeighted(img1, 0.7, img2, 0.3, 0, result);

Cv2.ImWrite("merge.jpg", result);

必须记住的 3 个规则

  1. 两张图像必须大小相同、通道相同
  2. 标准混合:alpha + beta = 1.0
  3. gamma 是整体亮度偏移

一句话终极总结

Cv2.AddWeighted = 两张图像线性混合

公式:dst = src1a + src2b + gamma

它是图像叠加、融合、水印、淡入淡出的万能工具

工程示例代码:

public override Mat Execute(Mat src)
{
    Mat dst = new Mat();

    try
    {
        // 1. 统一尺寸
        Mat image2Resized = new Mat();
        Cv2.Resize(Image2, image2Resized, src.Size());

        // ==============================================
        // 🔥 终极修复:不管是3通道、4通道、1通道,全部转成和 src 一致
        // ==============================================
        Mat image2Final = new Mat();

        // 如果是 4通道透明图 → 转 3通道 BGR
        if (image2Resized.Channels() == 4)
        {
            Cv2.CvtColor(image2Resized, image2Final, ColorConversionCodes.BGRA2BGR);
        }
        // 如果通道数不匹配 → 强制转换
        else if (image2Resized.Channels() != src.Channels())
        {
            if (src.Channels() == 1)
                Cv2.CvtColor(image2Resized, image2Final, ColorConversionCodes.BGR2GRAY);
            else
                Cv2.CvtColor(image2Resized, image2Final, ColorConversionCodes.GRAY2BGR);
        }
        else
        {
            image2Final = image2Resized;
        }

        // 现在通道、尺寸完全一致
        Cv2.AddWeighted(src, Alpha, image2Final, 1 - Alpha, 0, dst);

        Success = true;
        Message = "融合成功";

        // 释放临时资源
        if (image2Final != image2Resized)
            image2Final.Dispose();
        image2Resized.Dispose();
    }
    catch (Exception ex)
    {
        Message = "融合失败:" + ex.Message;
        Success = false;
        return src.Clone();
    }

    return dst;
}

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1