使用centernet进行大规模遥感影像目标检测

        时间又过了好久了。。。这一次我再来更新一下目标检测这一块的内容,为什么要更新这一块呢,主要是看到了YOLOX的发布,晚上11点躺在床上看的,终于看到了一个硬货,旷世科技还是牛逼。。一句话总结,什么Anchor,什么nms,统统不要,直接一把梭,端对端输出结果,最终精度又高,网络又简洁,真是不错。好了,希望不要被旷世的人看见,我这彩虹屁吹的。
       很久很久之前,我就Anchor非常不爽,为什么神经网络这么简洁的东西,要加这么个玩意,不就是让网络训练的更加稳定一些么,这个东西的添加,再某个程度上来说,大大增加了开发难度,容易在编程的时候搞晕头脑,虽然说精度尚可,但是我隐隐约约总感觉这玩意绝对淘汰,所以我一直期待一种真正的工程版的Anchor-Free算法,今天要讲的就是centernet这个网络,我非常喜欢这篇文章,非常简单,非常有效,而且可扩展性有非常的好。
       原理部分我就不多讲了,我们先直接看结果吧
                            
       30张样本,检测出来的飞机还是不错的!
        不知道把它用到大范围上,效果会如何,我用深圳宝安区做了一个测试,影像大小为20000*30000左右,跑了5分钟左右吧,看看效果如何: 
                            

       看看宝安机场如何?

                         

 

      整体来看,效果还是非常不错的,有几个大飞机丢失了,这个是在意料当中,后面把样本扩充一下,加一些新的trick进去,相信应该不错。

      当然这里面还有一些核心算法,我用python代码给大家讲一下,这篇论文里面也有几个需要注意的地方,尤其是用到遥感工程项目里面。
      第一个,groundTruth准备
      这一部分,我们需要准备真值中心点,还有长宽,中心点偏移,这里需要注意一点,就是原始论文里面有这样一句话,--We do not normalize the scale and directly use the raw pixel coordinates. We instead scale the loss by a constant λsize.
       The overall training objective !,意思就是说使用原始的长宽输入到真值里面,然后计算loss,这个实在是太重要了,因为我发现很多知乎公众号里边,他妈的根本就没提这个细节,我就按照很多通用做法,把它scale成一定的比例,当成真值,
结果发现长宽输出会出现负数,这就明显比对了,请使用下面这个代码!!
def get_hw_center(json_path, h, w, scale):
    """
    从json格式中读取目标的宽高和中心点位置
    json_path: json文件的路径
    h:         原始图像的高度
    w:         原始图像的宽度
    scale;    特征图与原图的比例,centernet为1/4
    """
    myObject = []
    with open(json_path, 'r', encoding='utf-8') as f:
        ret_dic = json.load(f)
        imgPath = ret_dic['path']
        target_Obj['imgPath'] = imgPath

        object = (ret_dic['outputs']['object'])
        numObject = len(object)
        print(numObject)

        for i in range(0, numObject):
            obj = object[i]['bndbox']
            xmin = obj['xmin']
            ymin = obj['ymin']
            xmax = obj['xmax']
            ymax = obj['ymax']

            obj_width = np.abs(xmax - xmin)*scale  # 原图中目标的宽度,原版论文无需归一化
            obj_height = np.abs(ymax - ymin)*scale  # 原图中目标的高度,原版论文无需归一化

            centerPoint = [(xmax+xmin)/2*scale, (ymax+ymin) /
                           2*scale]  # 目标在特征图中的中心点坐标
            target_Obj['height'] = np.array(obj_height).copy()
            target_Obj['width'] = np.array(obj_width).copy()
            target_Obj['centerPoint'] = np.array(centerPoint).copy()

            myObject.append(target_Obj.copy())

        return myObject
 
      第二个,网络结构里面更改
      原论文---We modify both ResNets and DLA-34 using deformable convolution layers [12] and use the Hourglass network as is,意思就是说,resnet,DLA,hourglass这些网络,作者在上采样阶段,用了可形变卷积来替换,
这一个可以多说一点,形变卷积可以学习到传统卷积无法学下到的长距离信息。
 
      第三个,损失函数
      这个是最重要的了,我们一定要看原论文,特别注意热图,长宽,中心点偏移三者的权重,论文推荐比例为[1,0.1,1],当然这是实验科学,具体的还要根据各位的自己数据来!
      我们上代码:
class L1Loss(nn.Module):
    """
    L1 loss,论文证明,该loss要比smooth L1 loss要好!
    """

    def __init__(self):
        super(L1Loss, self).__init__()

    def forward(self, pred, mask, target):
        numPoint = mask[:, 0, :, :].float().sum()  # 目标点个数

        loss = F.l1_loss(pred * mask, target * mask,
                         reduction='elementwise_mean')
        return loss/(numPoint+1e-4)

     好吧,先写到这里,下一步我会来更新超大影像的目标检测及相关工程应用上的精度 与效率如何,需要代码请加qq 1044625113。

     用一句话来总结我的想法,只做有用的东西,不做灌水的东西!大家共勉!

posted @ 2021-08-17 15:49  我爱木叶123qq  阅读(483)  评论(0编辑  收藏  举报