OpenCV图像叠加、融合与按位操作详解

一颗松果
一颗松果
发布时间:2026-10-13| 3人浏览过
原创

本文详解OpenCV中图像处理的三种核心操作:使用cv2.add进行像素级图像叠加,注意数值截断与NumPy模运算的区别;利用cv2.addWeighted实现加权图像融合,通过调整alpha和beta控制透明度;以及通过cv2.bitwise_and执行按位操作,结合掩膜(mask)实现Logo嵌入等局部图像修改。

图像叠加:cv2.add

一、图像叠加:cv2.add


res=cv2.add(img1, img2) 或者res=cv2.add(img1, 标量值)

参数说明:cv2.add函数用于将两张图片对应位置的像素值相加,或者给每个像素值加上一个标量。若计算结果超过255,则强制设置为255。

需注意,若进行两张图片的相加,必须确保两者的尺寸和通道数完全一致;若使用标量值相加,该值可为整数或浮点数,通常用于提升图像亮度。


import cv2

img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
print(img1.shape)
print(img2.shape)
#输出: (1039, 750, 3)
   #(1050, 700, 3)
   
img2.resize((img1.shape[0],img1.shape[1],3))
print(img2.shape)
#输出:(1039, 750, 3)

res=cv2.add(img1,img2)#或者res=cv2.add(img1,10)

前文提到cv2.add会将超过255的值截断为255,但NumPy中的加法运算执行的是模运算,具体差异见下文示例。


import cv2
import numpy as np

x = np.uint8([250])
y = np.uint8([10])

print( cv2.add(x,y) ) # 250+10 = 260 => 255
print( x+y )     # 250+10 = 260 % 256 = 4

输出: [[255]] [4]

图像融合:cv2.addWeighted

二、图像融合:cv2.addWeighted


cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst

dst = src1 * alpha + src2 * beta + gamma

参数说明:src1为第一张图片,alpha为其权重;src2为与第一张大小和通道数相同的图片,beta为其权重;gamma为加到总和上的标量,用于调节亮度;dst为输出结果。

同样需要注意,参与融合的图片尺寸必须保持一致。


import cv2
import numpy as np

img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
#统一图片大小
img2 = cv2.resize(img2,(img1.shape[1],img1.shape[0]))

dst = cv2.addWeighted(img1,0.5,img2,0.5,0)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()




用户可根据需求调整两张图片的权重比例,从而获得不同的视觉效果。

图像按位操作:cv2.bitwise_and

三、图像的按位操作:cv2.bitwise_and


'''
注意,src1和src2的形状要保持一致,一般都是同一张图像,
关键是在于mask,mask必须得是8-bit单通道array,尺寸也要和src相同
'''
bitwise_and(src1, src2[, dst[, mask]]) -> dst

直接相加图片会改变颜色,图像混合会改变透明度,因此需要采用按位操作。首先了解掩膜(mask)的概念:掩膜利用一副二值化图片对另一幅图片进行局部遮挡,具体效果如下图所示:(此处参考了 原文链接)

基于此思路,我们需要从原图中抠出放置Logo的区域,再将Logo嵌入其中。


import cv2
import numpy as np

img1 = cv2.imread('lena.jpg')
img2 = cv2.imread('opencv-logo-white.jpg')

# 把logo放在左上角,所以我们只关心这一块区域
rows, cols = img2.shape[:2]
roi = img1[:rows, :cols]

# 创建掩膜
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

# 保留除logo外的背景
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
dst = cv2.add(img1_bg, img2) # 进行融合
img1[:rows, :cols] = dst # 融合后放在原图上

cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()



阅读至此,许多人会产生疑问,包括作者初期也有类似困惑。

为何要使用两个roi进行与运算?roi&roi结果不仍是roi本身吗?

mask与roi尺寸相同,且希望在roi中去除的区域在mask中对应像素值恰好为0,为何不直接让roi和mask相与?

查阅资料后得到的解释如下,仅供参考:

  • 因为mask是单通道的array,这是规定,而roi是三通道,两者无法直接进行与运算。
  • 因此先利用roi和roi相与得到roi本身,而mask可以控制相与后输出数据的某些元素发生变化,相与后的输出即为roi,此时相当于直接对roi进行操作,使roi中和mask中像素值为0的像素点对应的像素值也为0,即变为黑色,从而达到预期效果。

到此这篇关于opencv中图像叠加/图像融合/按位操作的实现的文章就介绍到这了,更多相关opencv 图像叠加/图像融合/按位操作内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。