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