图像阈值与平滑处理
阈值处理
ret, dst = cv2.threshold(src, thresh, maxval, type)
-
src: 输入图,只能输入单通道图像,通常来说为灰度图
-
dst: 输出图
-
thresh: 阈值
-
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
-
type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
-
cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
-
cv2.THRESH_BINARY_INV THRESH_BINARY的反转
-
cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
-
cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
-
cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import cv2 as cv import matplotlib.pyplot as plt cat = cv.imread('cat.jpg', cv.COLOR_BGR2GRAY) ret, thresh1 = cv.threshold(cat, 127, 255, cv.THRESH_BINARY) ret, thresh2 = cv.threshold(cat, 127, 255, cv.THRESH_BINARY_INV) ret, thresh3 = cv.threshold(cat, 127, 255, cv.THRESH_TRUNC) ret, thresh4 = cv.threshold(cat, 127, 255, cv.THRESH_TOZERO) ret, thresh5 = cv.threshold(cat, 127, 255, cv.THRESH_TOZERO_INV) titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [cat, thresh1, thresh2,thresh3, thresh4, thresh5] for i in range(6): plt.subplot(2, 3, i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]), plt.yticks([])
图像平滑
-
均值滤波
均值滤波就是一个简单的平均卷积操作。假设你给的参数是(3, 3),那么他的意思就是用一个3*3大小的核去对图像做卷积,卷积核的值是1。,将他们加起来的值除以总数,在这里是9。然后将归一化的数替换原来的值。
1 | 1 | 1 |
1 | 1 | 1 |
1 | 1 | 1 |
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('lenaNoise.png') cv.imshow('img', img) # 均值滤波 blur = cv.blur(img, (3, 3)) cv.imshow('blur', blur) cv.waitKey(0) cv.destroyAllWindows
下图可以看出均值滤波可以去掉椒盐噪声。
-
方框滤波
方框滤波基本上和均值滤波一样,可以归一化。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('lenaNoise.png') cv.imshow('img', img) # 方框滤波 box = cv.boxFilter(img, -1, (3, 3), normalize = True) cv.imshow('box', box) cv.waitKey(0) cv.destroyAllWindows
可以看出结果和均值滤波一样。下面讲一下函数 box = cv.boxFilter(img, -1, (3, 3), normalize = True)
-1 :表示结果通道数和输入图片通道数保持一致
normalize = True :表示归一化结果再除以总数9。这就是为什么上面的结果和均值滤波一样的原因。
当 box = cv.boxFilter(img, -1, (3, 3), normalize = False)时,表示结果不出以总数。那么他们相加,如果值大于255,就令最后的值等于255.如果值小于255,就令最后的值保持不变。看结果:
-
高斯滤波
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('lenaNoise.png') G = cv.GaussianBlur(img, (5, 5), 0) cv.imshow('G', G) cv.waitKey(0) cv.destroyAllWindows()
cv2.GaussianBlur(img, (5, 5), 1) 这里1代表标准差取1。
高斯滤波的卷积核满足高斯分布,更重视中间的值。
-
中值滤波
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import cv2 as cv img = cv.imread('lenaNoise.png') median = cv.medianBlur(img, 5) cv.imshow('median', median) cv.waitKey(0) cv.destroyAllWindows()
中值滤波,顾名思义,去矩形范围中的中值。
-
将多个结果拼接在一起
np.hstack
res = np.hstack((blur, G, median)) cv.imshow('all', res) cv.waitKey(0) cv.destroyAllWindows()