Open CV系列学习笔记(六)模糊操作
什么是模糊操作?
模糊操作的作用是在图片时减低噪声。
模糊操作有均值模糊,中值模糊,高斯模糊和自定义模糊
模糊操作的基本原理:
1、基于离散卷积
2、定义好每一个卷积核
3、不同的卷积核得到不同的卷积效果
4、模糊是卷积的一种表象
卷积原理:
一、均值模糊
CV2.BLUR
原型:blur(src, ksize, dst=None, anchor=None, borderType=None)
作用:对图像进行算术平均值模糊
参数:ksize:卷积核的大小。dst,若填入dst,则将图像写入到dst矩阵。borderType:填充方式
假设我们传入的kszie=(ksize_h, ksize_w),那么均值模糊的卷积核就是:
代码:
def blur_demo(image):#均值模糊
dst = cv.blur(image,(5,5))
cv.imshow("blur_demo",dst)
运行结果:
二、中值模糊
CV2.MEDIANBLUR
原型:mediaBlur(src, ksize, dst=None)
作用:对图像进行中值模糊
参数:ksize:卷积核的大小。dst,若填入dst,则将图像写入到dst矩阵。
(其实只是用了类似卷积核的这个矩阵,计算方式就是取中间位置的数)
medianBlur函数,输入的ksize是一个int型整数,不同于blur中的size。它的卷积核是个ksize*ksize的矩阵。
medianBlur中值模糊就是以滑动的方式从原矩阵取出ksize*ksize个数,然后进行排序,结果就是中间位置的数。
代码:
def median_blur_demo(image):#中值模糊(去除椒盐噪声)
dst = cv.medianBlur(image,5)
cv.imshow("median_blur_demo",dst)
结果:
三、自定义模糊
代码:
def custom_blur_demo(image):#自定义模糊
#kernel = np.ones([5,5],np.float32)/25
kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]], np.float32)#图像锐化
dst = cv.filter2D(image,-1,kernel=kernel)
cv.imshow("custom_blur_demo",dst)
运行结果:(图像锐化)
完整代码;
import cv2 as cv
import numpy as np
def blur_demo(image):#均值模糊(去除随机噪声)
dst = cv.blur(image,(5,5))
cv.imshow("blur_demo",dst)
def median_blur_demo(image):#中值模糊(去除椒盐噪声)
dst = cv.medianBlur(image,5)
cv.imshow("median_blur_demo",dst)
def custom_blur_demo(image):#自定义模糊
#kernel = np.ones([5,5],np.float32)/25
kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]], np.float32)#图像锐化
dst = cv.filter2D(image,-1,kernel=kernel)
cv.imshow("custom_blur_demo",dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("E:/picture/3.bmp")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
custom_blur_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
四、自定义模糊
正态分布
正态分布中,越接近中心点,取值越大,越远离中心,取值越小。
计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。正态分布显然是一种可取的权重分配模式。
高斯函数
如何反映出正态分布?则需要使用高函数来实现。
上面的正态分布是一维的,而对于图像都是二维的,所以我们需要二维的正态分布。
正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:
其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。
根据一维高斯函数,可以推导得到二维高斯函数:
有了这个函数 ,就可以计算每个点的权重了。
代码:
import cv2 as cv
import numpy as np
def clamp(pv):
if pv > 255:
return 255
if pv < 0:
return 0
else:
return pv
def gaussian_noise(image):#加入高斯噪声
h,w,c = image.shape
for row in range(h):
for col in range(w):
s = np.random.normal(0,20,3)
b = image[row,col,0] #blue
g = image[row,col,1] #green
r = image[row,col,2] #red
image[row,col,0] = clamp(b+s[0])
image[row,col,1] = clamp(g+s[1])
image[row,col,2] = clamp(r+s[2])
cv.imshow("noise image",image)
print("--------HEllow Python-------")
src = cv.imread("E:/picture/IM_0000.jpg")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",src)
t1 = cv.getTickCount()
gaussian_noise(src)
t2 = cv.getTickCount()
time = (t2-t1)/cv.getTickFrequency()
print("用时 : %s"%(time*1000))
dst = cv.GaussianBlur(src, (5, 5), 0)#高斯滤波
cv.imshow("Gaussian Blur", dst)
cv.waitKey(0)
cv.destroyAllWindows()
结果: