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; }
/// <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; }
/// <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; }
/// <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]); }
/// <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) {}