在OpenCV图像加法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对应图像的明暗度,因此图像融合权重加法实际上是先各自调整两副图像的明暗度之后再相加。
import cv2
out = cv2.addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=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
该函数的前5个参数与addWeighted对应,但多了个regionTopLeftPos参数,用于指定小图像左上角放置到大图像的具体位置,缺省为大图像的左上角。
下面使用addWeightedSmallImgToLargeImg来实现一个两副图像融合的案例。
import numpy as np
import cv2
img1 = cv2.imread(r'a.jpg')
img2 = cv2.imread(r'b.jpg')
img = addWeightedSmallImgToLargeImg(img1, 1, img2, 0.6,regionTopLeftPos=(100, 100))
cv2.imwrite('result.jpg', img)
【1】https://blog.csdn.net/LaoYuanPython/article/details/109143281