Sobel算子是图像边缘检测中最重要的算子之一,该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作2D卷积,即可分别得出横向及纵向的亮度差分近似值。Gx,Gy的值如下所示: 将图像I分别和
G
x
,
G
y
G_x,G_y
Gx,Gy作2D卷积,得到
G
x
′
,
G
y
′
G_x',G_y'
Gx′,Gy′ 图像的每一个像素的横向及纵向梯度近似值可用以下两个公式结合,来计算梯度的大小。
G
=
∣
G
x
′
∣
+
∣
G
y
′
∣
G=|G_x'|+|G_y'|
G=∣Gx′∣+∣Gy′∣
G
=
G
x
′
2
+
G
y
′
2
G=\sqrt{G_x'^2+G_y'^2}
G=Gx′2+Gy′2
计算得到G之后,我们只需要设定一个阈值
G
m
a
x
G_{max}
Gmax(比如说:100,一般来讲0-255左右为宜),若梯度G大于阈值
G
m
a
x
G_{max}
Gmax,则可认为该点是一个边界点。 代码如下:
import torch
from PIL import Image
import numpy as np
#彩色转灰度图:I(x,y) = 0.3 * I_R(x,y) +0.59 * I_G(x,y)+ 0.11 * I_B(x,y),PIL默认读入图片的颜色顺序为RGB
def color2gray(img):
return 0.3*img[:,:,0]+0.59*img[:,:,1]+0.11*img[:,:,2]
def sobel(img,mode,Gmax):
h,w=img.shape
sobel_img=np.zeros((h,w))
Gx=np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
Gy=np.array([[1,2,1],[0,0,0],[-1,-2,-1]])
for i in range(h):
for j in range(w):
tmp1=0
tmp2=0
for kx in range(3):
for ky in range(3):
if i+kx-1>=0 and i+kx-1=0 and j+ky-1Gmax:
sobel_img[i][j]=255
else:
sobel_img[i][j]=0
else:
if np.sqrt(tmp1**2+tmp2**2)>Gmax:
sobel_img[i][j]=255
else:
sobel_img[i][j]=0
return sobel_img
#读取图片
img_PIL = Image.open("test.jpg")
#显示原图
img_PIL.show()
#
img_PIL = np.array(img_PIL)
gray_img=color2gray(img_PIL)
#显示灰度图
image=Image.fromarray(np.uint8(gray_img))
image.show()
#显示sobel检测后的二值化图像
sobel_img=sobel(gray_img,1,127)
image=Image.fromarray(np.uint8(sobel_img))
image.show()
结果展示:
当对精度的要求较高时可以使用
S
c
h
a
r
r
滤
波
器
Scharr滤波器
Scharr滤波器,Scharr滤波器水平方向与竖直方向的核为:
边缘检测的效果如下:
不知为何,效果反而变差了.
去掉了
G
m
a
x
G_{max}
Gmax这个阈值的判断,将范围压缩至[0,255]后直接显示灰度图像,效果明显好了很多: 改进后的代码如下所示:
import torch
from PIL import Image
import numpy as np
#彩色转灰度图:I(x,y) = 0.3 * I_R(x,y) +0.59 * I_G(x,y)+ 0.11 * I_B(x,y),PIL默认读入图片的颜色顺序为RGB
def color2gray(img):
return 0.3*img[:,:,0]+0.59*img[:,:,1]+0.11*img[:,:,2]
def sobel(img,mode,Gmax):
h,w=img.shape
sobel_img=np.zeros((h,w))
Gx=np.array([[-3,0,3],[-10,0,10],[-3,0,3]])
Gy=np.array([[-3,-10,-3],[0,0,0],[3,10,3]])
for i in range(h):
for j in range(w):
tmp1=0
tmp2=0
for kx in range(3):
for ky in range(3):
if i+kx-1>=0 and i+kx-1=0 and j+ky-1Gmax,white,back)
return sobel_img
#读取图片
img_PIL = Image.open("test.jpg")
#显示原图
img_PIL.show()
#
img_PIL = np.array(img_PIL)
gray_img=color2gray(img_PIL)
#显示灰度图
image=Image.fromarray(np.uint8(gray_img))
image.show()
#显示sobel检测后的灰度图像
sobel_img=sobel(gray_img,1,60)
image=Image.fromarray(np.uint8(sobel_img))
image.show()