本篇学习笔记主要内容在图像的数值运算、图像阈值、图像平滑(滤波)等内容。
获取更多可以查看本栏目其他文章。
往期内容:
OpenCV-Python图像处理学习笔记(一)——认识、安装、环境测试
OpenCV-Python图像处理学习笔记(二)——图像/视频读取保存、分割及边界填充
OpenCV-Python图像处理学习笔记(三)——数值运算、图像阈值、图像平滑(滤波)
OpenCV-Python图像处理学习笔记(四)——形态学操作、图像梯度
OpenCV-Python图像处理学习笔记(五)——Canny 边缘检测、图像金字塔、轮廓检测(一)OpenCV-Python图像处理学习笔记(六)——轮廓检测(二)、模板匹配
OpenCV-Python图像处理学习笔记(七)——直方图、图像变换
目录
导入必要Python包
import cv2
import numpy as np
import matplotlib.pyplot as plt
1 图像数值运算
1.1 加法运算
x = np.array([250])
y = np.array([10])
print(cv2.add(x,y)) # 250+10 = 260 => 255
# [[255]]
print(x+y) # 250+10 = 260 % 256 = 4
# [4]
两幅图像的大小,类型必须一致,add()方式得到的数值最大为255,直接相加则会取余数。
1.2 图像融合
图像融合本质上也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。主要涉及到cv2.addWeighted()函数:
图像混合的计算公式如下:
通过修改 α 的值(0 → 1),可以实现非常酷的混合。 现在我们把两幅图混合在一起。第一幅图的权重是 0.7,第二幅图的权重 是 0.3。函数 cv2.addWeighted() 可以按下面的公式对图片进行混合操作。
这里的取值为 0。
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.destroyAllWindow()
1.3 图像缩放
cv2.resize()是图片缩放函数,可以对图像进行任意缩放操作,例如图像的运算操作只能在两幅图像的shape值一致情况下进行,此时可以适用cv2.resize(),涉及两中方式:
方式一:指明缩放尺寸
img = cv.imread("你希望缩放的图片")
# 缩放图像,缩放后尺寸为(400, 300)
dst = cv.resize(img, (400, 300))
cv.imshow('dst', dst)
cv.waitKey(0)
cv.destroyAllWindows()
方式二:指明缩放比例
# 等比例缩放,图像宽度缩放0.5,高度缩放0.3
dst = cv.resize(img, (0, 0), fx=0.5, fy=0.3)
2 图像阈值操作
阈值操作即当像素值高于阈值时,我们给这个像素赋予一个新值,否则我们给它赋予另外一种颜色。 这里可以适用cv2.threshhold()函数。
img = cv2.imread(path)
# cv2.threshold参数:原图像、阈值下界、阈值上界、阈值类型。
ret, threshold1 = cv2.threshold(img, 100, 205, cv2.THRESH_BINARY)
ret, threshold2 = cv2.threshold(img, 100, 205, cv2.THRESH_BINARY_INV)
ret, threshold3 = cv2.threshold(img, 100, 205, cv2.THRESH_TRUNC)
ret, threshold4 = cv2.threshold(img, 100, 205, cv2.THRESH_TOZERO)
ret, threshold5 = cv2.threshold(img, 100, 205, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
imgs = [img, threshold1, threshold2, threshold3, threshold4, threshold5]
for i in range(6):
plt.subplot(2, 3, i+1)
plt.imshow(imgs[i], cmap='gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
其中阈值类型有以下几种:
- cv2.THRESH_BINARY 二值阈值化
- cv2.THRESH_BINARY_INV 反向二值阈值化
- cv2.THRESH_TRUNC 截断阈值化
- cv2.THRESH_TOZERO 超过阈值被设置为0
- cv2.THRESH_TOZERO_INV 低于阈值被设置为0
下图可以更加直观的查看 各类阈值方法;
3 图像平滑
3.1 均值滤波
均值滤波本质是由一个归一化卷积框完成的。用卷积框覆盖区域所有像素的平均值来代替中心元素。可以使用函数 cv2.blur() 和 cv2.boxFilter() 来完成。
下面是一个5x5的归一化卷积框:
blur = cv2.blur(img, (5,5))
# normalize:核矩阵是否归一化处理的标记,为True进行归一化处理,否则不进行归一化处理,默认值为True;
# ddepth(-1)是处理结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度。
blur = cv2.boxFilter(img, -1, (5,5), normalize=False)
当normalize=True时, cv2.blur() 和 cv2.boxFilter()的结果保持一致,当cv2.boxFilter(normalize=False)时容易发生越界现象,此时数值会取255(白色)。
3.2 高斯滤波
这里需要了解一下高斯分布的基本概念:
又名正太分布,若随机变量X服从一个数学期望为μ、方差为σ2的正态分布,记为N(μ,σ2)。其概率密度函数为正态分布的期望值μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布。
高斯滤波则是把卷积核换成高斯核,简单来说,方框不变,将原来每个方框的值更换为符合高斯分布的,方框中心的值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包。原来的求平均数现在变成求加权平均数。实现的函数是cv2.GaussianBlur()。
# 0是指根据窗口大小(5,5)来计算高斯函数标准差
blur = cv2.GaussianBlur(img, (5,5), 0)
3.3 中值滤波
顾名思义就是用与卷积框对应像素的中值来替代中心像素的值。这个滤波器经常用来去除椒盐噪声。前面的滤波器都是用计算得到的一个新值来取代中心像素的值,而中值滤波是用中心像素周围(也可以使他本身)的值来取代。能有效的去除噪声。
卷积核的大小也应该是一个奇数。
median = cv2.medianBlur(img, 5)
4 小结
下期将继续同步OpenCV形态学转换等内容。