OpenCV-py学习笔记(二)—— 核心运算/操作

Posted by 刘知安 on 2019-10-26
文章目录
  1. 图像的算术运算
    1. 1.饱和加 cv2.add()
    2. 2. 图像混合 cv2.addWeighted()
    3. 3. 图像位操作

@[TOC]

图像的算术运算

1.饱和加 cv2.add()

OpenCV中的add()函数是饱和运算,也就是说,如果两个8位整数相加,超过了255,自动会截断成255.

1
2
3
4
5
6
7
8
>>> 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
[4]

2. 图像混合 cv2.addWeighted()

图像混合的数学表达式如下,原理就是将两张图片按照一定的比例(透明度)进行融合,产生的图片也一般会存在一种“透明”的感觉。
在这里插入图片描述
在OpenCV中参数的表达与上式略有不同,有以下三个参数α、β,γ
在这里插入图片描述

1
2
3
4
5
6
7
8
img1 = cv2.imread('ml.png')
img2 = cv2.imread('opencv_logo.jpg')

dst = cv2.addWeighted(img1,0.7,img2,0.3,0)

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

结果如下:
在这里插入图片描述
这里,我做了一个类似幻灯片淡入淡出效果的gif动图,由一张图动态过度到另一张,==一定记得把颜色通道翻转一下!!!== 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def slide_view():
img1 = cv2.resize(cv2.imread('bear.jpg'), (500, 500))
img2 = cv2.imread('OpenCV-logo.jpg')

fps = 20
buff = []
for i in range(fps):
alpha = i / fps
beta = 1 - i / fps
dst = cv2.addWeighted(img1, alpha, img2, beta, 0)

cv2.imshow('dst', dst)
# 这里记得反转一下颜色通道,OpenCV中是BGR,imageio是RGB
buff.append(dst[:, :, ::-1])

cv2.waitKey(int(1000 / fps))
cv2.destroyAllWindows()
gif = imageio.mimsave('logo2bear.gif', buff, 'GIF', duration=0.1)

这里效果图是gif不太好上传,你可以自己运行一下上述代码。

3. 图像位操作

上述融合中有一个问题,就是会产生“透明”的效果,有时候我们又不想这样,而是直接把一个图片A放在图片B的上面,这时候位操作就发挥了作用,大致将一下思路(这里记待插入的前景图片为A,插入到的那个图片为B):

  1. 先取出图片B的ROI。
  2. 先将图片A灰度化(如果已经是灰度图当然就无需这步),记为grayA。
  3. 将grayA二值化(取一个阈值,比如说10),小于10的像素为0,其他为1,记二值化后的图片为mask,为了后续需要,将mask按位取反得到mask_inv。
  4. 利用cv2.bitwise_and(roi, roi, mask=mask_inv)将图片B的ROI区域变黑。注意:bitwise_and的运算机制如下:
    在这里插入图片描述
  5. 利用cv2.bitwise_and(imgA, imgA, mask=mask)将图片A的前景取出。
  6. 把前景加到背景变黑的区域。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def bitwise_ops():
# cv2.namedWindow('123', cv2.WINDOW_NORMAL)

img = cv2.imread("man.jpg")
img_logo = cv2.imread("OpenCV-logo.jpg")

# ROI
rows, cols, channels = img_logo.shape
roi = img[0:rows, 0:cols]

# 新建一个logo的mask图片
img_logo_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY)
cv2.imshow("123", img_logo_gray)
cv2.waitKey(0)
ret, mask = cv2.threshold(img_logo_gray, 10, 255, cv2.THRESH_BINARY)
cv2.imshow("123", mask)
cv2.waitKey(0)
mask_inv = cv2.bitwise_not(mask)
cv2.imshow("123", mask_inv)
cv2.waitKey(0)

# 先把背景的ROI区域变黑
img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
cv2.imshow("123", img_bg)
cv2.waitKey(0)

# 取出logo的前景
img_lg = cv2.bitwise_and(img_logo, img_logo, mask=mask)
cv2.imshow("123", img_lg)
cv2.waitKey(0)

# 把logo前景放到变黑的背景图区域
dst = cv2.add(img_bg, img_lg)
img[0:rows, 0:cols] = dst

cv2.imshow('123', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果如下:
在这里插入图片描述