opencv06:图像上的算术运算

目标

学会:

  • 学习图像的几种算术运算
    • 加法
    • 减法
    • 按位运算
  • 学习以下函数
    • cv2.add
    • cv2.addWeighted

图像加法

可以通过OpenCV函数 cv2.add()或仅通过numpy操作res = img1 + img2添加两个图像。两个图像应具有相同的深度和类型,或者第二个图像只是一个标量值。

注意:OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算(超过最大值只取最大值),而Numpy加法是模运算(超过最大值,取模)

x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y))  # 250+10 = 260 => 255
# [[255]]  

print(x+y)  # 250+10 = 260 % 256 = 4  (0~255 -> 256)
# [4]

当添加两个图像时,它将更加可见。OpenCV功能将提供更好的结果。因此,始终最好坚持使用OpenCV功能。

图像融合

这也是图像加法,但是对图像赋予不同的权重,以使其具有融合或透明的感觉。根据以下等式按照权重加图像:

G(x) =(1 - alpha) * f_0(x) + alpha * f_1(x)

alpha取值从0~1,可以在一个图像到另一个图像之间执行很酷的过渡。

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst
函数效果如下
dst = src1 * alpha + src2 * beta + gamma;

找到两个图像,将它们融合在一起。第一幅图像的权重为0.7,第二幅图像的权重为
0.3。在图像上应用以下公式cv2.addWeighted()

img1 = cv2.imread('ml.png')
img2 = cv2.imread('origin.png')
dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意
img1和img2的尺寸大小要保持一致,否则无法对位相加。如果不一样,可以通过cv2.resize实现尺寸变换。
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
src - 原图
dst - 目标图像。
dsize - 目标图像大小。
interpolation - 插值方法。共有5种:
1)INTER_NEAREST - 最近邻插值法
2)INTER_LINEAR - 双线性插值法(默认)
3)INTER_AREA - 基于局部像素的重采样。
4)INTER_CUBIC - 基于4x4像素邻域的3次插值法
5)INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
example:
h, w, _ = img1.shape
img2 = cv2.resize(img2, (w,h), interpolation=cv2.INTER_AREA) # 将img2转换成img1大小

按位运算

这包括按位AND(与) 、 OR(或) 、 NOT(非) 、 XOR(异或)操作。它们在提取图像的任何部分、定义和处理非矩形 ROI 等方面非常有用。 下面将看到一个例子,如何改变一个图像的特定区域。 想把 OpenCV 的标志放在一个图像上面。如果添加两个图像,它会改变颜色。如果混合它,我得到一个透明的效果。但希望它是不透明的。如果是一个矩形区域,可以使用 ROI,就像在上一章中所做的那样。但是 OpenCV 的 logo 不是长方形的。所以可以使用如下的按位操作来实现:

cv2.bitwise_and():位与运算,有0则为0, 全为1则为1
cv2.bitwise_not():或运算,有1则为1, 全为0则为0
cv2.bitwise_or():非运算,非0为1, 非1为0
cv2.bitwise_xor():异或运算,不同为1, 相同为0

img1 = cv2.imread('messi.png')
img2 = cv2.imread('origin.png')
# logo left top
rows, cols, channel = img2.shape
roi = img1[0: rows, 0: cols]  # 获得bg
# mask of logo
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

# 现在将ROI中logo的区域涂黑
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)

# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)

# 将logo放入ROI并修改主图像
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • roi区域
    在这里插入图片描述

  • logo mask
    在这里插入图片描述

  • logo mask inv
    在这里插入图片描述

  • img1_bg
    在这里插入图片描述

  • img2_fg
    在这里插入图片描述

  • dst
    在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值