GWC-Net代码阅读

代码中关于网络定义的部分其实还是挺好懂的,所以本文的重点是cancatenation volumegroup-wise volume这部分(建议没有阅读过论文的阅读论文后再看)


1. Cost volume的构建

1.1 在stereo matching中,构建cost volume的步骤:

1)确定一系列离散的假设视差平面
2)将提取的每个视图的 2D 特征warp到假设平面
3)最后融合在一起构建 3D 或 4D cost volume

1.2 双目深度中的warp定义:

由于左右图像都经过校正,坐标映射由x轴方向的偏移量决定:
在这里插入图片描述
其中 Cr(d) 是指视差 d 处右视图的变换 x 轴坐标,而Xl是左视图的源 x 轴坐标。简单地就是说将右图沿x轴移动不同的视差d。


2. GWC网络结构

在这里插入图片描述
看不懂的先看论文


3. Cost volume

group-wise volume提供了特征向量匹配的相似度,而concat volume提供了语义信息作为补充,两者是互补的

下面结合代码理解concat volumegroup-wise volume的具体构建

3.1 Feature volume

Feature volume就是网络结构图中绿色的部分,可以看到它是将三个特征concat起来得到的,这三个特征由三个特征提取块(由卷积层构成)得到,详细见代码中feature_extraction类。

这里主要看这三个输出(l2,l3,l4)的维度,调用size方法可以看到它们都是四维的:B x C x H x W,即:Batch_size x 通道数 x 高 x 宽。然后在C这个维度将它们concat得到feature volume,维度及大小已经在下面的代码中注释。

    def forward(self, x):x = self.firstconv(x)x = self.layer1(x)l2 = self.layer2(x)l3 = self.layer3(l2)l4 = self.layer4(l3)# Batch_size * 通道数 * 高 * 宽# l2: < class 'torch.Tensor'> torch.Size([1, 64, 96, 312])# l3: < class 'torch.Tensor'> torch.Size([1, 128, 96, 312])# l4: < class 'torch.Tensor'> torch.Size([1, 128, 96, 312])gwc_feature = torch.cat((l2, l3, l4), dim=1)# gwc_feature: < class 'torch.Tensor'> torch.Size([1, 320, 96, 312])if not self.concat_feature:return {"gwc_feature": gwc_feature}else:concat_feature = self.lastconv(gwc_feature)return {"gwc_feature": gwc_feature, "concat_feature": concat_feature}

3.2 Group-wise volume

groupwise_correlation函数:分组计算特征的相关性。就是fea1与fea2点乘,然后在通道这个维度resize成num_groups x channels_per_group,然后再在channels_per_group这个维度取均值。

build_gwc_volume函数:这个就是在不同的视差等级上做warp操作,然后调用groupwise_correlation函数。

def groupwise_correlation(fea1, fea2, num_groups):B, C, H, W = fea1.shapeassert C % num_groups == 0channels_per_group = C // num_groups# 在PyTorch中view函数作用为重构张量的维度,相当于numpy中的resize()的功能# mean函数中的参数dim代表在第几维度求平均数# 通道数C = 320,组数num_groups = 40,每组通道数channels_per_group = 8cost = (fea1 * fea2).view([B, num_groups, channels_per_group, H, W]).mean(dim=2) # 在通道这个维度C取平均assert cost.shape == (B, num_groups, H, W)return costdef build_gwc_volume(refimg_fea, targetimg_fea, maxdisp, num_groups):# refimg_fea为左图的feature volume# targetimg_fea为右图的feature volume# 这里的maxdisp = 48,不是192# num_groups = 40B, C, H, W = refimg_fea.shapevolume = refimg_fea.new_zeros([B, num_groups, maxdisp, H, W])for i in range(maxdisp):if i > 0:volume[:, :, i, :, i:] = groupwise_correlation(refimg_fea[:, :, :, i:], targetimg_fea[:, :, :, :-i],num_groups)else:volume[:, :, i, :, :] = groupwise_correlation(refimg_fea, targetimg_fea, num_groups)# 使用 contiguous 方法则会重新开辟一块内存空间保证数据是在逻辑顺序和内存中是一致的,连续内存布局减少了CPU对对内存的请求次数volume = volume.contiguous()return volume

举例

在4维上不好解释,下面将左右图的feature volume看作3维的(也就是Batch_size=1)来举例子:
这里设channels_per_group = 2,就是两个通道作为一组
1. 视差disparity=0:
在这里插入图片描述
2. 视差disparity=1:
视差为1就是红色方框缩小1格,点乘时只有红色方框内的做点乘。
在这里插入图片描述
视差等于其他值时也是一样计算,将结果存在一个5维的volume中(B, num_groups, maxdisp, H, W),不考虑B就是4维。

这里可以看到这个volume中是有很多零的,点乘时只有红色方框内的做点乘,得到的结果W这个维度是比原来小的,所以要用零填充。


3.2 Concatenate volume

concat volume由左右图的feature volume先通过一个卷积减少通道数,然后连接在一起。
由下面的代码知feature volume经过这个卷积后,特征的维度为[1,12,96,312]。

		# concat_feature_channel = 12if self.concat_feature:self.lastconv = nn.Sequential(convbn(320, 128, 3, 1, 1, 1),nn.ReLU(inplace=True),nn.Conv2d(128, concat_feature_channel, kernel_size=1, padding=0, stride=1,bias=False))

然后看build_concat_volume的构建代码,看懂了group-wise volume的构建过程的话,理解这个也就很简单了,就是简单的移位拼接,不理解的话同样看下面的例子。

def build_concat_volume(refimg_fea, targetimg_fea, maxdisp):B, C, H, W = refimg_fea.shape# refimg_fea: < class 'torch.Tensor'> torch.Size([1, 12, 96, 312])volume = refimg_fea.new_zeros([B, 2 * C, maxdisp, H, W])for i in range(maxdisp):if i > 0:volume[:, :C, i, :, i:] = refimg_fea[:, :, :, i:]volume[:, C:, i, :, i:] = targetimg_fea[:, :, :, :-i]else:volume[:, :C, i, :, :] = refimg_feavolume[:, C:, i, :, :] = targetimg_fea# 使用 contiguous 方法则会重新开辟一块内存空间保证数据是在逻辑顺序和内存中是一致的,连续内存布局减少了CPU对对内存的请求次数volume = volume.contiguous()return volume

举例

在4维上不好解释,下面将左右图的feature volume看作3维的(也就是Batch_size=1)来举例子:
1. 视差disparity=0:
在这里插入图片描述
2. 视差disparity=1:
在这里插入图片描述
视差等于其他值时也是一样计算,将结果存在一个4维的volume中(B, C, maxdisp, H, W),不考虑B就是4维。



本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部