文章目录
1.卷积核运算
1.1 2个卷积核运算
分别应用两个卷积核,取两个绝对值结果的逐像素最大值。它的原理也不复杂,就是根据传入的2个卷积核,像素运算后取较大值为当前像素值.
Prewitt / Sobel 等算子用水平核检测垂直边缘、竖直核检测水平边缘,
取最大值可以响应任意方向的边缘,不遗漏。
G(x, y) = max(|G1(x, y)|, |G2(x, y)|)
- python代码
def apply_two_kernels_max(img, kernel1, kernel2, kernel_h, kernel_w, coeff=1.0):
width, height = img.width, img.height
result = Image(width, height)
cx = kernel_w // 2
cy = kernel_h // 2
for y in range(height):
for x in range(width):
acc1 = 0.0
acc2 = 0.0
for ki in range(kernel_h):
for kj in range(kernel_w):
pv = img.get_pixel(x - cx + kj, y - cy + ki)
acc1 += pv * kernel1[ki * kernel_w + kj]
acc2 += pv * kernel2[ki * kernel_w + kj]
v1 = abs(acc1 * coeff)
v2 = abs(acc2 * coeff)
result.set_pixel(x, y, min(255, max(v1, v2)))
return result
1.2 n个卷积核
对 N 个卷积核分别运算,取所有结果绝对值的逐像素最大值
用于 Kirsch 8 方向算子:8 个核各检测一个方向,
取最大响应作为该点的边缘强度。
G(x, y) = max_k |G_k(x, y)|
- ptyon代码
def apply_n_kernels_max(img, kernels, kernel_h, kernel_w, coeff=1.0):
width, height = img.width, img.height
result = Image(width, height)
cx = kernel_w // 2
cy = kernel_h // 2
for y in range(height):
for x in range(width):
max_val = 0.0
for kernel in kernels:
acc = 0.0
for ki in range(kernel_h):
for kj in range(kernel_w):
acc += img.get_pixel(x - cx + kj, y - cy + ki) * kernel[ki * kernel_w + kj]
val = abs(acc * coeff)
if val > max_val:
max_val = val
result.set_pixel(x, y, min(255, max_val))
return result
2. Roberts边缘检测算子
Roberts 边缘检测算子,定位精度高,对噪声敏感,计算简单;适合轮廓清晰的图像。它的计算原理就是
在 2×2 像素窗口中,计算两条对角线方向的差分,近似梯度幅度:
G = sqrt((p0 - p3)² + (p1 - p2)²)
窗口布局:
p0 p1
p2 p3
等价于两个 2×2 卷积核:
Gx (主对角): [ -1 0 ] Gy (副对角): [ 0 -1 ]
[ 0 1 ] [ 1 0 ]
说白了Roberts算子,就是水平核垂直-双向一阶差分,原理简单.
- python代码
def roberts(img):
"""
Roberts 交叉梯度算子
"""
width, height = img.width, img.height
result = Image(width, height)
for y in range(height - 1):
for x in range(width - 1):
p0 = img.get_pixel(x, y) # 左上
p1 = img.get_pixel(x + 1, y) # 右上
p2 = img.get_pixel(x, y + 1) # 左下
p3 = img.get_pixel(x + 1, y + 1) # 右下
gx = p0 - p3 # 主对角差分
gy = p1 - p2 # 副对角差分
gradient = math.sqrt(gx * gx + gy * gy)
result.set_pixel(x, y, min(255, gradient))
return result
- 效果图

3. Prewitt边缘检测算子
它的原理是用 3×3 窗口的行方向和列方向差分之和逼近偏导数,两方向取最大值:
Gy (检测水平边缘): Gx (检测垂直边缘):
-1 -1 -1 -1 0 +1
0 0 0 -1 0 +1
+1 +1 +1 -1 0 +1
G = max(|Gy|, |Gx|)
它的特点是- 等权系数,计算简单;对噪声有一定的平滑效果;对水平/垂直边缘响应强。
- python代码
def prewitt(img):
"""
Prewitt 算子
ky = [ # 检测水平方向灰度变化(Gy)
-1.0, -1.0, -1.0,
0.0, 0.0, 0.0,
1.0, 1.0, 1.0,
]
kx = [ # 检测垂直方向灰度变化(Gx)
-1.0, 0.0, 1.0,
-1.0, 0.0, 1.0,
-1.0, 0.0, 1.0,
]
return apply_two_kernels_max(img, ky, kx, 3, 3, 1.0)
- 效果图

4. Sobel边缘检测算子
它的原理是 在 Prewitt 基础上,对中心行/列赋予 2 倍权重,增强边缘响应:
Gy (检测水平边缘): Gx (检测垂直边缘):
-1 -2 -1 -1 0 +1
0 0 0 -2 0 +2
+1 +2 +1 -1 0 +1
G = max(|Gy|, |Gx|)
它的特点:
中心行/列加倍权重使对边缘的方向性更强,抗噪性优于 Prewitt,
是实际中最常用的一阶微分边缘检测算子。
- python代码
def sobel(img):
ky = [
-1.0, -2.0, -1.0,
0.0, 0.0, 0.0,
1.0, 2.0, 1.0,
]
kx = [
-1.0, 0.0, 1.0,
-2.0, 0.0, 2.0,
-1.0, 0.0, 1.0,
]
return apply_two_kernels_max(img, ky, kx, 3, 3, 1.0)
- 效果图

5. Krisch边缘检测
-
原理
使用 8 个 3×3 卷积核,分别检测 8 个主要方向(N/NE/E/SE/S/SW/W/NW)
的边缘。每个核将 5 个系数 (+5) 放在一侧,其余 8 个系数设为 -3,
中心为 0,使核和为 0(无直流响应)。对每个像素,计算 8 个方向的响应并取最大值,缩放 0.5 防止溢出: G(x, y) = 0.5 × max_k(|G_k|) -
特点:
- 各向异性,能精确检测特定方向的边缘;
- 取 8 个方向的最大值,等效于检测最显著方向的边缘;
- 比 Sobel 对方向性更敏感。
-
python代码
def kirsch(img):
kernels = [
# K1 — 上方 (N)
[ 5.0, 5.0, 5.0,
-3.0, 0.0, -3.0,
-3.0, -3.0, -3.0],
# K2 — 右上 (NE)
[-3.0, 5.0, 5.0,
-3.0, 0.0, 5.0,
-3.0, -3.0, -3.0],
# K3 — 右方 (E)
[-3.0, -3.0, 5.0,
-3.0, 0.0, 5.0,
-3.0, -3.0, 5.0],
# K4 — 右下 (SE)
[-3.0, -3.0, -3.0,
-3.0, 0.0, 5.0,
-3.0, 5.0, 5.0],
# K5 — 下方 (S)
[-3.0, -3.0, -3.0,
-3.0, 0.0, -3.0,
5.0, 5.0, 5.0],
# K6 — 左下 (SW)
[-3.0, -3.0, -3.0,
5.0, 0.0, -3.0,
5.0, 5.0, -3.0],
# K7 — 左方 (W)
[ 5.0, -3.0, -3.0,
5.0, 0.0, -3.0,
5.0, -3.0, -3.0],
# K8 — 左上 (NW)
[ 5.0, 5.0, -3.0,
5.0, 0.0, -3.0,
-3.0, -3.0, -3.0],
]
return apply_n_kernels_max(img, kernels, 3, 3, 0.5)
- 效果图

6. 拉普拉斯算子
-
原理:
二维拉普拉斯算子是各向同性的二阶微分算子:∇²f = ∂²f/∂x² + ∂²f/∂y² 8邻域离散近似(卷积核和为 0,保证对均匀区域响应为零): -1 -1 -1 -1 +8 -1 -1 -1 -1 -
特点:
各向同性,对任意方向边缘响应相同;对噪声敏感;
会在边缘两侧产生正负响应(取绝对值后显示为双边缘)。
“”" -
python代码
def laplacian(img):
"""
Laplacian(拉普拉斯)算子
kernel = [
-1.0, -1.0, -1.0,
-1.0, 8.0, -1.0,
-1.0, -1.0, -1.0,
]
return apply_kernel(img, kernel, 3, 3, 1.0, absolute=True)
- 效果图

7. 高斯-拉普拉斯算子
-
原理:
先用高斯滤波器平滑图像(抑制噪声),再应用拉普拉斯算子检测边缘。
将「高斯平滑 + 拉普拉斯」两步合并为一个 5×5 卷积核(σ ≈ 1.4):-2 -4 -4 -4 -2 -4 0 +8 0 -4 -4 +8 +24 +8 -4 × 0.25 -4 0 +8 0 -4 -2 -4 -4 -4 -2 -
特点:
- 先平滑再微分,比直接拉普拉斯对噪声更鲁棒;
- 5×5 核相比 3×3 具有更大的平滑效果;
- 缩放系数 0.25 用于将输出归一化到合理范围。
-
python代码
def gauss_laplacian(img):
kernel = [
-2.0, -4.0, -4.0, -4.0, -2.0,
-4.0, 0.0, 8.0, 0.0, -4.0,
-4.0, 8.0, 24.0, 8.0, -4.0,
-4.0, 0.0, 8.0, 0.0, -4.0,
-2.0, -4.0, -4.0, -4.0, -2.0,
]
return apply_kernel(img, kernel, 5, 5, 0.25, absolute=True)
- 效果图

2万+

被折叠的 条评论
为什么被折叠?



