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 个规则
- 两张图像必须大小相同、通道相同
- 标准混合:alpha + beta = 1.0
- 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;
}
若文章对您有帮助,可以激励一下我哦,祝您平安幸福!
| 微信 | 支付宝 |
|---|---|
![]() |
![]() |

