RANSAC-FLOW代码的理解

主要说明demo.py文件的理解,即输入img_source和img_target,使用训练好的模型权重,输出粗匹配结果和神经网络预测的光流匹配结果。

img_source 和 img_target 第三张图片是各区0.5权重加权叠加的结果。

网络分为4部分。netFeatCoarse 使用全卷积进行图特征提取,8倍下采样。netCorr计算相关性,netFlowCoarse预测光流匹配。

netMatch用于计算网络循环损失,训练涉及,这里不涉及。

一、初始化粗匹配模块

参数:

#7 scales, setting ransac parameters
nbScale = 7 #对img-source 进行7个尺度的特征提取
coarseIter = 10000 #RANSAC 算法迭代次数
coarsetolerance = 0.05 #RANSAC 算法参数
minSize = 400 # 图片最小size
imageNet = True # we can also use MOCO feature here
scaleR = 1.2 #用于计算尺度缩放比例

coarseModel = CoarseAlign(nbScale, coarseIter, coarsetolerance, 'Homography', minSize, 1, True, imageNet, scaleR)

初始化:

1使用ResNet-50预训练网络进行特征提取,这里使用到的层到layer3(有些红字是这个代码的显示错误)

 2特征处理设定

3获取多尺度缩放比例list

1.2 就是将原图缩放到1.2倍。

 二 对img_source进行多尺度特征提取

i1指代img_source。

 

1对img_s进行多尺度缩放

 IsList = []
            for i in range(len(self.scaleList)):
                #根据self.scaleList 进行缩放
                #400*self.scaleList[i])
                IsList.append(self.ResizeMaxSize(Is_org, int(self.minSize * self.scaleList[i])))
                #IsList newresize

 

    def ResizeMaxSize(self, I, minSize) :
        # -----------------------#
        #minSize = self.minSize * self.scaleList[i]
        #print('minSize')
        #print(minSize)
        #一次进入一个
        #480 453 426 400 377 355 333
        # -----------------------#
        #first minSize = 480
        #img_I w h 819 614
        #ratio = max 819/480 614/480 = 1.7
        #new_w, new_h = 819/1.7 614/1.7 = 480 352
        #480//16*16 整除16向下取整 再还原 确保是16整数倍
        #ratioW  ratioH = 480/819 352/614 = 0.5860805860805861 0.5732899022801303
        #img_I resize -> 480 352 #PIL.Image.LANCZOS(高质量下采样滤波器)
        w, h = I.size # 819 614  # minSize 480
        ratio = max(w / float(minSize), h / float(minSize)) # 1.7
        new_w, new_h = int(round(w/ ratio)), int(round(h / ratio))
        new_w, new_h = new_w // self.strideNet * self.strideNet , new_h // self.strideNet * self.strideNet #取整除 #16 2^4
        ratioW, ratioH = new_w / float(w), new_h / float(h) # new / orig ratio
        Iresize = I.resize((new_w, new_h), resample=Image.LANCZOS)
        
        return Iresize

缩放后的图片list

 2取出缩放比例=1 的图片。

    self.Is = IsList[len(self.scaleList) // 2]
            # -----------------------#
            # print('self.Is')
            # print(self.Is)
            #self.scaleList = 1 对应的图片
            #<PIL.Image.Image image mode=RGB size=400x288 at 0x122023E1F08>
            # -----------------------#

            # the number of new WH pairs
            self.IsTensor = self.toTensor(self.Is).unsqueeze(0).cuda()
            # -----------------------#
            # print('self.IsTensort.shape')
            # print(self.IsTensor.shape)
            #torch.Size([1, 3, 288, 400])
            # -----------------------#

3对多尺度的图片进行特征提取出,这个过程下采样率是8倍。

            for i in range(len(self.scaleList)) :

                # IsList[i] -> ToTensor() and normalize -> unsqueeze(0) 1 3 w h
                # -> self.net - F.normalize l2正则化

                feat = F.normalize(self.net(self.preproc(IsList[i]).unsqueeze(0).cuda()))
                # -----------------------#
                #print(IsList[i])
                #print('feat')
                # print(feat.shape)
                # torch.Size([1, 1024, 22, 30])
                # torch.Size([1, 1024, 21, 28])
                # torch.Size([1, 1024, 19, 26])
                # torch.Size([1, 1024, 18, 25])
                # torch.Size([1, 1024, 17, 23])
                # torch.Size([1, 1024, 16, 22])
                # torch.Size([1, 1024, 15, 20])
                # -----------------------#

4获取X方向和Y方向的index 

获取X方向和Y方向的索引,+0.5之后缩放到[-1,1]之间。

5把feature在尺度上进行拉伸成w*h ,1024代码channel,batch=1.

三对img_target进行特征提取

 

和上面基本一致,只对img_target进行处理。

    def setTarget(self, It_org) : 
        with torch.no_grad() : 
            self.It = self.ResizeMaxSize(It_org, self.minSize)
            self.ItTensor = self.toTensor(self.It).unsqueeze(0).cuda() # 1 3 288 400
            self.featt = F.normalize(self.net(self.preproc(self.It).unsqueeze(0).cuda()))
            self.Wt, self.Ht = outil.getWHTensor(self.featt)
            # -----------------------#
            #print('featt s', self.featt.shape)
            # torch.Size([1, 1024, 18, 25])
            # -----------------------#
            # print('self.Wt.shape and self.Ht.shape')
            # print(self.Wt.shape, self.Ht.shape)
            #torch.Size([450]) torch.Size([450])
            # -----------------------#

四 对ItTensor进行特征提取得到featt,featt在预测光流匹配时使用。

五 初始化光流匹配的grid用于之后计算求得光流匹配结果

 

 六使用getCoarse获取变换的参数矩阵

1获取余弦相识度最大的坐标的索引 

 

1计算两个feature的余弦相似度的到score矩阵 

2计算两个维度的top1

3把两个温度余弦最大的值结合 得到匹配的点。

4取得index

def mutualMatching(featA, featB) :
    # -----------------------#
    # print('featA.shape', featA.shape) #torch.Size([1024, 3235])
    # print('featB.shape', featB.shape) #torch.Size([1024, 450])
    # -----------------------#
    score = torch.mm(featA.transpose(0, 1), featB) #nbA * nbB 矩阵相乘 余弦相似度
    # -----------------------#
    # print('score.shape', score.shape) #torch.Size([3235, 450])
    # -----------------------#

    maxDim0, maxDim0Index = score.topk(k=1, dim = 0) # 1 * nbB
    maxDim1, maxDim1Index = score.topk(k=1, dim = 1) # nbA * 1
    # -----------------------#
    # maxDim0, maxDim0Index torch.Size([1, 450])
    # maxDim1, maxDim1Index torch.Size([3235, 1])
    # -----------------------#
    keepMaxDim0 = torch.zeros((featA.size(1), featB.size(1)), device=featA.device).scatter_(0, maxDim0Index, maxDim0)
    keepMaxDim1 = torch.zeros((featA.size(1), featB.size(1)), device=featA.device).scatter_(1, maxDim1Index, maxDim1)
    # print('keepMaxDim0', keepMaxDim0.shape) torch.Size([3235, 450])
    # print('keepMaxDim1', keepMaxDim1.shape) torch.Size([3235, 450])

    keepMax = keepMaxDim0 * keepMaxDim1
    keepMaxIndex = (keepMax > 0).nonzero()
    #print(keepMaxIndex)
    index1, index2 = keepMaxIndex[:, 0], keepMaxIndex[:, 1]
    return index1, index2 #x index y index

 2match1和match2包含上一步求得的匹配点的index。这步是使用RANSAC求得匹配的点。

返回变换参数矩阵bestParam。 和 进一步优化的匹配点的index。

 七根据求得的bestPara获取粗匹配关系,之后对原图使用粗匹配变换的到粗匹配后的结果。

F.grid_sample是一种采样插值变换方式。

 I1_coarse 是粗匹配变换后的feature,把它转换成图片就可以可视化了。

 

---

Fine Alignment

把粗匹配变换后的feature进行进一步优化。

---

把粗匹配变换后的feature放进下采样8倍的网络进行特征提取。

 九 

 输入上面提到的featt和featSample

输出两个feature的相关性

---

先对y进行padding处理,扩大尺度。

y与x长宽对应关系:y_w = x_w + 6, y_h = x_h+6。 

之后计算相关性coef

当i=0,j=0时 x与y左上角w*h大小的feature进行乘积计算 求得相关性。

遍历后得到49组相关性。

 十

把coef输入到netFlowCoarse网络中进一步优化

 1网络设定x方向的flowgrid 和 Y方向的flowgrid 形状都是1 49 1 1

 2

网络进行特征提取把相关性特征变成形状1 49 36 50 的feature

3把两个方向的gridflow与x进行乘积最后求得预测的flow。

之后进行线性上采样还原到 1 2 288 400大小

论文说不用反卷积是因为反卷积影响模型性能占用内存。

 

十一

 

网络预测的匹配关系flowdown8 -> flowup  + 上面的初始化的grid 作为预测的光流匹配结果。

使用F.grid_sample以粗匹配形状进行插值采样计算得到flow12 (这一步是叠加两个匹配?不太理解)

之后对IsTesor进行预测的flow变换得到光流匹配结果。

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值