☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░
一、概述
在《OpenCV-Python图像的加法运算cv2.add函数详解》详细介绍了图像的加法运算,除了这种加法外,OpenCV还提供了带权重的加法,即两副图像的像素通道值相加时各自按一定的权重比例取值来相加。
假设有2个图像矩阵src1和src2,在两个图像融合时,各自的权重分别为alpha和beta,则二者融合后的目标图像dst中各像素通道值的计算公式为:
dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma)
上述公式中两副图像的权重alpha和beta取值没有强制要求,但一般情况建议alpha+beta=1
。实际上alpha、beta和src1、src2相乘就是调整的src1、src2对应图像的明暗度(关于这点请参考《OpenCV-Python图像乘法运算cv2.multiply函数详解及像素值溢出归一化处理》),因此图像融合权重加法实际上是先各自调整两副图像的明暗度之后再相加。
对上述公式存在疑问的请参考:
二、融合cv2.addWeighted权重加法函数语法
调用语法:
addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None)
参数说明:
- src1, src2:需要融合相加的两副大小和通道数相等的图像
- alpha:src1的权重
- beta:src2的权重
- gamma:gamma修正系数,不需要修正设置为0,具体请参考《图像处理gamma修正(伽马γ校正)的原理和实现算法》
- dst:可选参数,输出结果保存的变量,默认值为None,如果为非None,输出图像保存到dst对应实参中,其大小和通道数与输入图像相同,图像的深度(即图像像素的位数)由dtype参数或输入图像确认
- dtype:可选参数,输出图像数组的深度,即图像单个像素值的位数(如RGB用三个字节表示,则为24位),选默认值None表示与源图像保持一致。
- 返回值:融合相加的结果图像
三、案例
addWeighted只能实现两副相同大小的图像融合相加,可能我们更需要的是一副小图像和一副大图像的融合相加。在本案例中就实现这样一个函数:
def addWeightedSmallImgToLargeImg(largeImg,alpha,smallImg,beta,gamma=0.0,regionTopLeftPos=(0,0)):
srcW, srcH = largeImg.shape[1::-1]
refW, refH = smallImg.shape[1::-1]
x,y = regionTopLeftPos
if (refW>srcW) or (refH>srcH):
#raise ValueError("img2's size must less than or equal to img1")
raise ValueError(f"img2's size {smallImg.shape[1::-1]} must less than or equal to img1's size {largeImg.shape[1::-1]}")
else:
if (x+refW)>srcW:
x = srcW-refW
if (y+refH)>srcH:
y = srcH-refH
destImg = np.array(largeImg)
tmpSrcImg = destImg[y:y+refH,x:x+refW]
tmpImg = cv2.addWeighted(tmpSrcImg, alpha, smallImg, beta,gamma)
destImg[y:y + refH, x:x + refW] = tmpImg
return destImg
addWeightedSmallImgToLargeImg函数的前5个参数与addWeighted对应,但多了个regionTopLeftPos参数,用于指定小图像左上角放置到大图像的具体位置,缺省为大图像的左上角。
下面使用addWeightedSmallImgToLargeImg来实现一个两副图像融合的案例。案例中使用的大图像seaside.jpg如下:
小图像beauty.jpg如下:
将两副图像融合按权重100%和10%融合,代码如下:
import numpy as np
import cv2
def main():
img1 = cv2.imread(r'F:\pic\seaside.jpg')
img2 = cv2.imread(r'F:\pic\beauty.jpg')
img = addWeightedSmallImgToLargeImg(img1, 1, img2, 0.1,regionTopLeftPos=(300,300))
cv2.imshow('img', img)
cv2.waitKey(0)
main()
运行结果显示的融合图像如下:
四、小结
本文详细介绍了OpenCV-Python相同大小和通道数的两副图像融合的cv2.addWeighted权重加法函数的语法,并在此基础上实现了一个小图像和大图像融合的函数addWeightedSmallImgToLargeImg,并通过addWeightedSmallImgToLargeImg实现了一个图像融合的案例。需要注意的是两幅图像融合的权重系数之间并没有关联关系,而只是用于设置两副图像融合前的明暗度,但一般建议这两个权重值的和为1。
更多OpenCV-Python的介绍请参考专栏《OpenCV-Python图形图像处理》相关文章。
关于老猿的付费专栏
老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏都适合有一定Python基础但无相关知识的小白读者学习。
付费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。