opencv图像滤波

什么是滤波

图像滤波

  • 图像滤波是图像处理中的一种基本操作,通过卷积操作对图像进行处理,以改变或增强图像的特征。
  • 滤波的目的通常包括去除噪声、平滑图像、增强边缘等。

卷积核

  • 卷积核是滤波过程中使用的一个小矩阵,它在图像上滑动并与图像进行卷积操作,从而产生新的图像。
  • 卷积核的不同形状和数值可以实现不同的滤波效果。

滤波目的

  • 高通滤波:用于强调图像中的高频信息,例如边缘和细节。
  • 低通滤波:用于去除图像中的高频信息,主要用于平滑图像和去噪。
  • 中通滤波:用于获取特定频率范围内的信号。
  • 阻带滤波:用于去除特定频率范围内的信号。

滤波分析

  • 时域分析:直接对信号在时间域上的变化进行分析。
  • 频域分析:通过对信号进行傅里叶变换等操作,将信号转换到频率域,以便更好地理解信号的频率特性。

卷积操作

卷积是通过卷积核与图像之间逐点相乘求和的操作。卷积核是一个小矩阵,通过滑动在图像上与图像每个局部区域进行卷积。

卷积可用于包括平滑锐化,边缘检测等图像处理任务。

# 定义卷积核

kernel = np.ones((3,3),np.float32) /9

# 卷积操作

kernel_img = cv2.filter2D(img,-1,kernel)

kernel: 卷积核,这里是一个3x3的平均滤波器。它是一个二维的数值矩阵,用于在卷积操作中与图像的局部区域进行逐点相乘并求和。在这里,每个元素的值为1/9,是为了对图像进行平均化处理

  • image: 输入图像。
  • -1: 输出图像的深度,设置为-1表示输出图像与输入图像有相同的深度。
  • kernel: 卷积核。

平滑操作

平滑操作是通过卷积核的权重对图像进行平均化,来降低图像的高频噪声,实现图像平滑化。

平滑滤波器:

均值滤波器:

  • 作用:均值滤波器是一种平滑滤波器,用于降低图像中的噪声并平滑图像。它是一种简单的线性滤波器,通过对图像的局部区域取平均值来替代中心像素的值。
  • 操作过程: 对于每个像素,取其周围邻域的像素值的平均值,然后将该平均值赋给中心像素。

高斯滤波器:

  • 作用: 高斯滤波器也是一种平滑滤波器,主要用于去除图像中的噪声和平滑图像。与均值滤波器不同,高斯滤波器对邻域内的像素进行加权平均,权重由高斯分布决定。
  • 操作过程: 对于每个像素,取其周围邻域的像素值进行加权平均,权重由高斯分布确定。中心像素的权重最大,周围像素的权重逐渐减小。

smoothed_img = cv2.GaussianBlur(img,(5,5),0)

  • image: 输入图像。
  • (5, 5): 卷积核的大小,这里是一个5x5的高斯核。
  • 0: 高斯核的标准差,设为0表示使用默认值,由卷积核的大小自动计算。

锐化操作

锐化操作指突出图像中的细节和边缘

锐化滤波器通常包括一些正负值,以增强边缘对比度

sharpened_kernel = np.array([[-1,0,-1],[-1,5,-1],[-1,0,-1]])

sharpened_img = cv2.filter2D(img,-1,sharpened_kernel)

  • image: 输入图像。
  • -1: 输出图像的深度,设置为-1表示输出图像与输入图像有相同的深度。
  • sharpened_kernel: 锐化核,这里是一个锐化滤波器。通过这个核,图像的边缘和细节会更加突出。

梯度操作

梯度操作用于检测图像中的边缘,通过计算图像中每个像素梯度值。

常见使用Sobel滤波器,通过在水平和垂直方向上进行卷积计算梯度。

gra_x = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)

gra_y = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)

gra_mag = np.sqrt(gra_x**2 + gra_y**2)

  • image: 输入图像。
  • cv2.CV_64F: 输出图像的深度,64位浮点数。
  • 1, 0: Sobel核的水平方向导数。
  • 0, 1: Sobel核的垂直方向导数。
  • ksize=3: Sobel核的大小,这里是3x3。
import cv2
import numpy as np



# 读取图像
image = cv2.imread('example_image.jpg', cv2.IMREAD_GRAYSCALE)

# 定义卷积核
kernel = np.ones((3, 3), np.float32) / 9  # 3x3平均滤波器

# 卷积操作
convolved_image = cv2.filter2D(image, -1, kernel)

# 平滑操作 - 高斯滤波
smoothed_image = cv2.GaussianBlur(image, (5, 5), 0)

# 锐化操作
sharpened_image = cv2.filter2D(image, -1, np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]))

# 梯度操作 - Sobel滤波器
gradient_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
gradient_magnitude = np.sqrt(gradient_x**2 + gradient_y**2)

中值滤波和双边滤波

中值滤波(Median Filtering):

  • 任务: 主要用于去除图像中的椒盐噪声或脉冲噪声,这些噪声可能导致图像中出现明显的黑白点。
  • 操作过程: 对图像的每个像素,用它周围邻域中所有像素的中值替代原始像素值。
  • 优点: 对于椒盐噪声效果较好,能够在保留图像边缘信息的同时有效地去除噪声。

双边滤波(Bilateral Filtering):

  • 任务: 主要用于平滑图像,同时保留图像的边缘信息。
  • 操作过程: 双边滤波不仅考虑空间上的邻域关系,还考虑像素值之间的相似性。它在滤波时对邻域内像素的权重进行加权,以保留边缘。
  • 优点: 在去噪的同时,能够有效地保留图像的细节。

# 双边滤波,参数分别为图像,邻域直径,颜色空间标准差,灰度空间标准差
double_img = cv2.bilateralFilter(img,9,75,75)

邻域直径(Diameter of Neighborhood):

  • 作用: 它定义了在滤波过程中考虑的像素邻域的大小。
  • 含义: 邻域直径决定了在空间上对每个像素考虑的周围像素的数量。邻域直径越大,考虑的邻域范围就越广。

颜色空间标准差(Standard Deviation in Color Space):

  • 作用: 它定义了在颜色空间上考虑像素相似性的程度。
  • 含义: 颜色空间标准差控制了在颜色相似性方面的权重。较大的标准差意味着更广泛的颜色范围被考虑,从而使得颜色相差较大的像素在滤波过程中得到较小的权重。

灰度值空间标准差(Standard Deviation in Greyscale Space):

  • 作用: 它定义了在灰度值空间上考虑像素相似性的程度。
  • 含义: 灰度值空间标准差控制了在灰度值相似性方面的权重。较大的标准差意味着更广泛的灰度值范围被考虑,使得灰度相差较大的像素在滤波过程中得到较小的权重。
import cv2 


img = cv2.imread("example.jpg")
# 中值滤波,核大小为5*5
median_img = cv2.medianBlur(img,5)
# 双边滤波,参数分别为图像,邻域直径,颜色空间标准差,灰度空间标准差
double_img = cv2.bilateralFilter(img,9,75,75)

锐化算子

Laplacian锐化

拉普拉斯锐化简单来说,就是依据周围像素灰度带动中心点像素改变。当邻域灰度像素低于其所在领域内其他灰度像素平均值,其中心点灰度像素也会进一步降低;当邻域灰度像素高于其所在领域内其他灰度像素平均值,其中心点灰度像素也会进一步提高。

cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst

参数说明:

  • src:输入图像,可以是灰度图像,也可以是多通道的彩色图像
  • ddepth:输出图片的数据深度:
  • dst:输出图像,大小和类型与 src 相同
  • ksize:计算二阶导数滤波器的孔径大小,必须为正奇数,可选项
  • scale:缩放比例因子,可选项,默认值为 1
  • delta:输出图像的偏移量,可选项,默认值为 0
  • borderType:边界扩充的类型,注意不支持对侧填充(BORDER_WRAP)

同样,拉普拉斯锐化还有种方法,就是依据自定义卷积核。

kernel = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]],np.float32)

lap_img = cv2.filter2D(img,kernel,cv2.CV_64F)

USM锐化

USM(非锐化掩膜),就是先通过低通滤波筛选出低频分量,再用原图减去低频分量得到高频分量,最后将原图加上高频分量叠加就得到了非锐化掩模。

  • 首先使用低通滤波器平滑原图像得到低频分量图像:s = 低通滤波;
  • 原图像减去低频分量图像,产生的差值,高频分量图像称为模板:m = f - s;
  • 将模板图像乘以一个系数,加到原图像中,得到锐化后的图像:g = f + k × m
  • f为原图,k为锐化系数,m为剩下的高频分量。
import cv2
import numpy as np

def unsharp_masking(image, weight=1.5):
    # Step 1: Apply Gaussian blur
    blurred = cv2.GaussianBlur(image, (0, 0), 3)

    # Step 2: Calculate the unsharp mask
    mask = image - blurred

    # Step 3: Enhance edges by adding the mask back to the original image
    sharpened = image + weight * mask

    # Clip pixel values to be in the valid range [0, 255]
    sharpened = np.clip(sharpened, 0, 255).astype(np.uint8)

    return sharpened

# Load an example image
image = cv2.imread('example_image.jpg')

# Convert the image to grayscale (optional, depending on your input)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Apply the unsharp masking
sharpened_image = unsharp_masking(gray_image)

# Display the results
cv2.imshow('Original Image', gray_image)
cv2.imshow('Sharpened Image', sharpened_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2


src = cv2.imread(r"1.jpg")
dst = cv2.GaussianBlur(src, (5, 5), 0)
dst = cv2.addWeighted(src, 2, dst, -1, 0)
cv2.imshow("src show", src)
cv2.imshow("dst show", dst)
cv2.waitKey(0)

改进点:

mask阈值设定abs(mask)->threshold?1:0

梯度算子

以下卷积核的大小是固定的。

Sobel算子和Scharr算子

Sobel Scharr 其实就是求一阶或二阶导数。 Scharr 是对 Sobel (使用小的卷积核求解求解梯度角

度时)的优化。Laplacian 是求二阶导数。

Sobel 算子是高斯平滑与微分操作的结合体,所以它的抗噪声能力很好
Scharr 滤波器是对 Sobel 滤波器的改进版本
Sobel算子是一种常用的梯度算子,用于图像的边缘检测。它分为水平方向和垂直方向两个卷积核,分别用于检测图像在水平和垂直方向上的梯度。
import cv2
import numpy as np

# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)

# 使用Sobel算子进行边缘检测
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)

# 计算合并后的梯度幅值和方向
gradient_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)
gradient_direction = np.arctan2(sobel_y, sobel_x) * (180 / np.pi)

# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Sobel X', sobel_x)
cv2.imshow('Sobel Y', sobel_y)
cv2.imshow('Gradient Magnitude', gradient_magnitude.astype(np.uint8))
cv2.imshow('Gradient Direction', gradient_direction.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

Scharr算子是Sobel算子的一种改进版本,用于更精确地估计图像梯度。Scharr算子对噪声的敏感性较低,相对于Sobel算子,它具有更强的边缘响应,相较于sobel算子,scharr算子也有着自适应的卷积核大小。

import cv2

# 使用Scharr算子进行边缘检测
scharr_x = cv2.Scharr(image, cv2.CV_64F, 1, 0)
scharr_y = cv2.Scharr(image, cv2.CV_64F, 0, 1)

# 计算合并后的梯度幅值和方向
gradient_magnitude_scharr = np.sqrt(scharr_x**2 + scharr_y**2)
gradient_direction_scharr = np.arctan2(scharr_y, scharr_x) * (180 / np.pi)

# 显示结果
cv2.imshow('Scharr X', scharr_x)
cv2.imshow('Scharr Y', scharr_y)
cv2.imshow('Gradient Magnitude (Scharr)', gradient_magnitude_scharr.astype(np.uint8))
cv2.imshow('Gradient Direction (Scharr)', gradient_direction_scharr.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

Laplacian算子

上面锐化部分已经讲过了。

Prewitt算子

Prewitt算子和Roberts算子没有单独函数,他们同时都是自定义卷积核进行计算,Prewitt算子类似于Sobel算子,分为水平和垂直两个方向。Roberts算子采用2*2的卷积核。

import cv2
import numpy as np

# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)

# 使用Prewitt算子进行边缘检测
prewitt_x = cv2.filter2D(image, cv2.CV_64F, np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]]))
prewitt_y = cv2.filter2D(image, cv2.CV_64F, np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]]))

# 计算合并后的梯度幅值和方向
gradient_magnitude_prewitt = np.sqrt(prewitt_x**2 + prewitt_y**2)
gradient_direction_prewitt = np.arctan2(prewitt_y, prewitt_x) * (180 / np.pi)

# 显示结果
cv2.imshow('Prewitt X', prewitt_x)
cv2.imshow('Prewitt Y', prewitt_y)
cv2.imshow('Gradient Magnitude (Prewitt)', gradient_magnitude_prewitt.astype(np.uint8))
cv2.imshow('Gradient Direction (Prewitt)', gradient_direction_prewitt.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

Roberts算子

import cv2
import numpy as np

# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)

# 使用Roberts算子进行边缘检测
roberts_x = cv2.filter2D(image, cv2.CV_64F, np.array([[1, 0], [0, -1]]))
roberts_y = cv2.filter2D(image, cv2.CV_64F, np.array([[0, 1], [-1, 0]]))

# 计算合并后的梯度幅值和方向
gradient_magnitude_roberts = np.sqrt(roberts_x**2 + roberts_y**2)
gradient_direction_roberts = np.arctan2(roberts_y, roberts_x) * (180 / np.pi)

# 显示结果
cv2.imshow('Roberts X', roberts_x)
cv2.imshow('Roberts Y', roberts_y)
cv2.imshow('Gradient Magnitude (Roberts)', gradient_magnitude_roberts.astype(np.uint8))
cv2.imshow('Gradient Direction (Roberts)', gradient_direction_roberts.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 37
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++中使用OpenCV进行图像滤波可以通过调用OpenCV提供的函数来实现。图像滤波是一种常用的图像处理技术,可以用于去除图像中的噪声、平滑图像、边缘检测等。 OpenCV提供了多种图像滤波的函数,常用的包括均值滤波、中值滤波、高斯滤波等。下面我将介绍其中几种常用的图像滤波方法: 1. 均值滤波(平滑滤波): 均值滤波是一种简单的滤波方法,它将图像中每个像素的值替换为其周围像素的平均值。在OpenCV中,可以使用`blur`函数来实现均值滤波。 ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat srcImage = cv::imread("input.jpg"); cv::Mat dstImage; cv::blur(srcImage, dstImage, cv::Size(3, 3)); cv::imshow("Input Image", srcImage); cv::imshow("Output Image", dstImage); cv::waitKey(0); return 0; } ``` 2. 中值滤波: 中值滤波是一种非线性滤波方法,它将图像中每个像素的值替换为其周围像素的中值。中值滤波对于去除椒盐噪声等有很好的效果。在OpenCV中,可以使用`medianBlur`函数来实现中值滤波。 ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat srcImage = cv::imread("input.jpg"); cv::Mat dstImage; cv::medianBlur(srcImage, dstImage, 3); cv::imshow("Input Image", srcImage); cv::imshow("Output Image", dstImage); cv::waitKey(0); return 0; } ``` 3. 高斯滤波: 高斯滤波是一种线性滤波方法,它将图像中每个像素的值替换为其周围像素的加权平均值,权重由高斯函数计算得到。高斯滤波可以有效地平滑图像并保留图像的边缘信息。在OpenCV中,可以使用`GaussianBlur`函数来实现高斯滤波。 ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat srcImage = cv::imread("input.jpg"); cv::Mat dstImage; cv::GaussianBlur(srcImage, dstImage, cv::Size(3, 3), 0); cv::imshow("Input Image", srcImage); cv::imshow("Output Image", dstImage); cv::waitKey(0); return 0; } ``` 以上是几种常用的图像滤波方法的示例代码,你可以根据自己的需求选择合适的滤波方法进行图像处理。如果你有其他关于图像滤波的问题,请继续提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值