【OpenCV 例程200篇】21. 图像的叠加
两张图像直接进行加法运算后图像的颜色会改变,通过加权加法实现图像混合后图像的透明度会改变,都不能实现图像的叠加。实现图像的叠加,需要综合运用图像阈值处理、图像掩模、位操作和图像加法的操作。我们以 Lena 图像叠加 CVlogo 为例,讨论图像叠加的思路和步骤。...
·
『youcans 的 OpenCV 例程200篇 - 总目录』
【OpenCV 例程200篇】21. 图像的叠加
两张图像直接进行加法运算后图像的颜色会改变,通过加权加法实现图像混合后图像的透明度会改变,都不能实现图像的叠加。
实现图像的叠加,需要综合运用图像阈值处理、图像掩模、位操作和图像加法的操作。
我们以 Lena 图像叠加 CVlogo 为例,讨论图像叠加的思路和步骤:
- 确定图像叠加位置,将 Lena 图像中的叠加位置裁剪出来,使叠加图像的尺寸相同;
- 对前景图像进行二值化处理,生成黑白掩模图像 mask(LOGO区域黑色遮盖)及其反转掩模图像 maskInv (LOGO区域白色开窗);
- 以黑白掩模 mask(LOGO区域黑色遮盖)作为掩模,对背景图像(Lena裁剪图)进行位操作,LOGO区域遮盖为黑色,其它区域保持不变,得到叠加背景图像 img1BG;
- 以反转掩模 maskInv(LOGO区域白色开窗)作为掩模,对前景图像(CVlogo)进行位操作,LOGO区域保持不变,其它区域遮盖为黑色,得到叠加前景图像 img2FG;
- 背景图像 img1BG 和 前景图像 img2FG 通过 cv2.add 加法运算,得到裁剪部分的叠加图像;
- 用叠加图像替换Lena 图像中的叠加位置,得到Lena 叠加 CVlogo 的图像。
基本例程:1.30 图像的叠加
# 1.30 图像的叠加
img1 = cv2.imread("../images/imgLena.tif") # 读取彩色图像(BGR)
img2 = cv2.imread("../images/logoCV.png") # 读取 CV Logo
x, y = (0, 10) # 图像叠加位置
W1, H1 = img1.shape[1::-1]
W2, H2 = img2.shape[1::-1]
if (x + W2) > W1: x = W1 - W2
if (y + H2) > H1: y = H1 - H2
print(W1,H1,W2,H2,x,y)
imgROI = img1[y:y+H2, x:x+W2] # 从背景图像裁剪出叠加区域图像
img2Gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # img2: 转换为灰度图像
ret, mask = cv2.threshold(img2Gray, 175, 255, cv2.THRESH_BINARY) # 转换为二值图像,生成遮罩,LOGO 区域黑色遮盖
maskInv = cv2.bitwise_not(mask) # 按位非(黑白转置),生成逆遮罩,LOGO 区域白色开窗,LOGO 以外区域黑色
# mask 黑色遮盖区域输出为黑色,mask 白色开窗区域与运算(原图像素不变)
img1Bg = cv2.bitwise_and(imgROI, imgROI, mask=mask) # 生成背景,imgROI 的遮罩区域输出黑色
img2Fg = cv2.bitwise_and(img2, img2, mask=maskInv) # 生成前景,LOGO 的逆遮罩区域输出黑色
# img1Bg = cv2.bitwise_or(imgROI, imgROI, mask=mask) # 生成背景,与 cv2.bitwise_and 效果相同
# img2Fg = cv2.bitwise_or(img2, img2, mask=maskInv) # 生成前景,与 cv2.bitwise_and 效果相同
# img1Bg = cv2.add(imgROI, np.zeros(np.shape(img2), dtype=np.uint8), mask=mask) # 生成背景,与 cv2.bitwise 效果相同
# img2Fg = cv2.add(img2, np.zeros(np.shape(img2), dtype=np.uint8), mask=maskInv) # 生成背景,与 cv2.bitwise 效果相同
imgROIAdd = cv2.add(img1Bg, img2Fg) # 前景与背景合成,得到裁剪部分的叠加图像
imgAdd = img1.copy()
imgAdd[y:y+H2, x:x+W2] = imgROIAdd # 用叠加图像替换背景图像中的叠加位置,得到叠加 Logo 合成图像
plt.figure(figsize=(9,6))
titleList = ["1. imgGray", "2. imgMask", "3. MaskInv", "4. img2FG", "5. img1BG", "6. imgROIAdd"]
imageList = [img2Gray, mask, maskInv, img2Fg, img1Bg, imgROIAdd]
for i in range(6):
plt.subplot(2,3,i+1), plt.title(titleList[i]), plt.axis('off')
if (imageList[i].ndim==3): # 彩色图像 ndim=3
plt.imshow(cv2.cvtColor(imageList[i], cv2.COLOR_BGR2RGB)) # 彩色图像需要转换为 RGB 格式
else: # 灰度图像 ndim=2
plt.imshow(imageList[i], 'gray')
plt.show()
cv2.imshow("imgAdd", imgAdd) # 显示叠加图像 imgAdd
key = cv2.waitKey(0) # 等待按键命令
例程说明 1.30:
- 本例程实现图像的叠加,中间过程图像如上图所示,最终的叠加图像如下图所示。
- 图像叠加所涉及的操作步骤较多,建议将上文的步骤说明与程序、中间过程图像相互对照进行阅读。
- 使用位操作生成前景 img1Bg 时,使用掩模图像 mask 对 imgROI 与 imgROI 进行 “与操作”,而不是直接对 mask 与 imgROI 进行操作,是因为 mask 为灰度图像而 imgROI 为彩色图像,不能直接进行加法或位操作。
- 使用位操作生成前景、背景图像时,遮罩区域以外 imgROI 与 imgROI 进行 “自与操作”,如果用 “自或操作” (参见程序注释语句)的效果也是相同的。此处甚至也可以用加法操作 cv2.add 实现(参见程序注释语句),但位操作的运算速度更快。
- 函数 threshold() 将灰度图像转换为二值图像(Binarization),只有黑白两色。该方法通过固定阈值 thresh 处理图像,将像素点的灰度值设为 0 或 255。
(本节完)
版权声明:
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/121265151)
Copyright 2022 youcans, XUPT
Crated:2021-11-18
【第2章:图像的数值运算】
18. 图像的掩模加法
20. 图像的按位运算
21. 图像的叠加
更多推荐
已为社区贡献29条内容
所有评论(0)