opencv使用addweighted()实现两幅图融合相加

使用addweighted()函数可以使两图片按照权重相加融合。两图的大小、类型(高度/宽度/通道数)必须相同

 

 addWeighted(imgSrc2, alp, imgSrc1, 1 - alp, 0, imgDst);

OpenCV用addWeighted()方法实现将两张图按照不同的透明度进行叠加,程序写法为:    

addWeighted(原图2, a, 原图1, 1-a, 0, 合成图像);

其中,a为透明度参数,值在0~1.0之间,addWeighted()方法根据给定的两张原图及a值,用插值算法合成一张新图,运算公式为:    

合成图像素值=原图1像素值×(1-a)+原图2像素值×a

特别是,当a =0时,合成图像就等同于原图1;当a =1时,合成图像等同于原图2。

函数原型:

CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
                              double beta, double gamma, OutputArray dst, int dtype = -1);

 @brief Calculates the weighted sum of two arrays.
The function addWeighted calculates the weighted sum of two arrays as follows:


\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} ) \f]


where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently.
The function can be replaced with a matrix expression:
@code{.cpp}

dst = src1*alpha + src2*beta + gamma;

@endcode
@note Saturation is not applied when the output array has the depth CV_32S. You may even get result of an incorrect sign in the case of overflow.

注意:输出数组深度位CV_32S时,这个函数不适用,这时可能会内存溢出或者结果不对。
@param src1 first input array.
@param alpha weight of the first array elements.
@param src2 second input array of the same size and channel number as src1.
@param beta weight of the second array elements.
@param gamma scalar added to each sum.
@param dst output array that has the same size and number of channels as the input arrays.
@param dtype optional depth of the output array; when both input arrays have the same depth, dtype can be set to -1, which will be equivalent to src1.depth().

参数1:src1,第一个原数组.

参数2:alpha,第一个数组元素权重。透明度

参数3:src2第二个原数组

参数4:beta,第二个数组元素权重,透明度

参数5:gamma,图1与图2作和后添加的数值。不要太大,不然图片一片白。总和等于255以上就是纯白色了。

参数6:dst,输出图片

参数7:dtype ,默认为-1.不用管

只有尺寸相同的两幅图片才能融合,如果两幅图尺寸不相等,将其中一幅图重置尺寸,与另一幅相同,但是被重置尺寸的图片会变形。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat src1, src2, dst;//创建Mat数组,等待存储图片
	src1 = imread("4.jpg");
	src2 = imread("6.jpg");
	cout << "src1.size:"<< src1.size << endl;
	cout << "src2.size:" << src2.size << endl;
	imshow("原图1", src1);
	imshow("原图2", src2);
	//融合前判断两张图片尺寸是否一样
	if (src1.size != src2.size)
	{
		cout << "两张图片尺寸不一样" << endl;
		//resize 其中一幅图,使之于另一幅图尺寸一样
		resize(src1, src1, Size(src2.cols, src2.rows));
	}

	//将图1与图2线性混合
	addWeighted(src1, 0.5, src2, 0.5, 0, dst);
	/*注释
	参数分别为:图1,图1的权重,图2,图2的权重,权重和添加的值为0,输出图片src
	*/
	imshow("混合后的图片", dst);
	waitKey(0);
	return 0;

}

融合后:

 设置ROI,将一幅图嵌入到另一幅中:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat src1, src2, dst;//创建Mat数组,等待存储图片
	src1 = imread("4.jpg");
	src2 = imread("6.jpg");
	cout << "src1.size:"<< src1.size << endl;
	cout << "src2.size:" << src2.size << endl;
	imshow("原图1", src1);
	imshow("原图2", src2);
	//融合前判断两张图片尺寸是否一样
	if (src1.size != src2.size)
	{
		cout << "两张图片尺寸不一样" << endl;
		resize(src1, src1, Size(src1.cols*0.5, src1.rows*0.5));

		//利用ROI,获取将要理图像的矩形大小  
		Mat imageROI = src2(Rect(20, 40, src1.cols, src1.rows));
		//在ac图像左上角(20,40)处(即起点位置),获取同ahand图像尺寸一致的区域 
		addWeighted(src1, 0.5, imageROI, 0.5, 0, imageROI);
		imshow("混合后的图片", src2);
	}
	else {
		//将图1与图2线性混合
		addWeighted(src1, 0.5, src2, 0.5, 0, dst);
		imshow("混合后的图片", dst);
	}


	waitKey(0);
	return 0;

}

### 融合概述 融合是将两幅或更多像合并为一幅新像的技术,以获得更高质量的像信息。这种技术在计算机视觉和像处理中广泛应用,例如医学成像、遥感和增强现实等领域。OpenCV 提供了多种方法来实现融合,包括基于金字塔的方法(如拉普拉斯金字塔)和简单的加权平均法。 ### 使用 OpenCV 进行融合的基本步骤 #### 1. **加载像** 首先需要加载要融合像,并确保它们具有相同的尺寸。如果像的大小不同,则需要进行调整。 ```python import cv2 import numpy as np # 加载像 image1 = cv2.imread('image1.jpg') image2 = cv2.imread('image2.jpg') # 确保像大小相同 image1 = cv2.resize(image1, (512, 512)) image2 = cv2.resize(image2, (512, 512)) ``` #### 2. **简单加权平均法** 这是一种直接的方法,通过给每张像分配一个权重,然后将它们相加以生成最终的融合像。这种方法适用于像内容相似的情况。 ```python # 定义权重 alpha = 0.6 beta = 0.4 # 计算加权平均 blended_image = cv2.addWeighted(image1, alpha, image2, beta, 0) cv2.imshow('Blended Image', blended_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` #### 3. **基于金字塔的融合** 对于更复杂的场景,可以使用拉普拉斯金字塔来进行多尺度融合。这种方法能够保留更多的细节信息,并且在处理边缘时表现更好。 ##### 构建高斯金字塔 高斯金字塔是通过对像进行多次降采样来构建的,每次降采样都会减少像的分辨率。 ```python def build_gaussian_pyramid(image, levels): pyramid = [image] for _ in range(1, levels): image = cv2.pyrDown(image) pyramid.append(image) return pyramid ``` ##### 构建拉普拉斯金字塔 拉普拉斯金字塔是通过从高斯金字塔中的每一层减去其上一层的扩展版本来构建的。 ```python def build_laplacian_pyramid(gaussian_pyramid): laplacian_pyramid = [] for i in range(len(gaussian_pyramid) - 1): size = (gaussian_pyramid[i].shape[1], gaussian_pyramid[i].shape[0]) upsampled = cv2.pyrUp(gaussian_pyramid[i + 1], dstsize=size) laplacian = cv2.subtract(gaussian_pyramid[i], upsampled) laplacian_pyramid.append(laplacian) laplacian_pyramid.append(gaussian_pyramid[-1]) # 最顶层直接保留 return laplacian_pyramid ``` ##### 融合拉普拉斯金字塔 将两个像的拉普拉斯金字塔进行融合,通常是对每个层级的像进行加权平均。 ```python def blend_pyramids(pyramid1, pyramid2, weight=0.5): blended_pyramid = [] for l1, l2 in zip(pyramid1, pyramid2): blended_layer = weight * l1 + (1 - weight) * l2 blended_pyramid.append(blended_layer.astype(np.uint8)) return blended_pyramid ``` ##### 重建融合后的像 通过逐层扩展并相加的方式,从拉普拉斯金字塔重建最终的融合像。 ```python def reconstruct_from_pyramid(pyramid): reconstructed = pyramid[-1] for i in range(len(pyramid) - 2, -1, -1): size = (pyramid[i].shape[1], pyramid[i].shape[0]) reconstructed = cv2.pyrUp(reconstructed, dstsize=size) reconstructed = cv2.add(reconstructed, pyramid[i]) return reconstructed ``` ##### 完整的融合流程 ```python levels = 5 # 构建高斯金字塔 gaussian1 = build_gaussian_pyramid(image1, levels) gaussian2 = build_gaussian_pyramid(image2, levels) # 构建拉普拉斯金字塔 laplacian1 = build_laplacian_pyramid(gaussian1) laplacian2 = build_laplacian_pyramid(gaussian2) # 融合金字塔 blended_pyramid = blend_pyramids(laplacian1, laplacian2) # 重建像 final_image = reconstruct_from_pyramid(blended_pyramid) # 显示结果 cv2.imshow('Final Blended Image', final_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` ### 总结 上述代码展示了如何使用 OpenCV 实现两种常见的融合方法:简单加权平均法和基于拉普拉斯金字塔的多尺度融合。简单加权平均法适用于快速融合,而基于金字塔的方法则能够在复杂场景下提供更好的视觉效果。根据具体的应用需求,可以选择合适的方法来实现融合[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值