OpenCV-Python Tutorials
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html
图像叠加(融合)
主要函数
被叠加的两张图片的大小、类型(高度/宽度/通道数)必须相同。 但是如果这两张图片大小不相同,有什么方法解决?
-
cv2.add(img1,img2)
:直接对两张图片作加法运算
Numpy中可以直接用res = img1 + img2
相加,但这两者的结果并不相同,因为OpenCV中的加法运算是饱和运算(就是当运算结果大于一个上限或小于一个下限时,结果就等于上限或是下限。),而Numpy中的加法运算是取模运算。
如下面代码中cv2.add(x,y)
运行结果为[[255]],是因为250+10 = 260 >= 255
,所以结果就等于上限255,x+y
运行结果为[4],是因为250+10 = 260 mod 255 = 4
。
OpenCV的结果会更好,所以最好使用OpenCV中的函数
from imutils import *
import os
os.chdir('D:/BaiduYunDownload/')
img1 = imread('image1.jpg')
img2 = imread('image2.jpg')
show(img1)
show(img2)
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x,y)) #运行结果为[[255]]
print(x+y) #运行结果为[4]
res = img1 + img2
show(res)#显示使用数组加法后的图片
add = cv2.add(img1,img2)
show(add)#显示使用OpenCV中add函数的图片
-
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
:也是一种图片相加的操作,可以实现两张图片的线性融合。
- src1 – 输入图片1
- alpha – 图像1的加权系数(融合比例)
- src2 – 输入图像2,必须与图片1的大小、类型(高度/宽度/通道数)相同。beta – 图像2的加权系数(融合比例),
beta = 1.0 - alpha
- dst – 两个图像加权和后的图像,即输出的图像
- gamma – 加权和后的图像的偏移量
- dtype – 输出数组的可选深度;当两个输入数组具有相同的深度时,dtype可以设置为-1(默认值),这将相当于src1.depth().
当α=β=1时,就相当于两张图片直接相加
与cv2.add()
不同的是,cv2.addWeighted()
中两张图片的融合比例不同,这会给人一种混合或者透明的感觉。
图像混合的计算公式如下:
表示两种图片的融合比例,表示融合图片中的像素点, 和分别表示背景和前景图片中的像素点。通过修改的值(0–>1),可以实现不同的图像融合。
也可以按下面的公式对图片进行混合:
将沙漠和老虎的图片融合,沙漠的权重为0.6,老虎的权重为0.4
from imutils import *
import os
os.chdir('C:/Users/lenovo/Pictures/')
img1 = imread('desert.jpg')
img2 = imread('tiger.jpg')
dst = cv2.addWeighted(img1,0.6,img2,0.4,0)#γ的取值为0
show(dst)
运行结果:
如果想不断调节alpha的值,查看不同情况下的融合图像。(可以增加一个滑动条)
import cv2
import numpy as np
import os
os.chdir('C:/Users/lenovo/Pictures/')
img1 = cv2.imread('desert.jpg')
img2 = cv2.imread('tiger.jpg')
cv2.namedWindow('addImage')
#回调函数
def nothing(x):
pass
#添加一个调节alpha值得滑动条
alpha = 0 #初始化
cv2.createTrackbar('alpha','addImage',0,10,nothing)
while(1):
cv2.imshow('addImage',dst)
k = cv2.waitKey(1) & 0xFF
if k == ord('q'): #按q键退出
break
#获得滑动条的value值
alpha = cv2.getTrackbarPos('alpha','addImage')
alpha = alpha/10
beta = 1.0 - alpha
dst = cv2.addWeighted(img1,alpha,img2,beta,0)#γ的取值为0
cv2.destroyAllWindows()
运行结果:(由于放的图片太大,只能截取一部分展示一下滑动条)
3. 按位运算:按位与(AND)、按位或(OR)、按位非(NOT)、按位异或(XOR)等运算。
按位运算的用途:比如要得到一个加logo的图像。如果将两幅图片直接相加会改变图片的颜色,如果用图像混合,则会改变图片的透明度,所以我们需要用按位操作。
给图像加logo的具体步骤
实例:将OpenCV的logo加到图片为沙漠的左上角