系列所有代码,复制粘贴即可运行。
希望有能力的朋友还是拿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/
转载文章受原作者版权保护。转载请注明原作者出处!