在开始之前,我们先导入图像,img中存放我们需要用到的图像。并定义一个图像显示函数,便于接下来画图。
# 导入opencv库
import cv2
# 定义图像显示函数
def cv_show(name,img):
# 传入(自定义窗口名,图像数据)
cv2.imshow(name,img)
# 等待时间设为0,让图像不会自己消失
cv2.waitKey(0)
# cv2.waitKey(1000) # 图像显示1000毫秒后消失
# 键盘上任意按一个图像消失
cv2.destroyAllWindows()
# 指定图像所在的文件夹
filepath = 'C:\\...\\opencv\\img'
# 提取问价夹中的某一张图像
img = cv2.imread(filepath+'\\wise3.jpg')
src: 输入的图片
top, bottom, left, right: 相应方向上的边框宽度
borderType: 定义添加边框的方法
value:如果borderType为 cv2.BORDER_CONSTANT 时需要填充的常数值
cv2.BORDER_REPLICATE:复制法,复制最边缘像素
cv2.BORDER_REFLECT:反射法,在图像中指定像素的两边进行反射复制,如: gfedcba|abcdefgh|hgfedcb
cv2.BORDER_REFLECT_101:反射法,以最边缘像素为轴,如:dcba|abcd|dcba
cv2.BORDER_WRAP:外包装法,如:cdefgh|abcdefgh|abcdefg
cv2.BORDER_CONSTANT:常量数值填充
我们分别来看一下各种方法:
#(1)边界填充
# 先指定在上下左右分别填充的大小
top_size,bottom_size,left_size,right_size = (50,50,50,50)
# 填充函数cv2.copyMakeBorder(输入图像,填充多少,borderType=填充方法)
# 复制
img1 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
# 反射
img2 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT)
# 反射101
img3 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT_101)
# 外包装
img4 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
# 常量填充,value=0
img5 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_CONSTANT,value=0)
# 绘图
import matplotlib.pyplot as plt
# 显示中文宋体
plt.rcParams['font.sans-serif'] = ['SimSun']
# 设置画板大小
plt.figure(figsize=(10,7))
# 原图
plt.subplot(231),plt.imshow(img),plt.title('原图')
# 复制
plt.subplot(232),plt.imshow(img1),plt.title('复制')
# 反射
plt.subplot(233),plt.imshow(img2),plt.title('反射')
# 反射101
plt.subplot(234),plt.imshow(img3),plt.title('反射101')
# 外包装
plt.subplot(235),plt.imshow(img4),plt.title('外包装')
# 常量填充
plt.subplot(236),plt.imshow(img5),plt.title('常量0填充')
我们从图中可以看出不同方法的区别。可能有同学可能会问,这颜色怎么这么奇怪。注意,在opencv中图像的颜色通道是BGR组成的,而matplot中颜色通道是RGB构成,在展示图像时,会有颜色的差别,所以尽量用opencv的图像展示方法。
两张图片直接做加法,需要两张图像的size一样大,对应的像素点相加,由于每个像素点值的大小在0-255之间,因此相加后大于255的像素值自动减去255,如150+150=300,没有300的像素值,自动变成45。如果一张图像整体加上一个常量,即每个元素的增加一个常量值,亮度提升。
# 先读入2张图片
img1 = cv2.imread(filepath+'\\sit1.jpg')
img2 = cv2.imread(filepath+'\\wise2.jpg')
# ==1== 直接相加超过255的像素值会自动减去255
# 对img1上的所有像素点加10,整体的shape不变
img3 = img1+10
cv_show('img3',img3)
# 将两张图相加,两张图的shape需要一致
img4 = img1+img2
cv_show('img4',img4)
# 由于图中的每个像素点的取值是在0-255之间,如果超过255会自动减去255
size相同的两幅图像直接相加后的结果为
要求两张图象的size和通道数相同。对应像素值相加,相加后,超过255的数值就让它等于255
src1, src2:两幅图像相加,或一张图像加一个数值
mask:图像掩膜,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0
dtype:输出图像数组的深度,即图像单个像素值的位数(如RGB用三个字节表示,则为24位)。
# ==2== cv2.add()
# 相加后若超过255,那像素点的值就取255
img5 = cv2.add(img1,img2)
cv_show('img5',img5)
将两张图像按一定比例融合在一起,需要两张图像的size和通道数相同
#(3)图像融合,两张图混合在一起
# 读取两张图片
img1 = cv2.imread(filepath+'\\sit2.jpg')
img2 = cv2.imread(filepath+'\\wise2.jpg')
# ==1== 先查看一下两张图的shape
img1.shape #(503,1201,3)
img2.shape #(1080,1440,3)
注意制定具体的长度和高度时,一定是先指定宽再指定长,如下 cv2.resize(img2,(1201,503)),把img2变成高为503长为1201,而我们.shape查到的结果是(高, 长)
# ==2== 改变大小cv2.resize(图像,指定大小),接收返回值
# 注意先指定宽,再指定高
# 将img2变得和img1的size一样
img2 = cv2.resize(img2,(1201,503))
img2.shape
# 不指定具体数值,只给出倍数关系,即图像沿x和y轴的缩放比例
img4 = cv2.resize(img2,(0,0),fx=3,fy=3)
cv_show('name', img4)
相当于 y = a x1 + b x2 + c,其中a、b代表权重,c代表亮度上提亮多少
img5 = cv2.addWeighted(img1,0.5,img3,0.4,0)
cv_show('img5',img5)
首先我们把需要用到的图像和库导入一下
import cv2
import matplotlib.pyplot as plt
# 指定图像所在文件夹
filepath = 'C:\\...\\opencv\\img'
# 转换成灰度
img = cv2.imread(filepath+'\\wise3.jpg',cv2.IMREAD_GRAYSCALE)
参数:
src: 输入图,只能输入单通道图像,通常是灰度图
dst: 输出图
thresh: 阈值,是一个值,通常为127
maxval: 当图像超过了阈值或低于阈值(由type决定),所赋予的值
type: 二值化操作的类型,包含:
cv2.THRESH_BINARY 二值法,超过阈值thresh部分取maxval(设定的最大值),否则取0
cv2.THRESH_BINARY_INV 超过阈值的部分取0,小于阈值取maxval
cv2.THRESH_TRUNC 截断,大于阈值的部分设为阈值,小于阈值的不变
cv2.THRESH_TOZERO 大于阈值的部分不变,小于阈值的部分变成0。亮的部分不变,暗的部分变成黑点
cv2.THRESH_TOZERO_INV 大于阈值的变成0,小于阈值的不变。暗的部分不变,亮的部分变成黑点
返回值
ret: 阈值
dst: 输出图
# 方法1:输入灰度图,阈值127,大于阈值变成255,小于阈值变成0
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# 方法2:大于阈值127变成0,小于阈值变成255。原本比较亮的变成黑点,原来暗的变成白点
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
# 方法3:大于阈值127的设为阈值,小于阈值的不变
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
# 方法4:大于阈值127的值变成127,小于127的值不变
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
# 方法5:小于127的值不变,大于127的值变成0
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
# 绘图
titles=['original','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images=[img,thresh1,thresh2,thresh3,thresh4,thresh5]
plt.figure(figsize=(8,8))
for i in range(6):
plt.subplot(2,3,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.show()