Example #1
0
        /// <summary>
        /// Allows specification of the slice plane, through point, and extent via two points in patient space
        /// </summary>
        public static VolumeSlicerParams Create(Volume volume, Vector3D sourceOrientationColumnPatient, Vector3D sourceOrientationRowPatient,
                                                Vector3D startPointPatient, Vector3D endPointPatient)
        {
            Vector3D sourceOrientationNormalPatient = sourceOrientationColumnPatient.Cross(sourceOrientationRowPatient);
            Vector3D normalLinePatient     = (endPointPatient - startPointPatient).Normalize();
            Vector3D normalPerpLinePatient = sourceOrientationNormalPatient.Cross(normalLinePatient);

            Vector3D slicePlanePatientX = normalLinePatient;
            Vector3D slicePlanePatientY = sourceOrientationNormalPatient;
            Vector3D slicePlanePatientZ = normalPerpLinePatient;

            Matrix slicePlanePatientOrientation = Math3D.OrientationMatrixFromVectors(slicePlanePatientX, slicePlanePatientY, slicePlanePatientZ);

            Matrix   _resliceAxes           = volume.RotateToVolumeOrientation(slicePlanePatientOrientation);
            Vector3D lineMiddlePointPatient = new Vector3D(
                (startPointPatient.X + endPointPatient.X) / 2,
                (startPointPatient.Y + endPointPatient.Y) / 2,
                (startPointPatient.Z + endPointPatient.Z) / 2);

            VolumeSlicerParams slicerParams = new VolumeSlicerParams(_resliceAxes);

            slicerParams.SliceThroughPointPatient = new Vector3D(lineMiddlePointPatient);
            slicerParams.SliceExtentXMillimeters  = (endPointPatient - startPointPatient).Magnitude;

            return(slicerParams);
        }
		/// <summary>
		/// Allows specification of the slice plane, through point, and extent via two points in patient space
		/// </summary>
		public static VolumeSlicerParams Create(IVolumeHeader volume, Vector3D sourceOrientationColumnPatient, Vector3D sourceOrientationRowPatient,
		                                               Vector3D startPointPatient, Vector3D endPointPatient)
		{
			Vector3D sourceOrientationNormalPatient = sourceOrientationColumnPatient.Cross(sourceOrientationRowPatient);
			Vector3D normalLinePatient = (endPointPatient - startPointPatient).Normalize();
			Vector3D normalPerpLinePatient = sourceOrientationNormalPatient.Cross(normalLinePatient);

			Vector3D slicePlanePatientX = normalLinePatient;
			Vector3D slicePlanePatientY = sourceOrientationNormalPatient;
			Vector3D slicePlanePatientZ = normalPerpLinePatient;

			Matrix slicePlanePatientOrientation = Math3D.OrientationMatrixFromVectors(slicePlanePatientX, slicePlanePatientY, slicePlanePatientZ);

			Matrix _resliceAxes = volume.RotateToVolumeOrientation(slicePlanePatientOrientation);
			Vector3D lineMiddlePointPatient = new Vector3D(
				(startPointPatient.X + endPointPatient.X)/2,
				(startPointPatient.Y + endPointPatient.Y)/2,
				(startPointPatient.Z + endPointPatient.Z)/2);

			VolumeSlicerParams slicerParams = new VolumeSlicerParams(_resliceAxes);

			slicerParams.SliceThroughPointPatient = new Vector3D(lineMiddlePointPatient);
			slicerParams.SliceExtentXMillimeters = (endPointPatient - startPointPatient).Magnitude;

			return slicerParams;
		}
Example #3
0
		protected internal byte[] GetOverlay(Frame baseFrame, out OverlayFrameParams overlayFrameParams)
		{
			var volume = this.Volume;

			// compute the bounds of the target base image frame in patient coordinates
			var baseTopLeft = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, 0));
			var baseTopRight = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(baseFrame.Columns, 0));
			var baseBottomLeft = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, baseFrame.Rows));
			var baseFrameCentre = (baseTopRight + baseBottomLeft)/2;

			// compute the rotated volume slicing basis axes
			var volumeXAxis = (volume.ConvertToVolume(baseTopRight) - volume.ConvertToVolume(baseTopLeft)).Normalize();
			var volumeYAxis = (volume.ConvertToVolume(baseBottomLeft) - volume.ConvertToVolume(baseTopLeft)).Normalize();
			var volumeZAxis = volumeXAxis.Cross(volumeYAxis);

			var @params = new VolumeSlicerParams(volumeXAxis, volumeYAxis, volumeZAxis);
			using (var slice = new VolumeSliceSopDataSource(volume, @params, volume.ConvertToVolume(baseFrameCentre)))
			{
				using (var sliceSop = new ImageSop(slice))
				{
					using (var overlayFrame = sliceSop.Frames[1])
					{
						// compute the bounds of the target overlay image frame in patient coordinates
						var overlayTopLeft = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, 0));
						var overlayTopRight = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(overlayFrame.Columns, 0));
						var overlayBottomLeft = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, overlayFrame.Rows));
						var overlayOffset = overlayTopLeft - baseTopLeft;

						// compute the overlay and base image resolution in pixels per unit patient space (mm).
						var overlayResolutionX = overlayFrame.Columns/(overlayTopRight - overlayTopLeft).Magnitude;
						var overlayResolutionY = overlayFrame.Rows/(overlayBottomLeft - overlayTopLeft).Magnitude;
						var baseResolutionX = baseFrame.Columns/(baseTopRight - baseTopLeft).Magnitude;
						var baseResolutionY = baseFrame.Rows/(baseBottomLeft - baseTopLeft).Magnitude;

						// compute parameters to register the overlay on the base image
						var scale = new PointF(baseResolutionX/overlayResolutionX, baseResolutionY/overlayResolutionY);
						var offset = new PointF(overlayOffset.X*overlayResolutionX, overlayOffset.Y*overlayResolutionY);

						//TODO (CR Sept 2010): could this be negative?
						// validate computed transform parameters
						Platform.CheckTrue(overlayOffset.Z < 0.5f, "Compute OffsetZ != 0");

						overlayFrameParams = new OverlayFrameParams(
							overlayFrame.Rows, overlayFrame.Columns,
							overlayFrame.BitsAllocated, overlayFrame.BitsStored,
							overlayFrame.HighBit, overlayFrame.PixelRepresentation != 0 ? true : false,
							overlayFrame.PhotometricInterpretation == PhotometricInterpretation.Monochrome1 ? true : false,
							overlayFrame.RescaleSlope, overlayFrame.RescaleIntercept,
							scale, offset);

						return overlayFrame.GetNormalizedPixelData();
					}
				}
			}
		}
Example #4
0
		public ISopDataSource[] CreateSops(bool signed, Modality modality, Vector3D voxelSpacing, Vector3D sliceAxisX, Vector3D sliceAxisY, Vector3D sliceAxisZ)
		{
			var seriesInstanceUid = DicomUid.GenerateUid().UID;
			var slicerParams = new VolumeSlicerParams(sliceAxisX, sliceAxisY, sliceAxisZ);
			var volume = CreateVolume(signed, modality, voxelSpacing);
			using (VolumeSlicer slicer = new VolumeSlicer(volume, slicerParams, seriesInstanceUid))
			{
				return new List<ISopDataSource>(slicer.CreateSlices()).ToArray();
			}
		}