图像阈值
一、ret,dst = cv2.threshold(src, thresh, maxval, type)
-
src:输入图,只输入单通道图像,通常来说是灰度图(也可以是B、G、R)
-
dst:输出图
-
thresh:阈值
-
maxval:当像素值超过了阈值(或者小于阈值,这是由type决定的),所赋予的值,一般是255(白色)
-
type:二值化操作的类型,包括以下五种类型
- cv2.THRESH_BINARY:超过阈值就取maxval,否则取0 ——二元取值
- cv2.THRESH_BINAY_INV:上面的翻转,即不超过的取maxval,超过就0 —— 同样也是二元取值
- cv2.THRESH_TRUNC:超过阈值就设为阈值,否则不变
- cv2.THRESH_TOZERO:超过阈值不变,否则为0
- cv2.THRESH_BINAY_INV:上面的翻转,即超过为0,不超过不变
import cv2
import matplotlib
import matplotlib.pyplot as plt #取别名(用于绘图展示)
import numpy as np #取别名,下面是notepad专用,立即显示图像
%matplotlib inline
def cv_show(name, img): #定义函数用于显示图片,此处name为窗口名,img为cv2调用imread方法的返回值
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img_gray = cv2.imread('sys.jpg', cv2.IMREAD_GRAYSCALE) #彩色图像的可以不加参数,也可加上IMREAD_COLOR
# cv_show('Test', img_gray)
img = cv2.imread('sys.jpg')
cv_show('Test', img)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image','Gray Image','BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, img_gray, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(7):
plt.subplot(2, 4 , i + 1), # 前面是行数,后面是列数,i+1的值应该在 [1 - 行*列] 之间
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
二、图像平滑
- 也就是进行各种滤波操作
- 卷积就是根据邻域像素值得出中心点的像素值
img = cv2.imread('sys.jpg')
cv_show('sys', img)
三、滤波的用法
-
均值滤波(blur):
把包括中心点和D8领域的一共九个像素点的灰度值求平均,命为处理后的中心点值
-
方框滤波(boxFilter):
和均值滤波大致一致,重点在于最后一个参数normalize的取值,若为True则和均值滤波一致,若为False则不会取平均,直接累加,越界就取最大值
-
高斯滤波(GaussianBlur):
卷积核里的数值满足高斯分布,相当于更重视中心像素值,D4领域比较近就赋予更大权值,(D8-D4)领域比较远,权值比较小,最后除数是各权值之和
-
中值滤波(medianBlur):
对N * N个元素进行排序,取中间值为中心点像素值,能一次性把所有噪音点都去除
## 均值滤波
## 简单的平均卷积操作
# 第一个参数是待处理图像,第二个参数是方阵大小(一般奇数)
blur = cv2.blur(img, (3, 3))
cv_show('Blur', blur)
## 方框滤波
## 基本和均值一样,可以选择归一化
#传入-1表示自动计算,normalize的值为True则会归一化(平均)使得结果和均值滤波一致
box = cv2.boxFilter(img, -1, (3, 3), normalize = True)
#若normalize为False,则会累加不会平均,越界出去就直接赋最大值
cv_show('Box', box)
## 方框滤波
## 不进行归一
box = cv2.boxFilter(img, -1, (3, 3), normalize = False)
cv_show('Box', box)
## 高斯滤波
## 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中心值
# 最后一个参数是中心像素值所占权重,会进行矩阵处理
aussian = cv2.GaussianBlur(img, (5, 5), 1)
cv_show('Gassian', aussian)
## 中值滤波
## 相当于使用中值代替
## 非线性操作
median = cv2.medianBlur(img, 5) # 后面参数是矩阵阶数
cv_show('Median', median)
# 拼接所有展示结果
#vstack - vertical, hstack - horizontal
res = np.hstack([blur, aussian, box, median])
print(res)
cv_show('Component', res)
[[[ 8 17 7]
[13 22 12]
[21 30 20]
[57 45 62]
[58 46 63]
[61 46 62]]
...
[[ 3 3 19]
[ 5 5 21]
[16 16 31]
[59 64 67]
[59 62 66]
[59 62 66]]]
## 使用plt
plt.imshow(res)
<matplotlib.image.AxesImage at 0x296bc1d3340>
- 效果演示 从左至右依次为:均值滤波、高斯滤波、无归一化的方框滤波、中值滤波。 归一化的方框和均值效果等价。
def winds(images):
for i in range(len(images)):
images[i] = cv2.resize(images[i], (0, 0), fx = 0.7, fy = 0.7)
# 注意下面这一句的神来之笔
images[i][ :,-2:,:] = 255
res = np.hstack(images)
cv_show('Compare', res)
winds([blur, aussian, box, median])