OpenCV 例程200篇 总目录-202205更新
【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合
拉普拉斯金字塔将源图像分解到不同的频带,越高频的图像信息越到上层。在相同显示尺寸下比较不同分辨率的拉普拉斯图像,可以发现不同尺度下关注的细节是不同的,低分辨率下关注的是较大尺度的基本纹理,而高分辨率下关注的是更精细的纹理。
因此,可以针对不同分解层的频带特征与细节,采用不同的融合算子以突出特定频带上特征与细节,也就可以将不同图像的特征与细节融合在一起。
金字塔图像融合过程,是在不同尺度、不同空间分辨率和不同分解层上分别进行的,也称为多波段融合(Multi-band Blending)。多波段融合的思想,是先对多幅图像分别构建拉普拉斯金字塔,然后对同一层图像(相同频段)按一定规则融合,对融合后的图像金字塔重建得到融合图像。
基于图像分割的拉普拉斯金字塔的图像融合的基本步骤为:
1、对前景图片进行图像分割。如果前景图片的背景颜色比较简单,可以将图片转换到 HSV 色彩空间,用 cv.inRange() 进行色彩图像分割;
2、调整尺寸,将背景图片调整到 power(2,levels) 的整数倍,将前景图像调整到指定大小;
3、图像向下取样, 构造高斯金字塔;
4、图像向上取样, 构造拉普拉斯金字塔;
5、基于掩模图像的拉普拉斯加权融合;
6、由最低分辨率的高斯图像生成最低分辨率的起始图,拼接背景图像和前景的高斯金字塔顶层;
7、通过拼接图像的拉普拉斯金字塔,逐层(逐个分辨率)重建拼接图像,直到得到最高分辨率的拼接图像。
例程:1.91 基于图像分割的金字塔图像融合
# 1.91:基于图像分割的金字塔图像融合img1 = cv2.imread("../images/seaside02.png") # 背景图像img2 = cv2.imread("../images/seagull01.png") # 添加的前景图像xmin, ymin, w, h = 160, 64, 256, 256 # 矩形 ROI 位置: (ymin:ymin+h, xmin:xmin+w)print(img1.shape, img2.shape)levels = 3# HSV 色彩空间图像分割hsv = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV) # 将图片转换到 HSV 色彩空间lowerColor = np.array([100, 43, 46]) # 蓝色阈值下限: 100/43/46upperColor = np.array([124, 255, 255]) # 蓝色阈值上限: 蓝色124/255/255binary = cv2.inRange(hsv, lowerColor, upperColor) # 背景色彩图像分割kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9)) # (5, 5) 结构元dilate = cv2.dilate(cv2.bitwise_not(binary), kernel=kernel, iterations=3) # 图像膨胀segment = cv2.bitwise_and(img2, img2, mask=dilate) # 前景分割图像,前景以外区域黑色# 调整尺寸,将背景图片调整到 power(2,levels) 的整数倍imgBack = cv2.resize(img1, (512, 512), interpolation=cv2.INTER_CUBIC)front = cv2.resize(segment, (w, h)) # 将前景图像调整到指定大小 (w,h)imgFront = np.zeros(imgBack.shape, dtype=np.uint8) # 与 imgback 尺寸相同的黑色图像imgFront[ymin:ymin+h, xmin:xmin+w] = frontgrayFront = cv2.cvtColor(imgFront, cv2.COLOR_BGR2GRAY)_, mask0 = cv2.threshold(grayFront, 1, 255, cv2.THRESH_BINARY_INV) # 二值化处理bg = cv2.bitwise_and(imgBack, imgBack, mask=mask0) # 生成背景,mask 遮罩区域黑色fg = imgFront # 生成前景,前景以外区域黑色stack = cv2.add(bg, fg) # 直接合成前景与背景plt.figure(figsize=(10, 7))plt.subplot(231), plt.axis('off'), plt.title("Original back")plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))plt.subplot(232), plt.axis('off'), plt.title("Original front")plt.imshow(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB))plt.subplot(233), plt.axis('off'), plt.title("Segmentation ")plt.imshow(cv2.cvtColor(segment, cv2.COLOR_BGR2RGB))plt.subplot(234), plt.axis('off'), plt.title("Stacked")plt.imshow(cv2.cvtColor(stack, cv2.COLOR_BGR2RGB))# 图像向下取样, 构造高斯金字塔: [原图,下取样1次,下取样2次,下取样3次,下取样4次]gaussPyrB, gaussPyrF, maskLPyr = [imgBack], [imgFront], [mask0]print(img1.shape, img2.shape, mask0.shape)for i in range(1, levels): # 计算第 i 层高斯金字塔gaussPyrB.append(cv2.pyrDown(gaussPyrB[i-1]))gaussPyrF.append(cv2.pyrDown(gaussPyrF[i-1]))maskLPyr.append(cv2.resize(maskLPyr[i-1], dsize=None, fx=0.5, fy=0.5))# 图像向上取样, 构造拉普拉斯金字塔 [第1层残差,第2层残差,第3层残差,第4层残差]lapPyrB, lapPyrF = [], [] # 从最顶层开始恢复for i in range(levels-1): # 拉普拉斯金字塔有 4 层: 0,1,2,3lapB = gaussPyrB[i] - cv2.pyrUp(gaussPyrB[i+1]) # 残差lapPyrB.append(lapB)lapF = gaussPyrF[i] - cv2.pyrUp(gaussPyrF[i+1]) # 残差lapPyrF.append(lapF)# 基于掩模图像的拉普拉斯加权融合lapFusion = []for i in range(levels-1): # 拉普拉斯金字塔共 4 层: 0,1,2,3mask = maskLPyr[i] # 当前分辨率的掩模遮罩,前景区域黑色遮罩maskInv = 1 - mask # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色bg = cv2.bitwise_and(lapPyrB[i], lapPyrB[i], mask=mask) # 生成背景,mask 遮罩区域黑色fg = cv2.bitwise_and(lapPyrF[i], lapPyrF[i], mask=maskInv) # 生成前景,前景以外区域黑色lapStack = cv2.add(bg, fg) # 前景与背景合成,得到当前分辨率的拉普拉斯融合图像lapFusion.append(lapStack)print("lapFusion", i, maskLPyr[i].shape, lapPyrB[i].shape, lapFusion[i].shape)# 拼接高斯金字塔顶层 G4: (32,32)mask = maskLPyr[levels-1] # 当前分辨率的掩模遮罩,前景区域黑色遮罩maskInv = 1 - mask # 生成逆遮罩,前景区域白色开窗,前景以外区域黑色bg = cv2.bitwise_and(gaussPyrB[levels-1], gaussPyrB[levels-1], mask=mask) # 生成背景,mask 遮罩区域黑色fg = cv2.bitwise_and(gaussPyrF[levels-1], gaussPyrF[levels-1], mask=maskInv) # 生成前景,前景以外区域黑色gaussStack = cv2.add(bg, fg) # 前景与背景合成,得到叠加图像 (32,32)print("gaussStack", gaussStack.shape, gaussPyrB[levels-1].shape, maskLPyr[levels-1].shape) # (32,32)fusion = gaussStack # 从高斯金字塔顶层 G4:(32,32) 开始逐层复原for i in range(levels-1, 0, -1): # 拉普拉斯金字塔有 4 层: 3,2,1,0pyrG = cv2.pyrUp(fusion) # # 上采样,图像尺寸加倍fusion = lapFusion[i-1] + cv2.pyrUp(fusion)# plt.subplot(2,3,levels-i+2), plt.axis('off'), plt.title("G{}: {}".format(i-1,fusion.shape[:2]))# plt.imshow(cv2.cvtColor(fusion, cv2.COLOR_BGR2RGB))plt.subplot(235), plt.axis('off'), plt.title("GaussStack {}".format(gaussStack.shape[:2]))plt.imshow(cv2.cvtColor(gaussStack, cv2.COLOR_BGR2RGB))plt.subplot(236), plt.axis('off'), plt.title("fusion")plt.imshow(cv2.cvtColor(fusion, cv2.COLOR_BGR2RGB))plt.tight_layout()plt.show()
(本节完)
版权声明:
OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124965019)
Copyright 2022 youcans, XUPT
Crated:2022-5-25
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔
【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔
【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像
【youcans 的 OpenCV 例程200篇】188.基于拉普拉斯金字塔的图像融合
【youcans 的 OpenCV 例程200篇】189.基于掩模的拉普拉斯金字塔图像融合
【youcans 的 OpenCV 例程200篇】190.基于图像分割的图像融合
【youcans 的 OpenCV 例程200篇】191.基于图像分割的金字塔图像融合
【youcans 的 OpenCV 例程200篇】192.Gabor 滤波器组的形状
【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】