【论文解读】Referring Camouflaged Object Detection

论文信息

论文题目:Referring Camouflaged Object Detection

论文链接:https://arxiv.org/pdf/2306.07532

代码链接:https://github.com/zhangxuying1004/RefCOD

录用期刊:TPAMI 2025

论文单位:南开大学

ps:下文中为论文翻译及本人解读相结合(一些论文中说的比较清楚的就直接用原话了,有的地方我自己解释了下,也不是照搬原文的)

摘要

我们考虑参考伪装物体检测(Ref-COD)的问题,这是一个新任务,旨在基于一组包含显著目标物体的参考图像分割指定的伪装物体。我们首先组装了一个大规模数据集,称为R2C7K,它包含7K张图像,覆盖现实场景中的64个物体类别。然后,我们开发了一个简单但强大的双分支框架,命名为R2CNet,其中参考分支嵌入来自参考图像的目标物体共同表示,分割分支在共同表示的指导下识别和分割伪装物体。特别地,我们设计了一个参考掩码生成(RMG)模块来生成像素级先验掩码和一个参考特征增强(RFE)模块来增强识别指定伪装物体的能力。广泛的实验表明,我们的Ref-COD方法在分割指定伪装物体和识别目标物体主体方面优于其COD对应方法。我们的代码和数据集公开在https://github.com/zhangxuying1004/RefCOD

引言

引言部分就是介绍了一下COD的背景,但是本文做的"参考-伪装物体检测"其实是一个新的任务或者说一类新方法吧,所以作者在引言中给出的使用场景是:

一个典型例子是探险者寻找特定物种,但大多数物种可能与其他类似物体一起深藏。在这种情况下,如果我们有关于目标的参考信息,寻找过程将变得有方向性且更容易。

emm,这个理由感觉也不是太站得住脚?

但总之:Ref-COD利用参考信息指导指定伪装物体的识别

关键问题在于哪种形式的信息适合作为参考。本文选的是显著物体。理由如下:

现有的方法有基于文本参考的参考表达分割[11],和基于图像参考的少样本分割[12]。

然而,无论是包含指定伪装物体的标注图像,还是现有图像的详细文本描述,其获取过程都耗时费力,阻碍了这些方法向COD的迁移。考虑到网上很容易找到带显著目标的图像,我们提出一个简单问题:我们能否利用突出物体的图像来帮助更好地识别指定伪装物体?

受此问题启发,我们提出一个新颖的Ref-COD基准。我们的意图是利用日益先进的显著物体检测(SOD)研究,从参考图像中获取目标物体的共同表示,用于指导指定伪装物体的分割。图1说明了标准COD与我们Ref-COD之间的任务关系。

具体来说,Ref-COD将COD过程从盲目检测伪装场景中的差异物体,转变为有目的地匹配目标物体。

为了全面研究这一新基准,我们构建了一个大规模数据集,命名为R2C7K,其中包含大量无版权争议的现实场景样本。该数据集的基本信息如下:

1)它包含7K张图像,覆盖64个物体类别;

2)它由两个子集组成,即包含伪装物体的图像组成的Camo子集和包含显著物体的图像组成的Ref子集;

3)Ref子集中每个类别的图像数量固定,而Camo子集中的则不固定。

为了研究参考信息在Ref-COD中的作用,我们设计了一个双分支网络架构,并开发了一个简单但有效的框架,命名为R2CNet。

该框架包括一个参考分支和一个分割分支。

参考分支旨在从包含显著物体的参考图像中捕获目标物体的共同表示,这些表示将用于识别指定伪装物体。

特别地,我们构建了一个参考掩码生成(RMG)模块来生成像素级参考信息。在该模块中,参考分支的共同表示与分割分支的视觉特征在每个位置进行密集比较,以生成参考先验掩码。

然而,即使属于同一类别,伪装物体与显著物体之间可能存在外观差异,这可能增加准确识别伪装物体的难度。为了克服这一缺点,我们采用双源信息融合策略来消除两个信息源之间的差异。

此外,我们还设计了一个参考特征增强(RFE)模块,在参考掩码指导下实现多尺度视觉特征之间的交互,并进一步突出目标物体。

总结而言,本文的贡献可归纳如下:

  • 我们提出了一个新基准,称为Ref-COD。据我们所知,这是首次尝试桥接SOD和COD,并利用显著物体图像分割指定伪装物体。
  • 我们构建了一个大规模数据集,命名为R2C7K,可为Ref-COD研究提供数据基础和更深见解。
  • 我们设计了一个用于Ref-COD研究的新框架,命名为R2CNet,其优异的实验结果表明它为这一新主题提供了有效解决方案。

相关工作

首先介绍COD,然后介绍SOD主,最后描述不同参考信息形式的参考物体分割研究。

前面俩不说了,看下这个参考物体分割

参考物体分割意味着在给定图像中基于某种形式的参考(例如图像和文本)分割视觉物体。

介绍了两种做法:少样本分割和文本参考

少样本分割(FSS)探索基于包含同一类别物体的标注图像指导的物体分割。模型在大量像素标记为基础类的图像(查询集)上训练,并在给定少量标注样本(支持集)的情况下对未见类进行密集像素预测。特别地,大多数现有FSS网络包括两个分支,即支持分支和查询分支,以提取支持图像和查询图像的特征,并实现它们之间的交互。FSS研究的开创性工作由[68]提出,其中支持分支直接预测分割查询分支最后一层的权重。然后,[69]提出掩码平均池化操作以提取代表性支持特征,这被后续工作广泛采用。最近,大量工作[12],[70],[71]在冻结骨干网络上构建强大模块,以提升模型对未见类别的适应性。
参考表达分割(RES)探索基于文本表达的物体分割。RES旨在基于表达分割视觉物体,其网络也采用双分支架构。首个工作由[11]引入,其中视觉和语言特征分别由视觉编码器和语言编码器提取,其拼接用于生成分割掩码。随后,一系列基于多级视觉特征[72]、多模态LSTM[73]、注意力机制[74],[75]、协作网络[76]的方法相继融入RES,以生成高质量结果。此外,[77]采用文本描述作为参考,以丰富图像内容实现更好的固定预测。

在本文中,提出的Ref-COD也属于参考物体分割任务。然而,与现有方法不同,其参考信息的收集不费力。具体来说,它既不需要收集包含目标伪装物体的罕见且难标注图像,也不需要为现有COD数据集标注详细文本描述,这便于学术界和工业界跟进。

数据集

R2C7K数据集包含6,615个样本,覆盖64个类别,其中Camo子集由5,015个样本组成,Ref子集有1,600个样本。注意,该数据集的每个类别包含固定数量的参考图像(即25张),而每个类别中的COD图像数量分布不均。

对于Ref子集,每个类别随机选择20个样本用于训练,剩余5个样本用于测试;对于Camo子集,来自COD10K训练集的样本也用于训练,属于测试集的样本用于测试。来自NC4K的样本随机分配到训练和测试集,以确保这两个划分中每个类别至少包含6个样本。

框架

我们的R2CNet框架的总体架构,由两个分支组成,即绿色的参考分支和橙色的分割分支。在参考分支中,通过将视觉特征与SOD网络生成的前景图进行掩蔽和合并,从图像中获得指定对象的共同表示。在分割分支中,使用编码器最后三层的视觉特征来表示给定的图像。然后,在设计良好的RMG模块中融合并比较这两种特征表示,以生成掩模先验,该先验用于丰富不同尺度之间的视觉特征,以突出我们RFE模块中的伪装目标。最后,将丰富的特征输入解码器以生成最终的分割图。

概述:

  • 输入分为两部分,第一部分是包含伪装物体的图像,记作IcamoI^{camo}Icamo,另一部分包含少量显著目标物体的参考图像,记作IrefI^{ref}Iref,共有K张,{Iiref}i=1K\{I^{ref}i\}^K{i=1}{Iiref}i=1K。其中IcamoI^{camo}Icamo来自数据集的Camo子集,包含指定类别c的伪装物体,同时IrefI^{ref}Iref来自Ref子集,其显著物体属于类别c。
  • Ref-COD的输出是一个二值掩码MsegM^{seg}Mseg,用于IcamoI^{camo}Icamo中类别c的伪装物体。

具体来说:

参考图像分支:

输入图像后,编码器和解码器分别得到两个特征,记作 {Fkref}k=1K\{F_{k}^{ref}\}{k=1}^{K}{Fkref}k=1K和{Mkref}k=1K\{M{k}^{ref}\}_{k=1}^{K}{Mkref}k=1K。把编码器得到的特征称为视觉特征,大小为H32×W32\frac{H}{32} \times \frac{W}{32}32H×32W ,解码器得到的称为前景掩码。

这两个特征,送入MAP模块(masked average pooling ,MAP)

MAP函数是参考分支中的核心操作,用于从参考图像中提取目标物体的共同表示。

首先使用双线性下采样操作Fdown(⋅)\mathcal{F}{\text{down}}(\cdot)Fdown(⋅)对前景掩码 {Mkref}k=1K\{M{k}^{ref}\}_{k=1}^{K}{Mkref}k=1K进行下采样,采样到和视觉特征一样大小H32×W32\frac{H}{32} \times \frac{W}{32}32H×32W,然后与视觉特征逐元素相乘,随后沿空间维度求和,得到掩码区域的聚合特征,最后使用1x1卷积进行通道压缩

最后对FkobjF^{obj}_kFkobj做平均池化,得到最终输出: E∈Rcd×1×1E \in \mathbb{R}^{c_d \times 1 \times 1}E∈Rcd×1×1 是目标物体的嵌入向量,用于指导分割分支定位指定伪装物体。

ps:这一部分是离线计算完成的,作者先对这些显著物体图像进行特征提取,使用的网络是ICON-R,提取完了特征做了MAP计算之后,直接把这些特征存储在本地,在训练网络的过程中直接从本地读取。

复制代码
├── R2C7K  
    ├── Camo  
        ├── train                # training set of camo-subset with 64 categories.  
        └── test                 # tesing set of camo-subset with 64 categories.  
    ├── Ref          
        ├── Images               # all images of ref-subset with 64 categories.
        ├── RefFeat_ICON-R       # all object representations of ref-subset with 64 categories.  
        └── Saliency_ICON-R      # all foreground maps of ref-subset with 64 categories.  

看数据结构,其中RefFeat_ICON-R就是事先存储好的特征,训练时候直接读取。

分割分支:

分割分支也是编码器-解码器结构。

作者在论文中说,这里编码器直接用的resnet50

"事实上,我们发现在所提方案下,即使一个简单的分割网络也能表现良好。因此,采用ResNet-50[84]作为编码器,并选择其后三层的特征作为视觉表示"

解码器也很简单,是一个卷积头,由两个卷积层组成用于识别伪装物体。

重点是,两个新模块,即参考掩码生成(RMG)和参考特征增强(RFE),它们添加在编码器和解码器之间,以利用参考分支的共同表示来显式分割伪装目标。

编码器的后三层特征,记作2 3 4:

这些特征与参考分支的输出一起输入RMG模块,以生成融合特征和参考掩码。

RMG模块

首先是一个8维的相对位置编码:

受多模态融合近期工作[72],[85]的启发,我们通过在共同表示和视觉特征之间执行双源信息融合(DSF),具体来说,视觉特征的每个位置与一个8维嵌入向量拼接,

python 复制代码
def _make_coord(self, batch, height, width):
        xv, yv = torch.meshgrid([torch.arange(0,height), torch.arange(0,width)])
        xv_min = (xv.float()*2 - width)/width
        yv_min = (yv.float()*2 - height)/height
        xv_max = ((xv+1).float()*2 - width)/width
        yv_max = ((yv+1).float()*2 - height)/height
        xv_ctr = (xv_min+xv_max)/2
        yv_ctr = (yv_min+yv_max)/2
        hmap = torch.ones(height, width)*(1./height)
        wmap = torch.ones(height, width)*(1./width)
        coord = torch.autograd.Variable(torch.cat([xv_min.unsqueeze(0), yv_min.unsqueeze(0),\
            xv_max.unsqueeze(0), yv_max.unsqueeze(0),\
            xv_ctr.unsqueeze(0), yv_ctr.unsqueeze(0),\
            hmap.unsqueeze(0), wmap.unsqueeze(0)], dim=0))
        coord = coord.unsqueeze(0).repeat(batch,1,1,1)
        return coord

位置编码直接与视觉特征cat起来,

然后就是仿射变换# y = gamma * x + beta

其中这个gamma和beta呢都是由E生成的(E就是参考分支的特征)

代码:

复制代码
# y = gamma * x + beta
        beta2 = torch.tanh(self.beta_proj2(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x2)
        gamma2 = torch.tanh(self.gamma_proj2(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x2)
        beta3 = torch.tanh(self.beta_proj3(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x3)
        gamma3 = torch.tanh(self.gamma_proj3(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x3)
        beta4 = torch.tanh(self.beta_proj4(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x4)
        gamma4 = torch.tanh(self.gamma_proj4(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x4)
        x2 = self.fusion_process2(F.relu(gamma2 * x2 + beta2))
        x3 = self.fusion_process3(F.relu(gamma3 * x3 + beta3))
        x4 = self.fusion_process4(F.relu(gamma4 * x4 + beta4)) 

然后就是多尺度融合,就是自底向上融合,只不过融合的时候使用的是ConvLSTM

python 复制代码
# MSF
        x4_h, x4_c = self.upsample4(x4), self.upsample4(x4)
        x3_h, x3_c = self.lstmcell43(input_tensor=x3, cur_state=[x4_h, x4_c])
        # print('x3: ', x3_h.shape)

        x3_h, x3_c = self.upsample3(x3_h), self.upsample3(x3_c)
        x2_h, x2_c = self.lstmcell32(input_tensor=x2, cur_state=[x3_h, x3_c])
        # print('x2: ', x2_h.shape)

        return x2_h

融合完了返回一个最上层的特征即可

ConvLSTMCell代码如下:

python 复制代码
# convlstm
class ConvLSTMCell(nn.Module):

    def __init__(self, input_dim, hidden_dim, kernel_size, bias):
        """
        Initialize ConvLSTM cell.
        Parameters
        ----------
        input_dim: int
            Number of channels of input tensor.
        hidden_dim: int
            Number of channels of hidden state.
        kernel_size: (int, int)
            Size of the convolutional kernel.
        bias: bool
            Whether or not to add the bias.
        """

        super(ConvLSTMCell, self).__init__()

        self.input_dim = input_dim
        self.hidden_dim = hidden_dim

        self.kernel_size = kernel_size
        self.padding = kernel_size[0] // 2, kernel_size[1] // 2
        self.bias = bias

        self.conv = nn.Conv2d(in_channels=self.input_dim + self.hidden_dim,
                              out_channels=4 * self.hidden_dim,
                              kernel_size=self.kernel_size,
                              padding=self.padding,
                              bias=self.bias)

    def forward(self, input_tensor, cur_state):
        h_cur, c_cur = cur_state

        combined = torch.cat([input_tensor, h_cur], dim=1)  # concatenate along channel axis

        combined_conv = self.conv(combined)
        cc_i, cc_f, cc_o, cc_g = torch.split(combined_conv, self.hidden_dim, dim=1)
        i = torch.sigmoid(cc_i)
        f = torch.sigmoid(cc_f)
        o = torch.sigmoid(cc_o)
        g = torch.tanh(cc_g)

        c_next = f * c_cur + i * g
        h_next = o * torch.tanh(c_next)

        return h_next, c_next

    def init_hidden(self, batch_size, image_size):
        height, width = image_size
        return (torch.zeros(batch_size, self.hidden_dim, height, width, device=self.conv.weight.device),
                torch.zeros(batch_size, self.hidden_dim, height, width, device=self.conv.weight.device))

这个融合特征就是这个模块的输出。记作FfF^fFf

但是这个模块还有一个输出:参考掩码

看图可以看到还有一个TM, Target Matching操作,就是用来生成参考掩码的

目标匹配(Target Matching)​​模块,通过动态卷积操作计算分割分支特征与参考表示之间的相似度,生成​​参考先验掩码(referring prior mask)​​,为后续特征增强提供定位指导。

具体来说,把参考特征当作卷积核来对视觉特征进行卷积,将卷积结果拼接在一起,然后归一化与激活处理

python 复制代码
# 目标匹配计算
mask = torch.cat([  # 拼接batch内所有样本的结果
    F.conv2d(      # 动态卷积操作
        x2_h[i].unsqueeze(0),   # 融合特征 [1, C, H, W]
        ref_x[i].unsqueeze(0)    # 共同表示 [1, C, 1, 1] 作为卷积核
    ) 
    for i in range(bs)           # 遍历batch中每个样本
], 0)                            # 沿batch维度拼接

# 归一化与激活处理
mask = self.relevance_acti(      # LeakyReLU激活
    self.relevance_norm(mask)     # BatchNorm2d归一化
)

可以看下论文里原话的描述:

他就是说将参考特征与融合特征的每一个位置进行比较,用来生成参考掩膜,记作HmH^mHm。

我的理解就是:这里这个卷积核是1x1的,就是说他和融合特征的每一个位置去进行计算,

RFE模块

参考特征增强模块用于在不同尺度上丰富视觉特征。

具体来说,首先将上一阶段产生的先验掩码 (prior mask,HmH^mHm) 和融合特征 (fusion features,FfF^fFf) 分别调整尺寸至与前述三个特征图(即 {H2j+1×W2j+1}j=24\left\{\frac{H}{2^{j+1}}\times\frac{W}{2^{j+1}}\right\}_{j=2}^{4}{2j+1H×2j+1W}j=24)相同的形状。

然后,将同一尺度上调整尺寸后的掩码和特征图通过拼接 (concatenation) 进行融合。不同尺度的输出特征表示为 {Fjscale}j=24\left\{F_{j}^{\text{scale}}\right\}{j=2}^{4}{Fjscale}j=24(其中 Fjscale∈Rcd×H2j+1×W2j+1F{j}^{\text{scale}}\in R^{c_{d}\times\frac{H}{2^{j+1}}\times\frac{W}{2^{j+1}}}Fjscale∈Rcd×2j+1H×2j+1W),这些特征也被拼接在一起,以增强识别伪装目标的能力。我们将最终增强后的特征表示为 Fenr ∈ Rcd×H8×W8F^{enr}\,\in\,R^{c_{d}\times\frac{H}{8}\times\frac{W}{8}}Fenr∈Rcd×8H×8W。

如PFENet[70]所述,细粒度特征图中的微小目标在下采样过程中可能会变得模糊不清。因此,我们构建了一条跨尺度路径 (cross-scale path, CSP),从精细特征跨越到粗糙特征,以实现它们之间的交互。

此外,为了确保生成的增强特征 FenrF^{enr}Fenr 更加鲁棒,我们还对 {Fjscale}j=24\left\{F_{j}^{scale}\right\}{j=2}^{4}{Fjscale}j=24 施加了监督,其对应的预测图表示为 {Mjscale}j=24\left\{M{j}^{scale}\right\}{j=2}^{4}{Mjscale}j=24(其中 Mjscale∈R1×H×WM{j}^{scale}\in R^{1\times H\times W}Mjscale∈R1×H×W)。

这个增强后的特征,直接降低到1通道,尺寸调整为原始图像大小,就作为预测图了。

具体的细节参考代码中的注释:

python 复制代码
class RFE(nn.Module):
    ''' 
    Referring Feature Enrichment (RFE) Module
    Follow implementation of https://github.com/dvlab-research/PFENet/blob/master/model/PFENet.py
    '''
    def __init__(self, d_model=64):
        super(RFE, self).__init__()

        self.d_model = d_model
        self.pyramid_bins = [44, 22, 11]        # 352 // 8, 352 // 16, 352 // 32

        self.avgpool_list = [nn.AdaptiveAvgPool2d(bin_) for bin_ in self.pyramid_bins if bin_ > 1]

        self.init_merge = []
        self.alpha_conv = []
        self.beta_conv = []
        self.inner_cls = []

        for idx in range(len(self.pyramid_bins)):
            if idx > 0:
                self.alpha_conv.append(nn.Sequential(
                    nn.Conv2d(self.d_model*2, self.d_model, kernel_size=1, stride=1, padding=0, bias=False),
                    nn.BatchNorm2d(self.d_model),
                    nn.ReLU()
                )) 
            self.init_merge.append(nn.Sequential(
                nn.Conv2d(self.d_model + 1, self.d_model, kernel_size=1, padding=0, bias=False),
                nn.BatchNorm2d(self.d_model),
                nn.ReLU(inplace=True),
            ))  
            # 局部特征增强模块:就是两个3x3的卷积                    
            self.beta_conv.append(nn.Sequential(
                nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),
                nn.BatchNorm2d(self.d_model),
                nn.ReLU(inplace=True),
                nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),
                nn.BatchNorm2d(self.d_model),
                nn.ReLU(inplace=True)
            ))            
            self.inner_cls.append(nn.Sequential(
                nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),
                nn.BatchNorm2d(self.d_model),
                nn.ReLU(inplace=True),
                nn.Dropout2d(p=0.1),                 
                nn.Conv2d(self.d_model, 1, kernel_size=1)
            )) 
       
        self.init_merge = nn.ModuleList(self.init_merge) 
        self.alpha_conv = nn.ModuleList(self.alpha_conv)
        self.beta_conv = nn.ModuleList(self.beta_conv)
        self.inner_cls = nn.ModuleList(self.inner_cls)

        self.pyramid_cat_conv = nn.Sequential(
            nn.Conv2d(self.d_model*len(self.pyramid_bins), self.d_model, kernel_size=1, padding=0, bias=False),
            nn.BatchNorm2d(self.d_model),
            nn.ReLU(inplace=True),                          
        )              
        self.conv_block = nn.Sequential(
            nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(self.d_model),
            nn.ReLU(inplace=True),   
            nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(self.d_model),
            nn.ReLU(inplace=True),                             
        )  

    def forward(self, feats, mask):
        '''
        feats: [bs, 64, 44, 44]
        sf: [bs, 1, 44, 44]
        '''

        inner_out_list = [] # 存储各尺度预测结果
        pyramid_feat_list = [] # 存储各尺度处理后的特征
        
        # 多尺度处理循环
        for idx, tmp_bin in enumerate(self.pyramid_bins):
            if tmp_bin <= 1.0: # 这个tmp_bin上面定义了,取值为44、22、11,不可能小于1.0   这里应该是一个拓展,如果小于1.0的话就代表比例,就按照比例计算,实际暂时没用到这个
                bin_ = int(feats.shape[2] * tmp_bin)
                feats_bin = nn.AdaptiveAvgPool2d(bin)(feats)
            else: # 常规下采样(平均池化  并调整到设定的尺寸)
                bin_ = tmp_bin
                feats_bin = self.avgpool_list[idx](feats)
            # 掩码下采样
            mask_bin = F.interpolate(mask, size=(bin_, bin_), mode='bilinear', align_corners=True)
            # 特征+掩码 进行融合
            merge_feat_bin = torch.cat([feats_bin, mask_bin], 1) # 通道拼接
            merge_feat_bin = self.init_merge[idx](merge_feat_bin) # 1×1卷积融合

            if idx >= 1: # 从第二个尺度开始 要额外进行跨尺度融合(当前尺度+上一尺度)
                pre_feat_bin = pyramid_feat_list[idx-1].clone() # 获取上一尺度处理后的特征
                # 上采样至当前尺度尺寸
                pre_feat_bin = F.interpolate(pre_feat_bin, size=(bin_, bin_), mode='bilinear', align_corners=True)
                # 拼接当前特征和上一尺度特征
                rec_feat_bin = torch.cat([merge_feat_bin, pre_feat_bin], 1)
                # 特征融合(1×1卷积)+ 残差连接
                merge_feat_bin = self.alpha_conv[idx-1](rec_feat_bin) + merge_feat_bin  

            # beta_conv:就是过两个3x3的卷积
            merge_feat_bin = self.beta_conv[idx](merge_feat_bin) + merge_feat_bin
            # 辅助预测(多尺度监督)   这里输出一个监督图  
            inner_out_bin = self.inner_cls[idx](merge_feat_bin)
            # 特征上采样(恢复至输入尺寸)
            merge_feat_bin = F.interpolate(merge_feat_bin, size=(feats.size(2), feats.size(3)), mode='bilinear', align_corners=True)
            # # 保存当前尺度结果(中间的监督图)
            inner_out_list.append(inner_out_bin)
            # 保存处理后的特征
            pyramid_feat_list.append(merge_feat_bin)
        
        # 拼接所有尺度的特征  再卷积降通道
        feats_refine = self.pyramid_cat_conv(torch.cat(pyramid_feat_list, 1))
        # 再过俩卷积 + 残差连接
        feats_refine = self.conv_block(feats_refine) + feats_refine  

        return feats_refine, inner_out_list
损失函数

BCE+IoU

但是前面有四个预测图做bce,这里他没有设置权重,就直接相加了

实验

这个实验是这样的,先看前两行,baseline是没有参考信息的,就是编码器-解码器结构,然后逐级融合,得到分割结果。第二行是带参考信息的,可以看到效果好了很多。然后就是,分为了单目标和多目标,来看效果。

下面的都是在现有的方法上去应用参考信息,可以看到效果都有提升。

消融实验


相关推荐
一只小灿灿6 分钟前
前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
前端·opencv·计算机视觉
巴伦是只猫11 分钟前
【机器学习笔记 Ⅲ】4 特征选择
人工智能·笔记·机器学习
好心的小明24 分钟前
【王树森推荐系统】召回11:地理位置召回、作者召回、缓存召回
人工智能·缓存·推荐系统·推荐算法
lishaoan771 小时前
使用tensorflow的线性回归的例子(十二)
人工智能·tensorflow·线性回归·戴明回归
二DUAN帝1 小时前
UE实现路径回放、自动驾驶功能简记
人工智能·websocket·机器学习·ue5·自动驾驶·ue4·cesiumforue
zskj_zhyl2 小时前
AI健康小屋“15分钟服务圈”:如何重构社区健康生态?
大数据·人工智能·物联网
荔枝味啊~2 小时前
相机位姿估计
人工智能·计算机视觉·3d
mozun20202 小时前
激光雷达信号提取方法对比梳理2025.7.8
目标检测·激光雷达·信号提取·gm-apd·滤波算法
陈纬度啊3 小时前
自动驾驶ROS2应用技术详解
人工智能·自动驾驶·unix
开开心心_Every3 小时前
全能视频处理工具介绍说明
开发语言·人工智能·django·pdf·flask·c#·音视频