【opencv图像处理】–4. 低、高通滤波,卷积和各种算子

系列所有代码,复制粘贴即可运行。
希望有能力的朋友还是拿C++运行一下。

本节讨论图像的低通滤波(卷积,方盒,中值双边,高斯),高通滤波(Sobel,Scharr,Laplace,canny)

1. 卷积

用卷积核对每个像素做线性运算,最终得到的小图像称作convolved Feature卷积特征

  • 步长:卷积核扫描一次移动的像素单位
  • padding: 对图像做卷积之后,长宽都会变小,padding就是在外围补充0的圈数,结构上类似于HTML中的padding,可以通过公式计算出需要填充0的圈数
  • 卷积核的大小一般都是奇数,padding不好补,另外这种卷积核有中心
  • 卷积核案例:
    cv2.filter2D
import cv2
import numpy as np

cat = cv2.imread('cat.jpeg')

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

dst = cv2.filter2D(cat, -1, kernel)

cv2.imshow('cat', np.vstack((cat, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

2. 方盒滤波与均值滤波

滤波实际是去除噪点变模糊的过程,方盒滤波,卷积核内数值全为1,卷积核外乘一系数a。

  • 方盒滤波 boxFilter()

  • 均值滤波 blur

cat = cv2.imread('cat.jpeg')

dst = cv2.blur(cat, (5,5))

3. 高斯滤波

符合正态分布的概率密度函数,md高斯分布二维的数学公式:
G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x,y) = \frac{1}{2 \pi \sigma^2}e^{-\frac{x^2+y^2}{2\sigma ^2}}G (x ,y )=2 πσ2 1 ​e −2 σ2 x 2 +y 2 ​

  • 高斯滤波就是用符合高斯分布的卷积核对图片进行卷积操作,重点是计算该卷积核(高斯模板)
  • 例3X3卷积核,中间为x,y,上为x,y+1 左为x-1, y(其中x=0, y=0,因为在高斯中心)
  • 归一化:通过高斯函数算出来的值,还要保证加起来值为1,需要除以它们的和,才是最终的高斯模板
  • 有些高斯模板归一化的方法是,卷积核内的值均除以左上角的值,然后取整
  • GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])

  • 选择不同的sigma值会得到不同的平滑效果,sigma越大,平滑效果越明显/也越模糊

dst = cv2.GaussianBlur(cat, (5,5), sigmaX=10)

4. 中值滤波

适合胡椒噪音/椒盐噪声的去除,假设有一个数组,取中位数作为卷积之后的结果即可。

  • opencv的一个坑的地方,东西同样,但是API接口类型不同

dst = cv2.medianBlur(cat,5)

5. 双边滤波

可实现美颜,磨皮效果,是考虑了灰度距离和空间距离的两个高斯函数相乘,保留边缘信息。

  • 灰度距离: 像素与像素之间色阶不连续,像素之差,呈现断崖式下跌(边缘)
  • cv2.bilateralFilter
dst = cv2.bilateralFilter(cat, 7, sigmaColor=20, sigmaSpace=50)

用来找边界,特征提取,对象检测,模式识别等

1. Sobel(索贝尔)算子

边缘:像素值发生跃迁的地方。

  • Sobel算子对图像求一阶导数,值越大说明边缘信号越强烈
  • 沿着宽度和高度两个方向进行,使用水平和垂直两个方向卷积核

dx = cv2.Sobel(cat, -1, dx=1, dy=0, ksize=3)

dy = cv2.Sobel(cat, -1, dx=0, dy=1, ksize=3)

dst = cv2.add(dx, dy)
cv2.imshow('cat_ori', cat)
cv2.imshow('cat_merge', dst)
cv2.imshow('cat', np.vstack((dx, dy)))

2. Scharr(沙尔)算子

  • 当SOBEL的卷积核大小为3时,可能产生明显误差,因为是取导数的近似值;
  • 是对Sobel算子的进化,但是它仅作用于大小为3的内核。与Sobel算子一样快,但结果却更加精确。
  • Scharr算子与Sobel很类似,不过使用了不同的kernel值放大了像素变换的情况
  • Scharr只能求x或y方向的边缘
  • Sobel算子的ksize设置为-1就是Scharr算子
  • Scharr擅长寻找细小的边缘,一般用的较少
dx = cv2.Scharr(cat, -1, 1, 0)
dy = cv2.Scharr(cat, -1, 0, 1)

dst = cv2.add(dx, dy)
cv2.imshow('cat_ori', cat)
cv2.imshow('cat_merge', dst)
cv2.imshow('cat', np.vstack((dx, dy)))

3. Laplace(拉普拉斯)算子

拉普拉斯算子是求二阶导,对于边缘变化的反应更加敏锐。有的无意义的地方数值为0,需要去噪

  • Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
dst = cv2.Laplacian(cat, -1, ksize=3)

4. canny算子

被人认为是最有边缘检测算法,多级边缘检测算法

  • canny边缘检测一般步骤

  • Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])


dst = cv2.Canny(cat, 100, 200)
dst2 = cv2.Canny(cat, 64, 128)

Original: https://blog.csdn.net/Eric_Sober/article/details/126053086
Author: 终问鼎
Title: 【opencv图像处理】–4. 低、高通滤波,卷积和各种算子

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/651710/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球