首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由仿射变换矩阵生成pytorchθ

问由仿射变换矩阵生成pytorchθ
EN

Stack Overflow用户
提问于 2020-05-22 22:36:44
回答 1查看 1.6K关注 0票数 4

我试图在一个3D卷上进行一个严格的+比例转换,但是我似乎不明白torch.nn.functional.affine_grid所需的θ是如何工作的。

我有一个大小的变换矩阵(1,4,4),它是由矩阵平移*尺度*旋转产生的。如果我在例如scipy.ndimage.affine_transform中使用这个矩阵,它就没有问题。但是,相同的矩阵(裁剪为大小(1,3,4))在torch.nn.functional.affine_grid中完全失败。

我已经理解了翻译是如何工作的(范围-1到1),并且通过简单地将值规范化到该范围,我已经确认了翻译矩阵是如何工作的。至于另外两个人,我迷路了。

我尝试单独使用一个基本的缩放矩阵(下面)作为最基本的比较,但是在py手电筒中的结果与the的结果不同。

代码语言:javascript
复制
Scaling = 
[[0.75, 0, 0, 0],
[[0, 0.75, 0, 0],
[[0, 0, 0.75, 0],
[[0, 0, 0, 1]]

如何将(1,4,4)仿射矩阵转换成与torch.nn.functional.affine_grid相同的工作方式?或者,是否有一种方法可以根据变换参数(移位、欧拉角、缩放)生成正确的矩阵?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-23 14:01:22

对于在未来遇到类似问题的人来说,scipy与py手电仿射变换的问题是,scipy应用于(0,0,0)左右的转换,而py手电则在图像/卷的中间应用转换。

例如,让我们以参数为例:

代码语言:javascript
复制
euler_angles = [ea0, ea1, ea2]
translation = [tr0, tr1, tr2]
scale = [sc0, sc1, sc2]

并创建以下转换矩阵:

代码语言:javascript
复制
# Rotation matrix
R_x(ea0, ea1, ea2) = np.array([[1, 0, 0, 0],
                              [0, math.cos(ea0), -math.sin(ea0), 0],
                              [0, math.sin(ea0), math.cos(ea0), 0],
                              [0, 0, 0, 1]])

R_y(ea0, ea1, ea2) = np.array([[math.cos(ea1), 0, math.sin(ea1), 0],
                               [0, 1, 0, 0],
                               [-math.sin(ea1), 0, math.cos(ea1)], 0],
                               [0, 0, 0, 1]])

R_z(ea0, ea1, ea2) = np.array([[math.cos(ea2), -math.sin(ea2), 0, 0],
                               [math.sin(ea2), math.cos(ea2), 0, 0],
                               [0, 0, 1, 0],
                               [0, 0, 0, 1]])

R = R_x.dot(R_y).dot(R_z)

# Translation matrix
T(tr0, tr1, tr2) = np.array([[1, 0, 0, -tr0],
                             [0, 1, 0, -tr1],
                             [0, 0, 1, -tr2],
                             [0, 0, 0, 1]])
# Scaling matrix
S(sc0, sc1, sc2) = np.array([[1/sc0, 0, 0, 0],
                             [0, 1/sc1, 0, 0],
                             [0, 0, 1/sc2, 0],
                             [0, 0, 0, 1]])

如果您有一个体积(100,100,100),围绕卷中心的枕叶转换要求首先将卷的中心移动到(0,0,0),然后在应用S、T和R之后将其移回(50、50、50)。定义:

代码语言:javascript
复制
T_zero = np.array([[1, 0, 0, 50],
                   [0, 1, 0, 50],
                   [0, 0, 1, 50],
                   [0, 0, 0, 1]])

T_centre = np.array([[1, 0, 0, -50],
                     [0, 1, 0, -50],
                     [0, 0, 1, -50],
                     [0, 0, 0, 1]])

因此,中心周围的枕叶变换是:

代码语言:javascript
复制
transform_scipy_centre = T_zero.dot(T).dot(S).dot(R).T_centre

在放电筒中,参数之间存在一些细微的差异。

翻译定义在-1和1之间,它们的顺序也不同。以相同的(100,100,100)卷为例,通过以下方法给出了“火把”中的翻译参数:

代码语言:javascript
复制
# Note the order difference
translation_pytorch = =[tr0_p, tr1_p, tr2_p] = [tr0/50, tr2/50, tr1/50] 
T_p = T(tr0_p, tr1_p, tr2_p)

标度参数的顺序不同: scale_pytorch = sc0_p,sc1_p,sc2_p = sc2,sc0,sc1

代码语言:javascript
复制
 S\_p = S(sc0\_p, sc1\_p, sc2\_p)

欧拉角是最大的区别。要获得等效变换,首先参数为负值,顺序不同:

代码语言:javascript
复制
# Note the order difference
euler_angles_pytorch = [ea0_p, ea1_p, ea2_p] = [-ea0, -ea2, -ea1]
R_x_p = R_x(ea0_p, ea1_p, ea2_p)
R_y_p = R_y(ea0_p, ea1_p, ea2_p)
R_z_p = R_z(ea0_p, ea1_p, ea2_p)

计算旋转矩阵的顺序也不同:#注意阶差R_p = R_x_p.dot(R_z_p).dot(R_y_p)

考虑到所有这些因素,the变换的内容包括:

代码语言:javascript
复制
transform_scipy_centre = T_zero.dot(T).dot(S).dot(R).T_centre

等效于具有以下内容的py手电转换:

代码语言:javascript
复制
transform_pytorch = T_p.dot(S_p).dot(R_p)

我希望这能帮到你!

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

https://stackoverflow.com/questions/61964914

复制
相关文章

相似问题

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