Python实现Roberts、Sobel与Laplace算子的图像边缘提取

方予
方予
发布时间:2026-10-11 | 3人浏览过
原创

本文详细解析如何使用Python结合OpenCV与NumPy,手动实现Roberts、Sobel和Laplace三种经典算子进行图像边缘提取。通过遍历像素点并执行矩阵卷积运算,计算梯度幅值或二阶导数,最终将结果转换为uint8格式并显示处理前后的图像对比。

边缘提取的核心原理

图像边缘提取的本质是寻找像素灰度值发生剧烈变化的区域。在数学上,这通常通过计算图像矩阵与特定卷积核(算子)的卷积来实现。具体步骤包括:将图片矩阵与算子进行卷积求和,对卷积结果取绝对值,并将计算出的值存入一个与原图大小相同的矩阵中。最后,为了在屏幕上正确显示,需要将接收卷积和值的矩阵数据类型转换为 uint8。

Roberts 算子实现

Roberts 算子是一种利用局部差分算子寻找边缘的算子,其对具有陡峭的低噪声图像的效果最好。它使用对角线方向的相邻像素之差来近似梯度。

# robert 算子[[-1,-1],[1,1]]
def robert_suanzi(img):
  r, c = img.shape
  r_sunnzi = [[-1,-1],[1,1]]
  for x in range(r):
    for y in range(c):
      if (y + 2 <= c) and (x + 2 <= r):
        imgChild = img[x:x+2, y:y+2]
        list_robert = r_sunnzi*imgChild
        img[x, y] = abs(list_robert.sum())   # 求和加绝对值
  return img

在实现中,我们遍历图像的每个像素点。对于坐标 (x, y),提取其右下角的 2x2 子矩阵 imgChild。将该子矩阵与 Roberts 算子矩阵进行逐元素相乘(在 NumPy 中,列表与数组相乘会触发广播机制),然后求和并取绝对值,结果直接覆盖原图对应位置。

Sobel 算子实现

Sobel 算子结合了高斯平滑和微分求导,对噪声具有平滑作用,能提供较理想的检测效果。它分别计算水平和垂直方向的梯度,然后合成总梯度。

# # sobel算子的实现
def sobel_suanzi(img):
  r, c = img.shape
  new_image = np.zeros((r, c))
  new_imageX = np.zeros(img.shape)
  new_imageY = np.zeros(img.shape)
  s_suanziX = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])   # X方向
  s_suanziY = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])   
  for i in range(r-2):
    for j in range(c-2):
      new_imageX[i+1, j+1] = abs(np.sum(img[i:i+3, j:j+3] * s_suanziX))
      new_imageY[i+1, j+1] = abs(np.sum(img[i:i:i+3, j:j+3] * s_suanziY))
      new_image[i+1, j+1] = (new_imageX[i+1, j+1]*new_imageX[i+1,j+1] + new_imageY[i+1, j+1]*new_imageY[i+1,j+1])**0.5
  # return np.uint8(new_imageX)
  # return np.uint8(new_imageY)
  return np.uint8(new_image) # 无方向算子处理的图像

代码首先初始化用于存储 X 方向、Y 方向以及最终合成结果的矩阵。Sobel 算子包含两个 3x3 的卷积核,分别对应 X 方向和 Y 方向。在双重循环中,提取 3x3 的子图像区域,分别与 X 和 Y 方向的算子进行卷积求和并取绝对值。最终图像的梯度幅值通过公式 sqrt(Gx^2 + Gy^2) 计算得出,最后转换为 uint8 类型返回。

Laplace 算子实现

Laplace 算子是二阶微分算子,对图像中的线条和孤立点比较敏感。常用的 Laplace 模板有两种形式,本文采用其中一种:

# Laplace算子
# 常用的Laplace算子模板 [[0,1,0],[1,-4,1],[0,1,0]]  [[1,1,1],[1,-8,1],[1,1,1]]
def Laplace_suanzi(img):
  r, c = img.shape
  new_image = np.zeros((r, c))
  L_sunnzi = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])   
  # L_sunnzi = np.array([[1,1,1],[1,-8,1],[1,1,1]])   
  for i in range(r-2):
    for j in range(c-2):
      new_image[i+1, j+1] = abs(np.sum(img[i:i+3, j:j+3] * L_sunnzi))
  return np.uint8(new_image)

该函数同样遍历图像,提取 3x3 区域与指定的 Laplace 卷积核进行卷积运算。计算结果取绝对值后存入新矩阵,最终返回转换后的图像。注意,Laplace 算子对噪声非常敏感,通常在实际应用中会先进行高斯平滑处理。

完整运行代码与结果展示

以下代码展示了如何读取灰度图像,并依次应用上述三种算子进行边缘提取,最后通过 OpenCV 窗口显示处理前后的图像。

img = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('image', img)
 
# # robers算子
out_robert = robert_suanzi(img)
cv2.imshow('out_robert_image', out_robert)
 
# sobel 算子
out_sobel = sobel_suanzi(img)
cv2.imshow('out_sobel_image', out_sobel)
 
# Laplace算子
out_laplace = Laplace_suanzi(img)
cv2.imshow('out_laplace_image', out_laplace)
 
cv2.waitKey(0)
cv2.destroyAllWindows()

程序首先读取名为 1.jpg 的图像并转换为灰度模式。随后,分别调用 robert_suanzi、sobel_suanzi 和 Laplace_suanzi 函数处理图像,并将结果在独立的窗口中显示。按任意键关闭窗口。

以上就是Python通过Roberts、Sobel、Laplace算子实现图像边缘提取的详细内容,更多关于Python图像处理资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表