示例#1
0
        /// <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;
                }
            }
        }
示例#2
0
		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);
                            }
                        }
                    }
                }
            }
        }
示例#4
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());
                    }
                }
            }
        }
示例#5
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());
            }
        }