利用Sobel算子构造图邻接矩阵

索贝尔算子(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归一化。

你可能感兴趣的:(算法,人工智能,pytorch,神经网络)