首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Matlab中嵌入传输点?

如何在Matlab中嵌入传输点?
EN

Stack Overflow用户
提问于 2015-05-25 11:35:51
回答 1查看 5.2K关注 0票数 3

我正在使用Matlab将图像转换为目标图像。我有几何变换(Tform)。

例如,这是我的“tform”:

代码语言:javascript
复制
    1.0235    0.0022   -0.0607         0
   -0.0276    1.0002    0.0089         0
   -0.0170   -0.0141    1.1685         0
   12.8777    5.0311  -70.0325    1.0000

在Matlab2013中,可以轻松地使用imwarp:

代码语言:javascript
复制
%nii = 3D MR Image
I = nii.img; 
dii=nii.hdr.dime.pixdim(2:4);
Rfixed=imref3d(size(I),dii(2),dii(1),dii(3));    
new_img= imwarp(old_img, Rfixed, tform, 'OutputView', Rfixed);

使用imwarp (图像中的红色肺)效果很好。

我需要知道imwarp是如何工作的,然后我编写了我自己的函数

代码语言:javascript
复制
function [new_img] = aff3d(old_img, tform, range_x, range_y, range_z)

   [U, V, W] = ndgrid(range_x, range_y, range_z);
   xyz = [reshape(U,[],1)';reshape(V,[],1)';reshape(W,[],1)'];
   xyz = [xyz; ones(1,size(xyz,2))];


   uvw = tform.T * xyz;
   % avoid homogeneous coordinate  
   uvw = uvw(1:3,:)';


   xi = reshape(uvw(:,1), length(range_x),length(range_y),length(range_z));
   yi = reshape(uvw(:,2), length(range_x),length(range_y),length(range_z));
   zi = reshape(uvw(:,3), length(range_x),length(range_y),length(range_z));

   old_img = single(old_img);
   new_img = interp3(old_img,yi,xi,zi,'linear');

   ii = find(isnan(new_img));
   if(~isempty(ii))
      new_img(ii) = 0;
   end
end

我的功能(more info)的结果不符合隆升输出(红肺定位不对),有人能帮我吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-26 14:29:27

正如Ander所建议的,尝试乘以逆变换:

代码语言:javascript
复制
Tinv = tform.invert();
TinvMatrix = Tinv.T;

所以你的代码会变成:

代码语言:javascript
复制
function [new_img] = aff3d(old_img, tform, range_x, range_y, range_z)
   [U, V, W] = ndgrid(range_x, range_y, range_z);
   xyz = [reshape(U,[],1)';reshape(V,[],1)';reshape(W,[],1)'];
   xyz = [xyz; ones(1,size(xyz,2))];

   tformInv = invert(tform);
   uvw = tformInv.T * xyz;
   % avoid homogeneous coordinate  
   uvw = uvw(1:3,:)';
   xi = reshape(uvw(:,1), length(range_x),length(range_y),length(range_z));
   yi = reshape(uvw(:,2), length(range_x),length(range_y),length(range_z));
   zi = reshape(uvw(:,3), length(range_x),length(range_y),length(range_z));
   old_img = single(old_img);
   new_img = interp3(old_img,yi,xi,zi,'linear');
   ii = find(isnan(new_img));
   if(~isempty(ii))
      new_img(ii) = 0;
   end
end

在您的代码中,您将在old_img中进行内插,以尝试查找已被扭曲的new_img。这意味着您要做的是使用从输出图像空间映射到输入图像空间的逆映射。您似乎正在使用点的正向映射来插值旧图像,这是不正确的。

http://blogs.mathworks.com/steve/2006/04/28/spatial-transforms-forward-mapping/ http://blogs.mathworks.com/steve/2006/05/05/spatial-transformations-inverse-mapping/

我将使用上面的链接来回顾正向映射和逆映射。IMWARP使用逆映射。

造成混淆的部分原因是,当人们想到几何转换时,他们通常会考虑如何将点从old_image映射到new_image。因此,affine3d转换的"T“属性是根据正向映射来表述的。

当需要在软件中实现几何转换时,用逆映射来实现事物会更容易/更好。这就是imwarp所做的,这也是为什么当您试图复制imwarp行为时,需要反转转换。如果你读了关于逆映射的博客文章,这个算法就是IMWARP所做的。

您需要解决的唯一问题是IMWARP在非默认坐标系(使用非默认的空间引用对象)中所做的工作,在这种情况下,WorldLimits不能被离散的像素网格平均分割。这种行为是武断的,没有“权利”的行为。IMWARP行为是为了满足所请求的分辨率(PixelExtentInWorld),并在这种情况下稍微调整世界限制。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30437467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档