医学图像笔记(六)医学图像坐标变换

计算世界坐标涉及到的图像属性有:

orientation
spacing
origin
世界坐标计算:
[ P x P y P z 1 ] = [ X x Δ i Y x Δ j Z x Δ k S x P y Δ i Y y Δ j Z y Δ k S y P z Δ i Y z Δ j Z z Δ k S z 0 0 0 1 ] [ i j k 1 ] = M [ i j k 1 ] \left[ \begin{matrix} P_x \\ P_y \\ P_z \\ 1 \end{matrix} \right] = \left[ \begin{matrix} X_x \Delta_i&Y_x\Delta_j&Z_x\Delta_k &S_x \\ P_y \Delta_i&Y_y\Delta_j&Z_y\Delta_k&S_y\\ P_z\Delta_i&Y_z\Delta_j&Z_z\Delta_k&S_z \\ 0&0&0&1 \end{matrix} \right]\left[ \begin{matrix} i \\ j \\ k\\ 1 \end{matrix} \right] =M\left[ \begin{matrix} i \\ j \\ k \\ 1 \end{matrix} \right] PxPyPz1=XxΔiPyΔiPzΔi0YxΔjYyΔjYzΔj0ZxΔkZyΔkZzΔk0SxSySz1ijk1=Mijk1

图像坐标计算:
[ i j k 1 ] = M − 1 ⋅ [ P x P y P z 1 ] \left[ \begin{matrix} i \\ j \\ k \\ 1 \end{matrix} \right] = M^{-1}\cdot \left[ \begin{matrix} P_x \\ P_y \\ P_z \\ 1 \end{matrix} \right] ijk1=M1PxPyPz1

/* voxel index to point world position */
void IJK2WP(double* origin,
	double* spacing,
	double* orientation,
	int* ijk, double* wp)
{
	// |x|    | x1*spx y1*spy z1*spz dx|   |i|
	// |y|  = | x2*spx y2*spy z2*spz dy| * |j|
	// |z|	  | x3*spx y3*spy z3*spz dz|   |k|
	// |1|    |  0          0      0  1|   |1|
	double orientation_z[3];
	vtkMath::Cross(orientation, orientation + 3, orientation_z);
	vtkMath::Normalize(orientation_z);

	auto matrix = vtkSmartPointer<vtkMatrix4x4>::New();
	matrix->Identity();
	for (int i = 0; i < 3; i++)
	{
		matrix->SetElement(i, 0, orientation[i] * spacing[0]);
		matrix->SetElement(i, 1, orientation[i + 3] * spacing[1]);
		matrix->SetElement(i, 2, orientation_z[i] * spacing[2]);
		matrix->SetElement(i, 3, origin[i]);
	}
	double index[]{ ijk[0],ijk[1] ,ijk[2] ,1 };
	double* temp = matrix->MultiplyDoublePoint(index);
	wp[0] = temp[0];
	wp[1] = temp[1];
	wp[2] = temp[2];
}

/* point world position to voxel index */
void WP2IJK(double* origin,
	double* spacing,
	double* orientation,
	double* wp, int* ijk)
{
	double orientation_z[3];
	vtkMath::Cross(orientation, orientation + 3, orientation_z);
	vtkMath::Normalize(orientation_z);
	auto matrix = vtkSmartPointer<vtkMatrix4x4>::New();
	matrix->Identity();
	for (int i = 0; i < 3; i++)
	{
		matrix->SetElement(i, 0, orientation[i] * spacing[0]);
		matrix->SetElement(i, 1, orientation[i + 3] * spacing[1]);
		matrix->SetElement(i, 2, orientation_z[i] * spacing[2]);
		matrix->SetElement(i, 3, origin[i]);
	}
	auto invertMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
	vtkMatrix4x4::Invert(matrix, invertMatrix);

	double wp4[]{ wp[0],wp[1],wp[2],1 };
	auto temp = invertMatrix->MultiplyDoublePoint(wp4);
	ijk[0] = temp[0];
	ijk[1] = temp[1];
	ijk[2] = temp[2];
}

参考:医学图像坐标变换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花逐流水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值