OpenCv图像锐化及各种高通滤波

目录

什么是图像锐化以及为什么要进行图像锐化

图像锐化的方法

1.空域滤波的可使用几种方法

1.1梯度法

1.2拉普拉斯算子法

1.3定向滤波法

2.频域方面的高通滤波

2.1理想高通滤波器

2.2巴特沃斯高通滤波器


什么是图像锐化以及为什么要进行图像锐化

是什么?

消除或减弱图像的低频分量从而增强图像中物体的边缘轮廓信息的过程称为图像锐化。

为什么?

在上一节图像平滑处理过程中不仅消除了噪音,也使边缘纹理受到了损失(都是高频分量)。为了突出图像的边缘纹理信息,就可以使用图像锐化处理。

图像锐化的方法

图像锐化可以采用基于空间域的空域滤波的几种锐化方法或者基于频率域的高通滤波来处理。

1.空域滤波的可使用几种方法

1.1梯度法

也称一阶导数法。

 ①梯度的含义:

梯度的方向是方向导数取得最大值的方向,梯度的大小是方向导数的最大值。

方向导数是函数沿着某一方向的导数。(一般在3维函数上理解)

导数是函数在某一点的变化率。(一般在2维函数上理解) 

那么,以上三个概念叠加起来再结合图像后可以简单理解为对于图像某一像素点而言,梯度就是其值变化最快的方向向量。

②罗伯特(Robert)梯度算子

——《数字图像处理》第2版,陈天华编著

简单来说,对于一个像素点的值,用周围4个值交叉相减的绝对值之和代替。

③程序演示,基于Python Opencv

*注意:图片的数据类型一般是uint8,两个uint8的数据相加减经常出现标量溢出的情况,可以使用astype()函数转化为int后再进行运算。

1.自定义方法

###################
#    Robert算子   #
###################

def robert_filter(image):
    h = image.shape[0]
    w = image.shape[1]
    image_new = np.zeros(image.shape, np.uint8)
    for i in range(1, h-1):
        for j in range(1, w-1):
            image_new[i][j] = np.abs(image[i][j].astype(int)-image[i+1][j+1].astype(int)) + np.abs(image[i+1][j].astype(int)-image[i][j+1].astype(int))
    return image_new

2.上篇我们提到的自定义滤波器(cv::filter2D())来实现。

制作Robert交叉算子内核(模板):

kernel_1 = np.array([[-1, 0], [0, 1]], dtype=int)
kernel_2 = np.array([[0, -1], [1, 0]], dtype=int)

# src为源图像
# 前一个绝对值
form1 = cv2.filter2D(src, cv2.CV_16S, kernel_1)
form1 = cv2.convertScaleAbs(form1)

# 后一个绝对值
form2 = cv2.filter2D(src, cv2.CV_16S, kernel_2)
form2 = cv2.convertScaleAbs(form2)

# 两个绝对值相加,得到目标图像dst
dst = cv2.addWeighted(form1, 0.5, form2, 0.5, 0)

1.2拉普拉斯算子法

①数学原理:

 ②程序实现,基于Python Opencv:

跟上一小节一样要么自己定义方法要么使用模板结合filter2D()

1.自定义方法

def laplacian_filter(image):
    h = image.shape[0]
    w = image.shape[1]
    image_new = np.zeros(image.shape, np.uint8)
    for i in range(1, h-1):
        for j in range(1, w-1):
            image_new[i][j] = 4*image[i][j].astype(int) - image[i + 1][j].astype(int) - image[i - 1][j].astype(int) - image[i][j + 1].astype(int) - image[i][j - 1].astype(int) 
    return image_new

2.使用cv::filter()

拉普拉斯算子模板:

 另外再提一下,还可以使用8邻域模板。

# 4邻域模板与8邻域模板
kernel_4 = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]], dtype=int)
kernel_8 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=int)

# src为源图像
form1 = cv2.filter2D(src, cv2.CV_16S, kernel_4)
form2 = cv2.filter2D(src, cv2.CV_16S, kernel_8)

1.3定向滤波法

顾名思义,定向滤波是一种定向锐化的模板,可以对一定方向的物体行迹进行锐化突出

比如河流的走向是从左下角走向右上角,因此可以突出锐化对角方向。

①常用的三种定向滤波模板

 ②程序实现,基于Python Opencv:

kernel_shuiping = np.array([[-1, -1, -1], [2, 2, 2], [-1, -1, -1]], dtype=int)
kernel_duijiao = np.array([[-1, -1, 2], [-1, 2, -1], [2, -1, -1]], dtype=int)
kernel_chuizhi = np.array([[-1, 2, -1], [-1, 2, -1], [-1, 2, -1]], dtype=int)

# src为源图像
shuiping = cv2.filter2D(src, -1, kernel_shuiping)
duijiao = cv2.filter2D(src, -1, kernel_duijiao)
chuizhi = cv2.filter2D(src, -1, kernel_chuizhi)

2.频域方面的高通滤波

学习基于频域方面的高通滤波,那就要先学习频域变换,也就是学习傅里叶变换。

关于频域与傅里叶变换:

假如我们的图像是f(x,y),经过与算子(也称模板)h(x,y) 进行卷积运算后,得到一张原图像中某些特征被强化的新图像g(x,y)。

描述上述这句话的公式是:g(x,y)=f(x,y)*h(x,y)

而这个公式在频域中表示G(x,y)=F(x,y)H(x,y)。G、F、H分别是g、f、h的傅里叶变换。

那么以上帝视角来说,已知f,为了得到g,我们先将f变换为F,再构造滤波器函数H,就可以得到G,最终将G变换回g。

值得注意的是

在操作时,图片刚被变换到频域时,低频集中在一起出现在左上角,为了操作方便,需要将其移到中心。也正是因为这一点,低通滤波器可以制作掩膜屏蔽中心外的即屏蔽高频;高通滤波器可以制作掩膜屏蔽靠近中心的即屏蔽低频。 

另外,傅里叶逆变换回来后,是矢量图,需要转换为标量。

下面来详细介绍几种常见的高通滤波器。

2.1理想高通滤波器

顾名思义,非常理想,直接果断地屏蔽中心低频留下外围高频。

import cv2
import numpy as np

# 以灰度图读出图片
src=cv2.imread('cr7.jpg',0)

# 傅立叶变化
src_dft=cv2.dft(np.float32(src),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将图片中心从左上角移到中心
src_dft_shift=np.fft.fftshift(src_dft)

# 制作掩膜令中心为0,后面才能过滤掉中心低频
rows,cols=src.shape
crow,ccol=int(rows/2),int(cols/2)
mask=np.ones((rows,cols,2),np.uint8)
mask[crow-10:crow+10,ccol-10:ccol+10]=0

# 用掩膜对图像进行处理
src_dft_shift_over=src_dft_shift*mask

#将中心移回左上角
src_dft_shift_over_ishift=np.fft.ifftshift(src_dft_shift_over)

# 傅立叶逆变换
src_dft_shift_over_ishift_idft=cv2.idft(src_dft_shift_over_ishift)

#后续操作,将矢量转换成标量,并映射到合理范围之内
src_dft_shift_over_ishift_idft=cv2.magnitude(src_dft_shift_over_ishift_idft[:,:,0],src_dft_shift_over_ishift_idft[:,:,1])
src_dft_shift_over_ishift_idft=np.abs(src_dft_shift_over_ishift_idft)
src_dft_shift_over_ishift_idft=(src_dft_shift_over_ishift_idft-np.amin(src_dft_shift_over_ishift_idft))/(np.amax(src_dft_shift_over_ishift_idft)-np.amin(src_dft_shift_over_ishift_idft))

cv2.imshow("src",src)
cv2.imshow("image",src_dft_shift_over_ishift_idft)
cv2.waitKey()
cv2.destroyAllWindows()

2.2巴特沃斯高通滤波器

①数学理论:

传递函数H为:

D(u,v)是指点到频域原点的距离。

n为滤波器的阶次。

D0为滤波器的截至频率。一般取D(u,v)最大值的0.5(1/2)或0.707(√2/2)。

②基于Opencv的程序实现:

import cv2
import numpy as np

# 以灰度图读出图片
src=cv2.imread('nqm2.jpg',0)

# 傅立叶变化
src_dft=cv2.dft(np.float32(src),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将图片中心从左上角移到中心
src_dft_shift=np.fft.fftshift(src_dft)

# 制作掩膜,由于计算需要,我们先制作单通道的。
rows,cols=src.shape
crow,ccol=int(rows/2),int(cols/2)
mask=np.zeros((rows,cols),np.float64)

# 先计算点到中心的距离即公式中的D(u,v)
for i in range(rows):
    for j in range(cols):
        mask[i,j] = np.sqrt((i-crow) * (i-crow) + (j-ccol) * (j-ccol))
mask[crow,ccol]= 0.000001

# 求D0
d0 = mask[rows-1,cols-1]*0.5

# 用公式计算值并赋值给掩膜,阶次这里设置为1,可以根据需要来设或者求出来。
for i in range(rows):
    for j in range(cols):
        mask[i,j] = 1 / (1 + np.power(d0.astype(float) / mask[i,j].astype(float), 2 * 1))

# 由于傅里叶变换使图像变为双通道(x+yi),所以掩膜也是要双通道的。
mask = cv2.merge((mask, mask))

# 用掩膜对图像进行处理
src_dft_shift_over=src_dft_shift*mask

#将中心移回左上角
src_dft_shift_over_ishift=np.fft.ifftshift(src_dft_shift_over)

# 傅立叶逆变换
src_dft_shift_over_ishift_idft=cv2.idft(src_dft_shift_over_ishift)

#后续操作,将矢量转换成标量,并映射到合理范围之内
src_dft_shift_over_ishift_idft=cv2.magnitude(src_dft_shift_over_ishift_idft[:,:,0],src_dft_shift_over_ishift_idft[:,:,1])
src_dft_shift_over_ishift_idft=np.abs(src_dft_shift_over_ishift_idft)
src_dft_shift_over_ishift_idft=(src_dft_shift_over_ishift_idft-np.amin(src_dft_shift_over_ishift_idft))/(np.amax(src_dft_shift_over_ishift_idft)-np.amin(src_dft_shift_over_ishift_idft))

cv2.imshow("src",src)
cv2.imshow("image",src_dft_shift_over_ishift_idft)
cv2.waitKey()
cv2.destroyAllWindows()

  • 17
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
OpenCV中提供了多种高通滤波和低通滤波的函数,下面分别介绍其中的几种。 1. 高斯滤波(低通滤波) 高斯滤波是一种常用的低通滤波器,可以通过对信号进行平滑处理来去除高频噪声,保留信号中的低频信息。在OpenCV中,可以使用`cv2.GaussianBlur`函数实现高斯滤波。 ```python blurred = cv2.GaussianBlur(image, (ksize, ksize), sigmaX) ``` 其中,`image`为输入图像,`ksize`为滤波器的大小,`sigmaX`为高斯核的标准差。 2. 拉普拉斯滤波(高通滤波) 拉普拉斯滤波是一种常用的高通滤波器,可以通过增强信号的高频成分来增强图像的边缘信息。在OpenCV中,可以使用`cv2.Laplacian`函数实现拉普拉斯滤波。 ```python laplacian = cv2.Laplacian(image, cv2.CV_32F, ksize) ``` 其中,`image`为输入图像,`cv2.CV_32F`表示输出图像的数据类型为32位浮点数,`ksize`为滤波器的大小。 3. Sobel滤波(高通滤波) Sobel滤波也是一种常用的高通滤波器,它可以通过检测图像中的边缘来增强图像的高频成分。在OpenCV中,可以使用`cv2.Sobel`函数实现Sobel滤波。 ```python sobelx = cv2.Sobel(image, cv2.CV_32F, 1, 0, ksize) sobely = cv2.Sobel(image, cv2.CV_32F, 0, 1, ksize) ``` 其中,`image`为输入图像,`cv2.CV_32F`表示输出图像的数据类型为32位浮点数,`1`和`0`表示对x和y方向进行滤波,`ksize`为滤波器的大小。 总的来说,OpenCV提供了多种高通滤波和低通滤波的函数,具体使用哪种滤波器取决于信号的特性和需要的处理效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东东咚咚东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值