• 挑战图像处理100问(17)——拉普拉斯滤波器


    在这里插入图片描述

    拉普拉斯滤波

    Laplacian滤波器是对图像亮度进行二次微分从而检测边缘的滤波器。由于数字图像是离散的,xx方向和yy方向的一次微分分别按照以下式子计算:
    Ix(x,y)=I(x+1,y)I(x,y)(x+1)x=I(x+1,y)I(x,y)Iy(x,y)=I(x,y+1)I(x,y)(y+1)y=I(x,y+1)I(x,y) I_x(x,y)=frac{I(x+1,y)-I(x,y)}{(x+1)-x}=I(x+1,y)-I(x,y)\ I_y(x,y) =frac{I(x, y+1) - I(x,y)}{(y+1)-y}= I(x, y+1) - I(x,y)
    因此二次微分按照以下式子计算:
    Ixx(x,y)=Ix(x,y)Ix(x1,y)(x+1)x=Ix(x,y)Ix(x1,y)=[I(x+1,y)I(x,y)][I(x,y)I(x1,y)]=I(x+1,y)2 I(x,y)+I(x1,y) egin{aligned} &I_{xx}(x,y) \ =& frac{I_x(x,y) - I_x(x-1,y)}{(x+1)-x} \ =& I_x(x,y) - I_x(x-1,y)\ =&[I(x+1, y) - I(x,y)] - [I(x, y) - I(x-1,y)]\ =& I(x+1,y) - 2 I(x,y) + I(x-1,y) end{aligned}
    同理:
    Iyy(x,y)=I(x,y+1)2 I(x,y)+I(x,y1) I_{yy}(x,y)=I(x,y+1)-2 I(x,y)+I(x,y-1)
    特此,Laplacian 表达式如下:
    2 I(x,y)=Ixx(x,y)+Iyy(x,y)=I(x1,y)+I(x,y1)4I(x,y)+I(x+1,y)+I(x,y+1) egin{aligned} & abla^2 I(x,y)\ =&I_{xx}(x,y)+I_{yy}(x,y)\ =&I(x-1,y) + I(x,y-1) - 4 * I(x,y) + I(x+1,y) + I(x,y+1) end{aligned}
    如果把这个式子表示为卷积核是下面这样的:
    K=[010141010] K= left[ egin{matrix} 0&1&0\ 1&-4&1\ 0&1&0 end{matrix} ight]

    代码实现
    import cv2 # 我只用它来做图像读写和绘图,没调用它的其它函数哦
    import numpy as np # 进行数值计算
    
    # padding 函数
    def padding(img, K_size=3):
    	# img 为需要处理图像
    	# K_size 为滤波器也就是卷积核的尺寸,这里我默认设为3*3,基本上都是奇数
    
    	# 获取图片尺寸
    	H, W, C = img.shape
    
    	pad = K_size // 2 # 需要在图像边缘填充的0行列数,
    	# 之所以我要这样设置,是为了处理图像边缘时,滤波器中心与边缘对齐
    
    	# 先填充行
    	rows = np.zeros((pad, W, C), dtype=np.uint8)
    	# 再填充列
    	cols = np.zeros((H+2*pad, pad, C), dtype=np.uint8)
    	# 进行拼接
    	img = np.vstack((rows, img, rows)) # 上下拼接
    	img = np.hstack((cols, img, cols)) # 左右拼接
    
    	return img
    
    # Prewitt 滤波函数
    def laplacian(img, K_size=3):
    
    	# 获取图像尺寸
    	H, W, C = img.shape
    
    	# 进行padding
    	pad = K_size // 2
    	out = padding(img, K_size=3)
    
    	# 滤波器系数
    	K = np.array([[0., 1., 0.],[1., -4., 1.], [0., 1., 0.]])
    	
    	# 进行滤波
    	tem = out.copy()
    
    	for h in range(H):
    		for w in range(W):
    			for c in range(C):
    				out[pad+h, pad+w, c] = np.sum(K * tem[h:h+K_size, w:w+K_size, c], dtype=np.float)
    
    	out = np.clip(out, 0, 255)
    
    	out = out[pad:pad+H, pad:pad+W].astype(np.uint8)
    
    	return out
    
    # 这里需要把图像先灰度化
    # 直接用之前的灰度化代码
    # 灰度化函数
    def BGR2GRAY(img):
    
    	# 获取图片尺寸
    	H, W, C = img.shape
    
    	# 灰度化
    	out = np.ones((H,W,3))
    	for i in range(H):
    		for j in range(W):
    			out[i,j,:] = 0.299*img[i,j,0] + 0.578*img[i,j,1] + 0.114*img[i,j,2]
    
    	out = out.astype(np.uint8)
    
    	return out
    
    # 读取图片
    path = 'C:/Users/86187/Desktop/image/'
    
    
    file_in = path + 'cake.jpg' 
    file_out = path + 'laplacian_filter.jpg' 
    img = cv2.imread(file_in)
    
    # 调用函数进行灰度化
    img = BGR2GRAY(img)
    # 调用函数进行sobel滤波
    out = laplacian(img)
    
    # 保存图片
    cv2.imwrite(file_out, out)
    cv2.imshow("result", out)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    结果展示
    原图 拉普拉斯提取图像边缘
    在这里插入图片描述 在这里插入图片描述

    laplacian滤波器实现图像的锐化

    由于拉普拉斯是一种微分算子,它的应用可增强图像中灰度突变的区域,减弱灰度的缓慢变化区域。

    因此,锐化处理可选择拉普拉斯算子对原图像进行处理,产生描述灰度突变的图像,再将拉普拉斯图像与原始图像叠加而产生锐化图像:

    g(x,y)=f(x,y)+c[2f(x,y)] g(x, y)=f(x, y)+cleft[ abla^{2} f(x, y) ight]
    其中,f(x,y)f(x,y)为原始图像,g(x,y)g(x,y)为锐化后图像,cc为-1(卷积核中间为负数时,若卷积核中间为正数,则cc为1)。

    代码实现
    import cv2 # 我只用它来做图像读写和绘图,没调用它的其它函数哦
    import numpy as np # 进行数值计算
    
    # padding 函数
    def padding(img, K_size=3):
    	# img 为需要处理图像
    	# K_size 为滤波器也就是卷积核的尺寸,这里我默认设为3*3,基本上都是奇数
    
    	# 获取图片尺寸
    	H, W, C = img.shape
    
    	pad = K_size // 2 # 需要在图像边缘填充的0行列数,
    	# 之所以我要这样设置,是为了处理图像边缘时,滤波器中心与边缘对齐
    
    	# 先填充行
    	rows = np.zeros((pad, W, C), dtype=np.uint8)
    	# 再填充列
    	cols = np.zeros((H+2*pad, pad, C), dtype=np.uint8)
    	# 进行拼接
    	img = np.vstack((rows, img, rows)) # 上下拼接
    	img = np.hstack((cols, img, cols)) # 左右拼接
    
    	return img
    
    # Prewitt 滤波函数
    def laplacian(img, K_size=3):
    
    	# 获取图像尺寸
    	H, W, C = img.shape
    
    	# 进行padding
    	pad = K_size // 2
    	out = padding(img, K_size=3)
    
    	# 滤波器系数
    	K = np.array([[0., 1., 0.],[1., -4., 1.], [0., 1., 0.]])
    	
    	# 进行滤波
    	tem = out.copy()
    
    	for h in range(H):
    		for w in range(W):
    			for c in range(C):
    				out[pad+h, pad+w, c] = (-1)*np.sum(K * tem[h:h+K_size, w:w+K_size, c]) + tem[pad+h, pad+w, c]
    
    	out = np.clip(out, 0, 255)
    
    	out = out[pad:pad+H, pad:pad+W].astype(np.uint8)
    
    	return out
    
    # 这里需要把图像先灰度化
    # 直接用之前的灰度化代码
    # 灰度化函数
    def BGR2GRAY(img):
    
    	# 获取图片尺寸
    	H, W, C = img.shape
    
    	# 灰度化
    	out = np.ones((H,W,3))
    	for i in range(H):
    		for j in range(W):
    			out[i,j,:] = 0.299*img[i,j,0] + 0.578*img[i,j,1] + 0.114*img[i,j,2]
    
    	out = out.astype(np.uint8)
    
    	return out
    
    # 读取图片
    path = 'C:/Users/86187/Desktop/image/'
    
    
    file_in = path + 'cake.jpg' 
    file_out = path + 'laplacian_filter_1.jpg' 
    img = cv2.imread(file_in)
    
    # 调用函数进行灰度化
    img = BGR2GRAY(img)
    # 调用函数进行sobel滤波
    out = laplacian(img)
    
    # 保存图片
    cv2.imwrite(file_out, out)
    cv2.imshow("result", out)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
    
    结果展示
    原图 锐化
    在这里插入图片描述 在这里插入图片描述
  • 相关阅读:
    [译]HTML&CSS Lesson5: 定位
    Emscripten教程之入门指导
    html简单响应式滚动条置顶
    移动web开发问题和优化小结
    React+Webpack+ES6 兼容低版本浏览器(IE9)解决方案
    ECMAScript中有两种属性:数据属性和访问器属性。
    css写作建议和性能优化小结
    validator API文档
    HBase概念学习(九)HTablePool为何弃用?
    leetcode -day 15 Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/Jack-Tim-TYJ/p/12831910.html
Copyright © 2020-2023  润新知