附上我的代码,分别是3种方式
第一种:使用scipy库中的一些函数直接调用编写sobel
第二种: 纯手动编写sobel
第三种:直接调用cv2的sobel
import matplotlib.pyplot as plt
import cv2
import numpy as np
from scipy import *
# windows操作系统设置plt正常显示中文
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
#使用scipy卷积进行sobel
def sobel_filter1(img):
sobel_x=np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
sobel_y=np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
Gx=ndimage.convolve(img,sobel_x)
Gy=ndimage.convolve(img,sobel_y)
G = np.hypot(Gx, Gy)
return G
#纯手搓sobel
def sobel_filter2(img):
sp = img.shape
height = sp[0]
weight = sp[1]
sx = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
sy = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
dSobel = np.zeros((height,weight))
Gx = np.zeros(img.shape)
Gy = np.zeros(img.shape)
for i in range(height-2):
for j in range(weight-2):
Gx[i + 1, j + 1] = abs(np.sum(img[i:i + 3, j:j + 3] * sx))
Gy[i + 1, j + 1] = abs(np.sum(img[i:i + 3, j:j + 3] * sy))
dSobel[i+1, j+1] =np.sqrt(Gx[i+1, j+1]**2+Gy[i+1, j+1]**2)
return dSobel
img = cv2.imread(r"C:\Users\Cosine\Desktop\175.jpg", cv2.IMREAD_GRAYSCALE)#cv2尽量全英文路径
#使用plt绘图
fig=plt.figure()
plt.subplots_adjust(wspace=0.3,top=1.3)
plt.subplot(2, 2, 1) # 第一张图片显示在第 1 个子图区域
plt.title("原图")
plt.imshow(img,cmap='gray')
plt.subplot(2, 2, 2)
plt.title("直接调用sobel函数")
# 直接调用cv2.Sobel(src,ddepth,dx,dy):输出图像的深度(cv2.CV_8U、cv2.CV_16U、cv2.CV_32F、cv2.CV_64F),越深保留越多的边缘信息
edge1 = cv2.Sobel(img,cv2.CV_16U,1,1)
plt.imshow(edge1 , cmap='gray')
plt.subplot(2, 2, 3)
title="使用scipy卷积的sobel"
plt.title(title)
edge2=sobel_filter1(img)
plt.imshow(edge2, cmap='gray')
plt.subplot(2, 2, 4)
title="纯手动sobel"
plt.title(title)
edge3=sobel_filter2(img)
plt.imshow(edge3, cmap='gray')
plt.show()
底下两种编写sobel的结果为什么差异这么大
直接调用的结果反而也没有纯手动的好,待求解