public VolumeHeaderData(IList<IDicomAttributeProvider> sourceSops,
		                        Size3D arrayDimensions,
		                        Vector3D voxelSpacing,
		                        Vector3D volumePositionPatient,
		                        Matrix3D volumeOrientationPatient,
		                        int bitsAllocated,
		                        int bitsStored,
		                        bool isSigned,
		                        int paddingValue,
		                        double rescaleSlope,
		                        double rescaleIntercept,
		                        RescaleUnits rescaleUnits,
		                        string laterality = null)
		{
			Platform.CheckForNullReference(sourceSops, "sourceSops");
			Platform.CheckTrue(sourceSops.Count > 0, "At least one sourceSop is required");
			Platform.CheckForNullReference(arrayDimensions, "arrayDimensions");
			Platform.CheckForNullReference(voxelSpacing, "voxelSpacing");
			Platform.CheckForNullReference(volumePositionPatient, "originPatient");
			Platform.CheckForNullReference(volumeOrientationPatient, "orientationPatient");

			_volumeOrientationPatient = volumeOrientationPatient;

			var firstSop = sourceSops[0];
			ArrayDimensions = arrayDimensions;
			VoxelSpacing = voxelSpacing;
			VolumePositionPatient = volumePositionPatient;
			VolumeOrientationPatientX = volumeOrientationPatient.GetRow(0);
			VolumeOrientationPatientY = volumeOrientationPatient.GetRow(1);
			VolumeOrientationPatientZ = volumeOrientationPatient.GetRow(2);
			Modality = firstSop[DicomTags.Modality].ToString();
			SourceStudyInstanceUid = firstSop[DicomTags.StudyInstanceUid].ToString();
			SourceSeriesInstanceUid = firstSop[DicomTags.SeriesInstanceUid].ToString();
			FrameOfReferenceUid = firstSop[DicomTags.FrameOfReferenceUid].ToString();
			BitsPerVoxel = bitsAllocated;
			Signed = isSigned;
			PaddingValue = paddingValue;
			RescaleSlope = rescaleSlope;
			RescaleIntercept = rescaleIntercept;
			RescaleUnits = rescaleUnits ?? RescaleUnits.None;
			Laterality = laterality ?? string.Empty;
			VolumeSize = new Vector3D(ArrayDimensions.Width*VoxelSpacing.X, ArrayDimensions.Height*VoxelSpacing.Y, ArrayDimensions.Depth*VoxelSpacing.Z);
			VolumeBounds = new Rectangle3D(new Vector3D(0, 0, 0), VolumeSize);
			VolumeCenter = 0.5f*VolumeBounds.Size;
			VolumeCenterPatient = ConvertToPatient(VolumeCenter);

			// populate the DICOM data set
			FillDataSet(_collection, sourceSops, bitsAllocated, bitsStored, isSigned, rescaleSlope, rescaleIntercept, laterality);
		}
		public Matrix3D RotateToVolumeOrientation(Matrix3D patientOrientation)
		{
			return VolumeHeaderData.RotateToVolumeOrientation(patientOrientation);
		}
		public static void Rotate(this Matrix m, Matrix3D rotation)
		{
			var r = rotation != null ? rotation.Augment() : Matrix.GetIdentity(4);
			m.Set(r*m);
		}
		/// <summary>
		/// Gets a rotation matrix that, when multiplied by a column matrix representing a
		/// position vector in patient coordinates, will rotate the position vector
		/// into a coordinate system matching that of the image plane.
		/// </summary>
		/// <returns>The rotation matrix, or null if the <see cref="Frame"/>'s position information is invalid.</returns>
		private Matrix3D GetRotationMatrix()
		{
			if (_rotationMatrix == null)
			{
				if (ImageOrientationPatient.IsNull)
					return null;

				var normal = GetNormalVector();
				if (normal == null || normal.IsNull)
					return null;

				_rotationMatrix = new Matrix3D();
				_rotationMatrix.SetRow(0, (float) ImageOrientationPatient.RowX, (float) ImageOrientationPatient.RowY, (float) ImageOrientationPatient.RowZ);
				_rotationMatrix.SetRow(1, (float) ImageOrientationPatient.ColumnX, (float) ImageOrientationPatient.ColumnY, (float) ImageOrientationPatient.ColumnZ);
				_rotationMatrix.SetRow(2, normal);
			}

			return _rotationMatrix;
		}
Exemple #5
0
		/// <summary>
		/// Gets a value indicating whether or not the elements of <paramref name="left"/> are equal to <paramref name="right"/> within the given absolute tolerance.
		/// </summary>
		/// <exception cref="ArgumentException">If the matrices do not have the same dimensions.</exception>
		public static bool AreEqual(Matrix3D left, Matrix3D right, float tolerance)
		{
			for (int row = 0; row < 3; ++row)
			{
				for (int column = 0; column < 3; ++column)
				{
					if (!FloatComparer.AreEqual(left[row, column], right[row, column], tolerance))
						return false;
				}
			}

			return true;
		}
Exemple #6
0
		/// <summary>
		/// Performs matrix multiplication of <paramref name="left"/> and <paramref name="right"/>.
		/// </summary>
		public static Matrix3D operator *(Matrix3D left, Matrix3D right)
		{
			Matrix3D result = new Matrix3D();

			for (int row = 0; row < 3; ++row)
			{
				for (int column = 0; column < 3; ++column)
				{
					float value = 0F;

					for (int k = 0; k < 3; ++k)
						value = value + left[row, k]*right[k, column];

					result[row, column] = value;
				}
			}

			return result;
		}
Exemple #7
0
		/// <summary>
		/// Returns a matrix that is the transpose of this matrix.
		/// </summary>
		public Matrix3D Transpose()
		{
			Matrix3D transpose = new Matrix3D();

			for (int row = 0; row < 3; ++row)
			{
				for (int column = 0; column < 3; ++column)
					transpose[column, row] = this[row, column];
			}

			return transpose;
		}
			public static MockVolumeReference Create(Size3D arrayDimensions,
			                                         Vector3D voxelSpacing,
			                                         Vector3D volumePositionPatient,
			                                         Matrix3D volumeOrientationPatient)
			{
				var dataSet = new DicomAttributeCollection();
				dataSet[DicomTags.Modality].SetStringValue("SC");
				dataSet[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
				dataSet[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
				dataSet[DicomTags.FrameOfReferenceUid].SetStringValue(DicomUid.GenerateUid().UID);
				return new MockVolumeReference(new VolumeHeaderData(new IDicomAttributeProvider[] {dataSet},
				                                                    arrayDimensions,
				                                                    voxelSpacing,
				                                                    volumePositionPatient,
				                                                    volumeOrientationPatient,
				                                                    16, 16, false, 0, 1.0, 0.0, RescaleUnits.None));
			}
		private static void Rotate(Matrix3D transform, float angle, float x, float y, float z)
		{
			const double rads = Math.PI/180;

			var c0 = Math.Cos(rads*angle);
			var c1 = 1 - c0;
			var xc1 = x*c1;
			var yc1 = y*c1;
			var zc1 = z*c1;

			var s = Math.Sin(rads*angle);
			var xs = x*s;
			var ys = y*s;
			var zs = z*s;

			var r = new Matrix3D(new[,]
			                     	{
			                     		{(float) (x*xc1 + c0), (float) (x*yc1 - zs), (float) (x*zc1 + ys)},
			                     		{(float) (y*xc1 + zs), (float) (y*yc1 + c0), (float) (y*zc1 - xs)},
			                     		{(float) (z*xc1 - ys), (float) (z*yc1 + xs), (float) (z*zc1 + c0)}
			                     	});

			var m = r*transform;
			transform.SetRow(0, m[0, 0], m[0, 1], m[0, 2]);
			transform.SetRow(1, m[1, 0], m[1, 1], m[1, 2]);
			transform.SetRow(2, m[2, 0], m[2, 1], m[2, 2]);
		}
Exemple #10
0
		/// <summary>
		/// Rotates the specified volume orientation matrix into the patient coordinate system.
		/// </summary>
		/// <param name="volumeOrientation">The volume orientation to be converted, specified as a <see cref="Matrix3D"/>.</param>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeOrientation"/> is NULL.</exception>
		/// <returns>The specified volume orientation converted to the patient coordinate system.</returns>
		public Matrix3D RotateToPatientOrientation(Matrix3D volumeOrientation)
		{
			return _volumeHeaderData.RotateToPatientOrientation(volumeOrientation);
		}
		public Matrix3D RotateToVolumeOrientation(Matrix3D patientOrientation)
		{
			Platform.CheckForNullReference(patientOrientation, "patientOrientation");

			var orientationVolume = patientOrientation*_volumeOrientationPatient.Transpose();
			return orientationVolume;
		}
		public Matrix3D RotateToPatientOrientation(Matrix3D volumeOrientation)
		{
			Platform.CheckForNullReference(volumeOrientation, "volumeOrientation");

			var orientationPatient = volumeOrientation*_volumeOrientationPatient;
			return orientationPatient;
		}
		/// <summary>
		/// Initializes the <see cref="Volume"/> using the specified volume data.
		/// </summary>
		/// <remarks>
		/// Consider using <see cref="Volume.Create(IDisplaySet)"/> or one of its overloads to automatically construct and fill a <see cref="Volume"/> of the appropriate type.
		/// </remarks>
		public U16Volume(ushort[] array, Size3D arrayDimensions, Vector3D voxelSpacing, Vector3D volumePositionPatient, Matrix3D volumeOrientationPatient, IList<IDicomAttributeProvider> dicomAttributeModel, int paddingValue, double rescaleSlope, double rescaleIntercept, RescaleUnits rescaleUnits)
			: this(array, new VolumeHeaderData(dicomAttributeModel, arrayDimensions, voxelSpacing, volumePositionPatient, volumeOrientationPatient, 16, 16, false, paddingValue, rescaleSlope, rescaleIntercept, rescaleUnits), null, null) {}
		/// <summary>
		/// Initializes the <see cref="Volume"/> using the specified volume data.
		/// </summary>
		/// <remarks>
		/// Consider using <see cref="Volume.Create(IDisplaySet)"/> or one of its overloads to automatically construct and fill a <see cref="Volume"/> of the appropriate type.
		/// </remarks>
		public U16Volume(ushort[] array, Size3D arrayDimensions, Vector3D voxelSpacing, Vector3D volumePositionPatient, Matrix3D volumeOrientationPatient, IDicomAttributeProvider attributeProvider, int paddingValue, double rescaleSlope, double rescaleIntercept, RescaleUnits rescaleUnits)
			: this(array, arrayDimensions, voxelSpacing, volumePositionPatient, volumeOrientationPatient, new[] {attributeProvider}, paddingValue, rescaleSlope, rescaleIntercept, rescaleUnits) {}
		/// <summary>
		/// Initializes the <see cref="Volume"/> using the specified volume data.
		/// </summary>
		/// <remarks>
		/// Consider using <see cref="Volume.Create(IDisplaySet)"/> or one of its overloads to automatically construct and fill a <see cref="Volume"/> of the appropriate type.
		/// </remarks>
		public U16Volume(ushort[] array, Size3D arrayDimensions, Vector3D voxelSpacing, Vector3D volumePositionPatient, Matrix3D volumeOrientationPatient, IDicomAttributeProvider attributeProvider, int paddingValue)
			: this(array, arrayDimensions, voxelSpacing, volumePositionPatient, volumeOrientationPatient, new[] {attributeProvider}, paddingValue, 1, 0, RescaleUnits.None) {}
		/// <summary>
		/// Initializes the <see cref="Volume"/> using the specified volume data.
		/// </summary>
		/// <remarks>
		/// Consider using <see cref="Volume.Create(IDisplaySet)"/> or one of its overloads to automatically construct and fill a <see cref="Volume"/> of the appropriate type.
		/// </remarks>
		public S8Volume(sbyte[] array, Size3D arrayDimensions, Vector3D voxelSpacing, Vector3D volumePositionPatient, Matrix3D volumeOrientationPatient, IList<IDicomAttributeProvider> dicomAttributeModel, int paddingValue)
			: this(array, new VolumeHeaderData(dicomAttributeModel, arrayDimensions, voxelSpacing, volumePositionPatient, volumeOrientationPatient, 8, 8, true, paddingValue, 1, 0, RescaleUnits.None), null, null) {}