索贝尔算子(Sobeloperator)主要用于获得数字图像的一阶梯度,是一种离散性差分算子。
套用公式如下:
Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。
Sobel算子作为一种边缘检测算子,那么如何利用Sobel算子构造邻接矩阵呢?
代码如下:
class Sobel(nn.Module):
def __init__(self,in_channel,out_channel):
super(Sobel,self).__init__()
kernel_x = [[-1.0,0.0,1.0],[-2.0,0.0,2.0],[-1.0,0.0,1.0]] #横向Sobel卷积因子
kernel_y = [[-1.0,-2.0,-1.0],[0.0,0.0,0.0],[1.0,2.0,1.0]] #纵向Sobel卷积因子
kernel_x = torch.FloatTensor(kernel_x).expand(out_channel,in_channel,3,3) #将Sobel卷积核个数扩展到out_channel个,卷积核通道扩展到in_channel
kernel_x = kernel_x.type(torch.cuda.FloatTensor) #应该是将张量转到cuda上
kernel_y = torch.cuda.FloatTensor(kernel_y).expand(out_channel,in_channel,3,3)
kernel_y = kernel_y.type(torch.cuda.FloatTensor)
self.weight_x = nn.Parameter(data=kernel_x, requires_grad=False).clone()
self.weight_y = nn.Parameter(data=kernel_y, requires_grad=False).clone()
self.softmax = nn.Softmax()
def forward(self,x):
b,c,h,w = x.size()
sobel_x = F.conv2d(x,self.weight_x,stride=1, padding=1)
sobel_x = torch.abs(sobel_x)
sobel_y = F.conv2d(x,self.weight_y,stride=1, padding=1)
sobel_y = torch.abs(sobel_y)
if c == 1:
sobel_x = sobel_x.view(b, h, -1)
sobel_y = sobel_y.view(b, h, -1).permute(0,2,1)
else:
sobel_x = sobel_x.view(b, c, -1)
sobel_y = sobel_y.view(b, c, -1).permute(0,2,1)
sobel_A = torch.bmm(sobel_x,sobel_y) #水平竖直方向的特征进行点乘
sobel_A = self.softmax(sobel_A)
return sobel_A
利用Sobel卷积因子构造卷积核,使的卷积核对特卷积核的个数和通道数与输入特征匹配,使用水平和竖直方向卷积核对特征图卷积,得到的水平和竖直方向的特征进行点乘,点乘之后的特征进行softmax归一化。