/// <summary> /// Sets the slicing plane for the specified slice set based on two points on the specified source image. /// </summary> private static void SetSlicePlane(IMprStandardSliceSet sliceSet, IPresentationImage sourceImage, Vector3D startPoint, Vector3D endPoint) { IImageSopProvider imageSopProvider = sourceImage as IImageSopProvider; if (imageSopProvider == null) { return; } ImageOrientationPatient orientation = imageSopProvider.Frame.ImageOrientationPatient; Vector3D orientationRow = new Vector3D((float)orientation.RowX, (float)orientation.RowY, (float)orientation.RowZ); Vector3D orientationColumn = new Vector3D((float)orientation.ColumnX, (float)orientation.ColumnY, (float)orientation.ColumnZ); if (sliceSet != null && !sliceSet.IsReadOnly) { IImageBox imageBox = FindImageBox(sliceSet, sourceImage.ImageViewer as MprViewerComponent); sliceSet.SlicerParams = VolumeSlicerParams.Create(sliceSet.VolumeHeader, orientationColumn, orientationRow, startPoint, endPoint); IPresentationImage closestImage = GetClosestSlice(startPoint + (endPoint - startPoint) * 2, imageBox.DisplaySet); if (closestImage == null) { imageBox.TopLeftPresentationImageIndex = imageBox.DisplaySet.PresentationImages.Count / 2; } else { imageBox.TopLeftPresentationImage = closestImage; } } }
public void TestInverseRotationMatrices() { for (int x = 0; x < 360; x += 15) { for (int y = 0; y < 360; y += 15) { for (int z = 0; z < 360; z += 15) { VolumeSlicerParams expected = new VolumeSlicerParams(x, y, z); // this constructor stores x, y, z separately from the matrix Matrix mExpected = ComputeRotationMatrix(expected.RotateAboutX, expected.RotateAboutY, expected.RotateAboutZ); VolumeSlicerParams test = new VolumeSlicerParams(expected.SlicingPlaneRotation); // this constructor must infer x, y, z from the matrix Matrix mTest = ComputeRotationMatrix(test.RotateAboutX, test.RotateAboutY, test.RotateAboutZ); for (int r = 0; r < 3; r++) { for (int c = 0; c < 3; c++) { Assert.AreEqual(mExpected[r, c], mTest[r, c], 1e-6, "Rotation Matrices differ at R{3}C{4} for Q={0},{1},{2}", x, y, z, r, c); } } } } } }
public void TestInverseRotationMatrices() { for (int x = 0; x < 360; x += 15) { for (int y = 0; y < 360; y += 15) { for (int z = 0; z < 360; z += 15) { VolumeSlicerParams expected = new VolumeSlicerParams(x, y, z); // this constructor stores x, y, z separately from the matrix Matrix mExpected = ComputeRotationMatrix(expected.RotateAboutX, expected.RotateAboutY, expected.RotateAboutZ); VolumeSlicerParams test = new VolumeSlicerParams(expected.SlicingPlaneRotation); // this constructor must infer x, y, z from the matrix Matrix mTest = ComputeRotationMatrix(test.RotateAboutX, test.RotateAboutY, test.RotateAboutZ); for (int r = 0; r < 3; r++) { for (int c = 0; c < 3; c++) { Assert.AreEqual(mExpected[r, c], mTest[r, c], 1e-6, "Rotation Matrices differ at R{3}C{4} for Q={0},{1},{2}", x, y, z, r, c); } } } } } }
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()); } }