这篇文章准备了可直接运行的 Python + OpenCV 代码 ,一键对比 Roberts、Prewitt、Sobel 三种边缘检测效果,自带图片读取、显示、保存,复制就能用!
完整代码(直接复制运行)
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# ===================== 1. 读取图像 =====================
# 替换成你的图片路径(支持 jpg/png 等)
img = cv2.imread("test.jpg", 0) # 0 表示灰度图
# ===================== 2. Roberts 算子实现 =====================
def roberts_edge_detect(img):
# Roberts 两个卷积核
kernel_x = np.array([[1, 0],
[0, -1]], dtype=int)
kernel_y = np.array([[0, 1],
[-1, 0]], dtype=int)
# 卷积计算
x = cv2.filter2D(img, cv2.CV_16S, kernel_x)
y = cv2.filter2D(img, cv2.CV_16S, kernel_y)
# 取绝对值 + 融合
abs_x = cv2.convertScaleAbs(x)
abs_y = cv2.convertScaleAbs(y)
roberts = cv2.addWeighted(abs_x, 0.5, abs_y, 0.5, 0)
return roberts
# ===================== 3. Prewitt 算子实现 =====================
def prewitt_edge_detect(img):
# Prewitt 核
kernel_x = np.array([[1,1,1],
[0,0,0],
[-1,-1,-1]], dtype=int)
kernel_y = np.array([[-1,0,1],
[-1,0,1],
[-1,0,1]], dtype=int)
x = cv2.filter2D(img, cv2.CV_16S, kernel_x)
y = cv2.filter2D(img, cv2.CV_16S, kernel_y)
abs_x = cv2.convertScaleAbs(x)
abs_y = cv2.convertScaleAbs(y)
prewitt = cv2.addWeighted(abs_x, 0.5, abs_y, 0.5, 0)
return prewitt
# ===================== 4. Sobel 算子实现(OpenCV 自带)=====================
def sobel_edge_detect(img):
sobel_x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
sobel_y = cv2.Sobel(img, cv2.CV_16S, 0, 1)
abs_x = cv2.convertScaleAbs(sobel_x)
abs_y = cv2.convertScaleAbs(sobel_y)
sobel = cv2.addWeighted(abs_x, 0.5, abs_y, 0.5, 0)
return sobel
# ===================== 5. Canny 算子实现(最优边缘检测,OpenCV 自带)=====================
def canny_edge_detect(img):
# Canny 步骤:高斯滤波降噪 → 梯度计算 → 非极大值抑制 → 双阈值检测
# 高斯滤波(降噪核心)
blurred = cv2.GaussianBlur(img, (3, 3), 0)
# 双阈值设置(minVal=50, maxVal=150,可根据图片调整)
canny = cv2.Canny(blurred, 50, 150)
return canny
# ===================== 6. 执行四种检测 =====================
roberts_img = roberts_edge_detect(img)
prewitt_img = prewitt_edge_detect(img)
sobel_img = sobel_edge_detect(img)
canny_img = canny_edge_detect(img)
# ===================== 7. 显示对比结果 =====================
plt.figure(figsize=(15, 10))
plt.subplot(231), plt.imshow(img, cmap='gray')
plt.title('Original Gray Image'), plt.axis('off')
plt.subplot(232), plt.imshow(roberts_img, cmap='gray')
plt.title('Roberts Edge'), plt.axis('off')
plt.subplot(233), plt.imshow(prewitt_img, cmap='gray')
plt.title('Prewitt Edge'), plt.axis('off')
plt.subplot(234), plt.imshow(sobel_img, cmap='gray')
plt.title('Sobel Edge'), plt.axis('off')
plt.subplot(235), plt.imshow(canny_img, cmap='gray')
plt.title('Canny Edge(最优)'), plt.axis('off')
plt.tight_layout() # 自动调整子图间距,避免标题重叠
plt.show()
# 可选:保存结果
# cv2.imwrite("roberts_result.png", roberts_img)
# cv2.imwrite("prewitt_result.png", prewitt_img)
# cv2.imwrite("sobel_result.png", sobel_img)
# cv2.imwrite("canny_result.png", canny_img)
使用方法
-
把你的图片命名为
test.jpg,和代码放在同一文件夹 -
安装依赖:
pythonpip install opencv-python numpy matplotlib -
直接运行代码,会自动弹出5张对比图:原图、Roberts、Prewitt、Sobel、Canny
效果一眼看懂
-
Roberts :边缘细、对角线准,但噪声多、断断续续
-
Prewitt :边缘连续、比 Roberts 干净,但抗噪一般
-
Sobel :边缘最完整、最平滑、抗噪最强(最常用)
-
Canny:边缘最清晰、噪声最少、定位最准(最优选择),自带降噪,边缘无断裂
总结
-
代码包含手动实现 Roberts、Prewitt + OpenCV 自带 Sobel、Canny,四种算子一键对比
-
运行后直接出5张对比图,直观看到四种算子的效果差异
-
工业项目优先用 Sobel(性价比高),对边缘质量要求极高用 Canny(最优),简单对角线检测用 Roberts