OpenCV-Python Tutorials

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html

图像叠加(融合)

主要函数

被叠加的两张图片的大小、类型(高度/宽度/通道数)必须相同。 但是如果这两张图片大小不相同,有什么方法解决?

  1. 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函数的图片


  1. 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()中两张图片的融合比例不同,这会给人一种混合或者透明的感觉。
图像混合的计算公式如下:
python opencv显示中文 opencv文档python_图像融合python opencv显示中文 opencv文档python_图像融合_02表示两种图片的融合比例,python opencv显示中文 opencv文档python_图像融合_03表示融合图片中的像素点,python opencv显示中文 opencv文档python_图像融合_04python opencv显示中文 opencv文档python_python opencv显示中文_05分别表示背景和前景图片中的像素点。通过修改python opencv显示中文 opencv文档python_图像融合_02的值(0–>1),可以实现不同的图像融合。

也可以按下面的公式对图片进行混合:
python opencv显示中文 opencv文档python_python opencv显示中文_07

将沙漠和老虎的图片融合,沙漠的权重为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)

运行结果:

python opencv显示中文 opencv文档python_图像融合_08

如果想不断调节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()

运行结果:(由于放的图片太大,只能截取一部分展示一下滑动条)

python opencv显示中文 opencv文档python_图像融合_09


3. 按位运算:按位与(AND)、按位或(OR)、按位非(NOT)、按位异或(XOR)等运算。

按位运算的用途:比如要得到一个加logo的图像。如果将两幅图片直接相加会改变图片的颜色,如果用图像混合,则会改变图片的透明度,所以我们需要用按位操作。

给图像加logo的具体步骤

实例:将OpenCV的logo加到图片为沙漠的左上角

python opencv显示中文 opencv文档python_按位操作_10