tensor flow lstm 图像 一条直线_【开源计划】图像配准中变形操作(Warp)的pytorch实现...
前言
按照開源計劃的預告,這次我來分享圖像配準流程中的變形操作的代碼實現。首先我們先來回顧一下配準的流程,我們以這篇Unsupervised End-to-end Learning for Deformable Medical Image Registration論文中的流程圖為例,進行說明。該論文提出的配準框架是基于無監督學習的端到端的非剛性圖像配準,配準網絡(registration network)根據輸入的浮動圖像(moving image)與固定圖像(fixed image)預測出變形場(deformation field),然后采樣網格生成器(sampling grid generator)生成規則網格(regular grid),并與變形場結合得到采樣網格(sampling grid),再經過采樣器(sampler)對浮動圖像進行重采樣即得到變形后的圖像(warped image)。其中,從規則網格生成到得到變形后的圖像的過程一般稱為變形(warp,可能翻譯的不夠準確與專業)。另外,這個過程也正是論文Spatial Transformer Networks的思想,只不過最初該論文的應用是在自然圖像的檢測與分類任務上的,后來才被引入到醫學圖像配準上。正是它的引入,使得這種基于無監督學習的圖像配準變得可行。
基于無監督學習的配準模型示意圖?
該流程圖的原始說明引用如下:
值得注意的是,如果要使用基于無監督學習的配準框架,對網絡進行端到端地訓練,就需要依靠論文Spatial Transformer Networks的思想,實現一個可反向梯度計算的重采樣函數,將這個變形操作納入到配準模型框架之中。這個操作的實現對于一般的研究生來說無疑難度是巨大的,很慶幸,pytorch框架提供了一個這樣的函數,稱為grid_sample函數,為研究者們構建Spatial Transformer Networks提供了方便。具體介紹請點擊鏈接,參看pytorch的官方文檔說明。下面我將使用該函數,編寫變形(warp)的函數。
準備
首先,導入依賴包
import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variable?二維圖像變形(Warp)
變形(Warp)的操作內容就是,在初始化的過程中先生成一個與圖像大小相同的網格,即規則網格,如果使用規則網格對圖像變形,則可以得到一個與原始圖像相同的圖像,圖像不發生形變,這個過程的可視化可以參考我的另一篇博客。在調用變形函數時,需要提供兩個參數,一個是原始圖像,一個是變形場(flow-field),將變形場與規則網格相加,然后對原始圖像進行重采樣。代碼的實現,我參考一篇稱為PWC-Net的論文的開源代碼(這里是鏈接)其中的warp函數進行了修改,具體如下:
class Warper2d(nn.Module):def __init__(self, img_size):super(Warper2d, self).__init__()"""warp an image/tensor (im2) back to im1, according to the optical flow # img_src: [B, 1, H1, W1] (source image used for prediction, size 32)img_smp: [B, 1, H2, W2] (image for sampling, size 44)flow: [B, 2, H1, W1] flow predicted from source image pair"""self.img_size = img_sizeH, W = img_size, img_size# mesh grid xx = torch.arange(0, W).view(1,-1).repeat(H,1)yy = torch.arange(0, H).view(-1,1).repeat(1,W)xx = xx.view(1,H,W)yy = yy.view(1,H,W)self.grid = torch.cat((xx,yy),0).float() # [2, H, W]def forward(self, flow, img):grid = self.grid.repeat(flow.shape[0],1,1,1)#[bs, 2, H, W]if img.is_cuda:grid = grid.cuda() # if flow.shape[2:]!=img.shape[2:]: # pad = int((img.shape[2] - flow.shape[2]) / 2) # flow = F.pad(flow, [pad]*4, 'replicate')#max_disp=6, 32->44vgrid = Variable(grid, requires_grad = False) + flow# scale grid to [-1,1] # vgrid[:,0,:,:] = 2.0*vgrid[:,0,:,:]/(W-1)-1.0 #max(W-1,1) # vgrid[:,1,:,:] = 2.0*vgrid[:,1,:,:]/(H-1)-1.0 #max(H-1,1)vgrid = 2.0*vgrid/(self.img_size-1)-1.0 #max(W-1,1)vgrid = vgrid.permute(0,2,3,1) output = F.grid_sample(img, vgrid) # mask = Variable(torch.ones(img.size())).cuda() # mask = F.grid_sample(mask, vgrid) # # mask[mask<0.9999] = 0 # mask[mask>0] = 1return output#*mask三維圖像變形(Warp)
根據二維圖像變形操作的思路,我將其拓展到了三維圖像配準上,以下是實現代碼:
class Warper3d(nn.Module):def __init__(self, img_size):super(Warper3d, self).__init__()"""warp an image, according to the optical flowimage: [B, 1, D, H, W] image for samplingflow: [B, 3, D, H, W] flow predicted from source image pair"""self.img_size = img_sizeD, H, W = img_size# mesh grid xx = torch.arange(0, W).view(1,1,-1).repeat(D,H,1).view(1,D,H,W)yy = torch.arange(0, H).view(1,-1,1).repeat(D,1,W).view(1,D,H,W)zz = torch.arange(0, D).view(-1,1,1).repeat(1,H,W).view(1,D,H,W)self.grid = torch.cat((xx,yy,zz),0).float() # [3, D, H, W]def forward(self, img, flow):grid = self.grid.repeat(flow.shape[0],1,1,1,1)#[bs, 3, D, H, W] # mask = torch.ones(img.size())if img.is_cuda:grid = grid.cuda() # mask = mask.cuda()vgrid = grid + flow# scale grid to [-1,1]D, H, W = self.img_sizevgrid[:,0] = 2.0*vgrid[:,0]/(W-1)-1.0 #max(W-1,1)vgrid[:,1] = 2.0*vgrid[:,1]/(H-1)-1.0 #max(H-1,1)vgrid[:,2] = 2.0*vgrid[:,2]/(D-1)-1.0 #max(H-1,1)vgrid = vgrid.permute(0,2,3,4,1)#[bs, D, H, W, 3] output = F.grid_sample(img, vgrid, padding_mode='border')#, mode='nearest' # mask = F.grid_sample(mask, vgrid)#, mode='nearest' # mask[mask<0.9999] = 0 # mask[mask>0] = 1return output#*mask另外,voxelmorph開源代碼提供了TensorFlow實現的Spatial Transformer Networks,有興趣的可以查看其代碼。
結束語
最后,以上僅供參考,歡迎各位網友批評指正與留言交流。如果對你有幫助,請點贊告訴我呀,我會更有動力寫相關的文章。
想看配準介紹的視頻的同學,請移步我的B站賬號:
Bilibili 萌新up主:愛分享的毛毛Timmy的主頁?space.bilibili.com里面有我的項目介紹視頻,后期也會更新更多內容,請關注我不迷路哦,如果對你有億點點幫助,就多一鍵三連與我互動吧,謝謝~
版權聲明
本文為CSDN博主「愛分享的毛毛Timmy」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:【開源計劃】圖像配準中變形操作(Warp)的pytorch實現_Timmymm的博客-CSDN博客_pytorch deformation
總結
以上是生活随笔為你收集整理的tensor flow lstm 图像 一条直线_【开源计划】图像配准中变形操作(Warp)的pytorch实现...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上技国际战略合作KIC中国,搭建中韩企业
- 下一篇: const int是什么类型_C++的c