1. 图像运算概念
在计算机的世界里,图像由一个个像素点组成,每个像素点代表一个数字,并且数字的大小代表像素点的颜色,所有像素点的颜色组成了一个图像。因此,使用矩阵可以很好的表示图像。
OpenCV提供的运算方法就是基于矩阵的运算。
2. 图像运算
2.1 add()
将两张图片相加(矩阵的各个像素点分别对应相加)
result = cv2.add(img1,img2)
参数:两张大小完全相同的图片。
返回值计算过后的图片(深拷贝)
把lina图4的左上角部分截取了在图1中,然后与girl图2相加,得到如图3的结果
2.2 substract()
将两个图片做差(矩阵的各个像素点分别对应相减)
result = cv2.subtract(img1,img2)
参数:img1-img2
结果保存在一个新参数中(深拷贝)
图像1和2作差后,亮度降低
部分代码示例:
import cv2 import numpy as np img1 = cv2.imread('./image/girl.png') img2 = cv2.imread('./image/lina.jpg') # 打印两个图片的参数 print(img1.shape) print(img2.shape) # 创建像素点为1的矩阵,并且每个像素点都乘50 img3 = np.ones((185, 185, 3), np.uint8)*100 # img2过大,我们截取部分图像,让region与img1一样大 # 截取为深拷贝,对截取的图像运算,并不改变原图像 region = img2[0:185, 0:185] # 将两个图像运算 result = cv2.add(img1, region) # 降低图片的亮度 low_light_result = cv2.subtract(result, img3) # 展示图片 # cv2.imshow("img1", img1) # cv2.imshow("img2", img2) # cv2.imshow("region", region) cv2.imshow('result', result) cv2.imshow('img3', img3) cv2.imshow('low_light_result', low_light_result) cv2.waitKey(0)
2.3 multiply()/divide()
矩阵乘法(将两个矩阵各个像素点分别相乘)
result = cv2.multiply(img1,img2)
矩阵除法(将两个矩阵的各个像素点分别相除)
result = cv2.divide()
2.4 addWeighted()
图像融合,按权重相加
result = cv2.addWeighted(A,alpha,B,bate,gamma)
参数:alpha:A的权重;bate:B的权重;gamma:静态权重(运算完以后再加gamma)
将图1按0.2,图2按0.8的权重相加得到图3
部分代码展示
import cv2 import numpy as np img1 = cv2.imread('./image/girl.png') img2 = cv2.imread('./image/lina.jpg') # 打印两个图片的参数 print(img1.shape) print(img2.shape) # img2过大,我们截取部分图像,让region与img1一样大 # 截取为深拷贝,对截取的图像运算,并不改变原图像 region = img2[0:185, 0:185] # 展示图片 cv2.imshow("img1", img1) cv2.imshow("region", region) # 图像融合 result = cv2.addWeighted(region, 0.2, img1, 0.8, 0) cv2.imshow('result', result) cv2.waitKey(0)
2.5 与/或/非
这里的逻辑运算和我们熟知的其他语言的逻辑运算是一致的。是将矩阵的各个像素点分别进行逻辑运算。
bitwise_and()
图像的按位与运算
result = cv2.bitwise_and(img1,img2)
bitwise_or()
图像的按位或运算
result = cv2.bitwise_or(img1,img2)
bitwise_not()
图像的非运算
result = cv2.bitwise_not(img)
bitwise_xor
图像的按位异或运算(相同为0,相异为1)
result = cv2.bitwise_xor(img1,img2)
部分代码展示
import cv2 import numpy as np # 创建一个全0图像 img1 = np.zeros((400, 400, 3), np.uint8) img2 = np.zeros((400, 400, 3), np.uint8) # 将两幅图部分变成白色 img1[100:200, 100:200] = [255, 255, 255] img2[150:250, 150:250] = [255, 255, 255] cv2.imshow('img1', img1) cv2.imshow('img2', img2) # 位运算 img_and = cv2.bitwise_and(img1, img2) cv2.imshow('img_and', img_and) img_or = cv2.bitwise_or(img1, img2) cv2.imshow('img_or', img_or) img_not = cv2.bitwise_not(img1) cv2.imshow('img_not', img_not) img_xor = cv2.bitwise_xor(img1, img2) cv2.imshow('img_xor', img_xor) cv2.waitKey(0)
代码结果如下所示:
3.给一幅图像添加水印
下面将展示给图片添加水印的大致步骤:
- 引入一幅图片lina
- 要准备一个logo,自己创建
- 计算在图片的什么地方添加,把添加的地方变成黑色
- 利用add,将logo与图片叠加在一起
import cv2 import numpy as np img = cv2.imread('./image/lina.jpg') col, row, chanles = img.shape # 创建logo logo = np.zeros((80, 80, 3), np.uint8) mask1 = np.zeros((80, 80), np.uint8)# 只有一通道,是灰度图 # 画logo logo[10:40, 10:40] = [0, 0, 255] logo[30:70, 30:70] = [0, 255, 0] # 为了将图片中的部分截取下来,把logo的地方给弄黑 mask1[10:40, 10:40] = 255 mask1[30:70, 30:70] = 255 mask1 = cv2.bitwise_not(mask1) # 截取图像部分 region_img = img[0:80, 0:80] # 单通道图像与三通道图像运算,智能这样运算。 mask1 = cv2.bitwise_and(region_img, region_img, mask = mask1) finish_logo = cv2.add(logo, mask1) # 将处理好的mask1与原图像赋值(添加成功) img[0:80, 0:80] = finish_logo cv2.imshow('img', img) # cv2.imshow('logo', logo) # cv2.imshow('mask1', mask1) # cv2.imshow('fin_logo',finish_logo) cv2.waitKey(0)
以上就是关于图像运算的基本API,难免会有解释不清的地方,有问题欢迎在评论区讨论。



