コード例 #1
0
        /// <summary>
        /// Creates a <see cref="VolumeSlice"/> representing the slice at the specified position in a <see cref="Volume"/>.
        /// </summary>
        /// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
        /// <param name="position">The position, in patient coordinates, of the slice to be created.</param>
        /// <returns>A <see cref="VolumeSlice"/> instance representing the requested slice.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="position"/> is null.</exception>
        public VolumeSlice CreateSlice(IVolumeReference volumeReference, Vector3D position)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");
            Platform.CheckForNullReference(position, "position");

            return(CreateSlicesCore(volumeReference, position, null, 1).Single());
        }
コード例 #2
0
            public void Unload()
            {
                if (_volumeReference == null)
                {
                    return;
                }
                if (_largeObjectContainerData.IsLocked)
                {
                    return;
                }

                lock (_syncRoot)
                {
                    if (_volumeReference == null)
                    {
                        return;
                    }
                    if (_largeObjectContainerData.IsLocked)
                    {
                        return;
                    }

                    Progress = 0;

                    MemoryManager.Remove(this);
                    _largeObjectContainerData.LargeObjectCount = 0;
                    _largeObjectContainerData.BytesHeldCount   = 0;

                    // in general, this would be the only transient reference to the volume
                    // we can't stop external code from calling CreateTransientReference() too
                    // but if they did, the volume wouldn't really release here anyway, so that external code would still work
                    _volumeReference.Dispose();
                    _volumeReference = null;
                }
            }
コード例 #3
0
        private static VolumeSlice CreateSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, float thicknessAndSpacing, Vector3D throughPoint)
        {
            // compute Rows and Columns to reflect actual output size
            var frameSize = GetSliceExtent(volumeReference, slicerParams);

            // compute Pixel Spacing
            var effectiveSpacing = GetEffectiveSpacing(volumeReference);

            // compute Image Orientation (Patient)
            var matrix = new Matrix(slicerParams.SlicingPlaneRotation);

            matrix[3, 0] = throughPoint.X;
            matrix[3, 1] = throughPoint.Y;
            matrix[3, 2] = throughPoint.Z;
            var resliceAxesPatientOrientation = volumeReference.RotateToPatientOrientation(matrix);

            // compute Image Position (Patient)
            var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoint, volumeReference, slicerParams);

            var args = new VolumeSliceArgs(frameSize.Height, frameSize.Width, effectiveSpacing, effectiveSpacing,
                                           new Vector3D(resliceAxesPatientOrientation[0, 0], resliceAxesPatientOrientation[0, 1], resliceAxesPatientOrientation[0, 2]),
                                           new Vector3D(resliceAxesPatientOrientation[1, 0], resliceAxesPatientOrientation[1, 1], resliceAxesPatientOrientation[1, 2]),
                                           thicknessAndSpacing, Convert(slicerParams.InterpolationMode));

            return(new VolumeSlice(volumeReference, true, args, topLeftOfSlicePatient, thicknessAndSpacing));
        }
コード例 #4
0
            /// <summary>
            /// Called when all references to the cached item are destroyed, and thus all held source frames and volume can be released.
            /// </summary>
            private void Dispose()
            {
                MemoryManager.Remove(this);

                // this method is executed on a worker thread after no one else has a reference to this except maybe the memory manager
                // so we lock it so that we don't accidentally dispose the real volume simultaneously from different threads
                // blocking here isn't a big deal since we're also on a worker thread
                lock (_syncRoot)
                {
                    if (_volumeReference != null)
                    {
                        _volumeReference.Dispose();
                        _volumeReference = null;
                    }
                }

                if (_frames != null)
                {
                    foreach (var frameReference in _frames)
                    {
                        frameReference.Dispose();
                    }
                    _frames.Clear();
                    _frames = null;
                }
            }
コード例 #5
0
        /// <summary>
        /// Creates <see cref="VolumeSlice"/>s representing slices around a specified position in a <see cref="Volume"/>.
        /// </summary>
        /// <remarks>
        /// If extent of the slices is not fixed in any way (e.g. via specifying <see cref="Columns"/>, <see cref="SliceWidth"/>, etc.),
        /// then <paramref name="position"/> is effectively ignored and the slices will cover the entirety of the volume.
        /// </remarks>
        /// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
        /// <param name="position">Reference position, in patient coordinates, around which slices will be created.</param>
        /// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="position"/> is null.</exception>
        public IList <VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D position)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");
            Platform.CheckForNullReference(position, "position");

            return(CreateSlicesCore(volumeReference, position, null, 0).ToList());
        }
コード例 #6
0
        /// <summary>
        /// Initializes the instance of <see cref="VolumeSlicerCore"/>.
        /// </summary>
        /// <param name="volumeReference">The <see cref="IVolumeReference"/> of the volume.</param>
        /// <param name="args">The requested slicer algorithm parameters.</param>
        /// <exception cref="ArgumentNullException">Thrown if either <paramref name="volumeReference"/> or <paramref name="args"/> are null.</exception>
        protected VolumeSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
        {
            Platform.CheckForNullReference(volumeReference, "volume");
            Platform.CheckForNullReference(args, "args");

            _volumeReference = volumeReference;
            _args            = args;
        }
コード例 #7
0
		/// <summary>
		/// Initializes the instance of <see cref="VolumeSlicerCore"/>.
		/// </summary>
		/// <param name="volumeReference">The <see cref="IVolumeReference"/> of the volume.</param>
		/// <param name="args">The requested slicer algorithm parameters.</param>
		/// <exception cref="ArgumentNullException">Thrown if either <paramref name="volumeReference"/> or <paramref name="args"/> are null.</exception>
		protected VolumeSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
		{
			Platform.CheckForNullReference(volumeReference, "volume");
			Platform.CheckForNullReference(args, "args");

			_volumeReference = volumeReference;
			_args = args;
		}
コード例 #8
0
        /// <summary>
        /// Creates <see cref="VolumeSlice"/>s representing a number of slices starting from the specified position in a <see cref="Volume"/>.
        /// </summary>
        /// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
        /// <param name="startPosition">Position, in patient coordinates, of the first slice.</param>
        /// <param name="count">The number of slices to be created.</param>
        /// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="startPosition"/> is null.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="count"/> is less than or equal to zero.</exception>
        public IList <VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D startPosition, int count)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");
            Platform.CheckForNullReference(startPosition, "startPosition");
            Platform.CheckPositive(count, "count");

            return(CreateSlicesCore(volumeReference, startPosition, null, count).ToList());
        }
コード例 #9
0
        /// <summary>
        /// Creates <see cref="VolumeSlice"/>s representing slices between two positions in a <see cref="Volume"/>.
        /// </summary>
        /// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
        /// <param name="startPosition">Position, in patient coordinates, of the first slice.</param>
        /// <param name="endPosition">Position, in patient coordinates, of the last slice.</param>
        /// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="startPosition"/> is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="endPosition"/> is null.</exception>
        public IList <VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D startPosition, Vector3D endPosition)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");
            Platform.CheckForNullReference(startPosition, "startPosition");
            Platform.CheckForNullReference(endPosition, "endPosition");

            return(CreateSlicesCore(volumeReference, startPosition, endPosition, 0).ToList());
        }
コード例 #10
0
        internal VolumeSliceSopDataSource(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, IList <Vector3D> throughPoints)
        {
            Platform.CheckForNullReference(throughPoints, "throughPoints");
            Platform.CheckTrue(throughPoints.Count > 0, "At least one through point must be specified.");
            var volume = volumeReference.Volume;

            _volumeReference     = volumeReference;
            _slicerParams        = slicerParams;
            _resliceMatrix       = new Matrix(slicerParams.SlicingPlaneRotation);
            _resliceMatrix[3, 0] = throughPoints[0].X;
            _resliceMatrix[3, 1] = throughPoints[0].Y;
            _resliceMatrix[3, 2] = throughPoints[0].Z;
            _throughPoints       = new List <Vector3D>(throughPoints).AsReadOnly();

            // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management
            _prototypeDataSet = volume.DataSet;

            _instanceDataSet = new DicomAttributeCollection();

            // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames.
            // We need to support multi-valued Slice Location in the base viewer first.
            // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices)
            // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes.
            // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size)

            // assign Rows and Columns to reflect actual output size
            Size frameSize = GetSliceExtent(volume, slicerParams);

            _instanceDataSet[DicomTags.Columns].SetInt32(0, frameSize.Width);
            _instanceDataSet[DicomTags.Rows].SetInt32(0, frameSize.Height);

            // assign Image Orientation (Patient)
            Matrix resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(_resliceMatrix);

            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(0, resliceAxesPatientOrientation[0, 0]);
            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(1, resliceAxesPatientOrientation[0, 1]);
            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(2, resliceAxesPatientOrientation[0, 2]);
            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(3, resliceAxesPatientOrientation[1, 0]);
            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(4, resliceAxesPatientOrientation[1, 1]);
            _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(5, resliceAxesPatientOrientation[1, 2]);

            // assign Image Position (Patient)
            Vector3D topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoints[0], volume, slicerParams);

            _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(0, topLeftOfSlicePatient.X);
            _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(1, topLeftOfSlicePatient.Y);
            _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(2, topLeftOfSlicePatient.Z);

            // assign Number of Frames
            _instanceDataSet[DicomTags.NumberOfFrames].SetInt32(0, throughPoints.Count);

            // assign a new SOP instance UID
            _instanceDataSet[DicomTags.SopInstanceUid].SetString(0, DicomUid.GenerateUid().UID);
        }
コード例 #11
0
        internal VolumeSlice(IVolumeReference volumeReference, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float?spacingBetweenSlices)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");
            Platform.CheckForNullReference(sliceArgs, "slicerArgs");
            Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient");

            _volumeReference      = volumeReference;
            _sliceArgs            = sliceArgs;
            _imagePositionPatient = imagePositionPatient;

            // compute Rows and Columns to reflect actual output size
            Columns = sliceArgs.Columns;
            Rows    = sliceArgs.Rows;

            // compute Slice Thickness
            var sliceThickness = sliceArgs.SliceThickness;

            SliceThickness = new DicomAttributeDS(DicomTags.SliceThickness)
            {
                Values = sliceThickness
            }.ToString();
            SpacingBetweenSlices = spacingBetweenSlices.HasValue ? new DicomAttributeDS(DicomTags.SpacingBetweenSlices)
            {
                Values = spacingBetweenSlices.Value
            }.ToString() : string.Empty;

            // compute Pixel Spacing
            var spacing = new DicomAttributeDS(DicomTags.PixelSpacing);

            spacing.SetFloat32(0, sliceArgs.RowSpacing);
            spacing.SetFloat32(1, sliceArgs.ColumnSpacing);
            PixelSpacing = spacing.ToString();

            // compute Image Orientation (Patient)
            var rowOrientation    = sliceArgs.RowOrientationPatient;
            var columnOrientation = sliceArgs.ColumnOrientationPatient;
            var orientation       = new DicomAttributeDS(DicomTags.ImageOrientationPatient);

            orientation.SetFloat32(0, rowOrientation.X);
            orientation.SetFloat32(1, rowOrientation.Y);
            orientation.SetFloat32(2, rowOrientation.Z);
            orientation.SetFloat32(3, columnOrientation.X);
            orientation.SetFloat32(4, columnOrientation.Y);
            orientation.SetFloat32(5, columnOrientation.Z);
            ImageOrientationPatient = orientation.ToString();

            // compute Image Position (Patient)
            var position = new DicomAttributeDS(DicomTags.ImagePositionPatient);

            position.SetFloat32(0, _imagePositionPatient.X);
            position.SetFloat32(1, _imagePositionPatient.Y);
            position.SetFloat32(2, _imagePositionPatient.Z);
            ImagePositionPatient = position.ToString();
        }
コード例 #12
0
ファイル: MprSliceSet.cs プロジェクト: hksonngan/Xian
        protected MprSliceSet(Volume volume)
        {
            Platform.CheckForNullReference(volume, "volume");
            _volume = volume.CreateTransientReference();

            _sliceSops = new ObservableDisposableList <MprSliceSop>();
            _sliceSops.EnableEvents  = true;
            _sliceSops.ItemAdded    += OnItemAdded;
            _sliceSops.ItemChanged  += OnItemChanged;
            _sliceSops.ItemChanging += OnItemChanging;
            _sliceSops.ItemRemoved  += OnItemRemoved;
        }
コード例 #13
0
ファイル: MprSliceSet.cs プロジェクト: m-berkani/ClearCanvas
		protected MprSliceSet(Volumes.Volume volume)
		{
			Platform.CheckForNullReference(volume, "volume");
			_volume = volume.CreateReference();

			_sliceSops = new ObservableDisposableList<MprSliceSop>();
			_sliceSops.EnableEvents = true;
			_sliceSops.ItemAdded += OnItemAdded;
			_sliceSops.ItemChanged += OnItemChanged;
			_sliceSops.ItemChanging += OnItemChanging;
			_sliceSops.ItemRemoved += OnItemRemoved;
		}
コード例 #14
0
ファイル: VolumeSlice.cs プロジェクト: skwakftys/ClearCanvas
        internal VolumeSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, Vector3D throughPoint)
        {
            Platform.CheckForNullReference(throughPoint, "throughPoint");
            var volume = volumeReference.Volume;

            _volumeReference = volumeReference;
            _slicerParams    = slicerParams;
            _throughPoint    = throughPoint;

            // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management
            _prototypeDataSet = volume.DataSet;

            // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames.
            // We need to support multi-valued Slice Location in the base viewer first.
            // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices)
            // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes.
            // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size)

            // compute Rows and Columns to reflect actual output size
            var frameSize = GetSliceExtent(volume, slicerParams);

            Colums = frameSize.Width;
            Rows   = frameSize.Height;

            // compute Image Orientation (Patient)
            var matrix = new Matrix(slicerParams.SlicingPlaneRotation);

            matrix[3, 0] = _throughPoint.X;
            matrix[3, 1] = _throughPoint.Y;
            matrix[3, 2] = _throughPoint.Z;

            var resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(matrix);
            var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient);

            orientation.SetFloat32(0, resliceAxesPatientOrientation[0, 0]);
            orientation.SetFloat32(1, resliceAxesPatientOrientation[0, 1]);
            orientation.SetFloat32(2, resliceAxesPatientOrientation[0, 2]);
            orientation.SetFloat32(3, resliceAxesPatientOrientation[1, 0]);
            orientation.SetFloat32(4, resliceAxesPatientOrientation[1, 1]);
            orientation.SetFloat32(5, resliceAxesPatientOrientation[1, 2]);
            ImageOrientationPatient = orientation.ToString();

            // compute Image Position (Patient)
            var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, _throughPoint, volume, slicerParams);
            var position = new DicomAttributeDS(DicomTags.ImagePositionPatient);

            position.SetFloat32(0, topLeftOfSlicePatient.X);
            position.SetFloat32(1, topLeftOfSlicePatient.Y);
            position.SetFloat32(2, topLeftOfSlicePatient.Z);
            ImagePositionPatient = position.ToString();
        }
コード例 #15
0
		internal VolumeSliceSopDataSource(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, IList<Vector3D> throughPoints)
		{
			Platform.CheckForNullReference(throughPoints, "throughPoints");
			Platform.CheckTrue(throughPoints.Count > 0, "At least one through point must be specified.");
			var volume = volumeReference.Volume;

			_volumeReference = volumeReference;
			_slicerParams = slicerParams;
			_resliceMatrix = new Matrix(slicerParams.SlicingPlaneRotation);
			_resliceMatrix[3, 0] = throughPoints[0].X;
			_resliceMatrix[3, 1] = throughPoints[0].Y;
			_resliceMatrix[3, 2] = throughPoints[0].Z;
			_throughPoints = new List<Vector3D>(throughPoints).AsReadOnly();

			// keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management
			_prototypeDataSet = volume.DataSet;

			_instanceDataSet = new DicomAttributeCollection();

			// JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames.
			// We need to support multi-valued Slice Location in the base viewer first.
			// When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices)
			// and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes.
			// Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size)

			// assign Rows and Columns to reflect actual output size
			Size frameSize = GetSliceExtent(volume, slicerParams);
			_instanceDataSet[DicomTags.Columns].SetInt32(0, frameSize.Width);
			_instanceDataSet[DicomTags.Rows].SetInt32(0, frameSize.Height);

			// assign Image Orientation (Patient)
			Matrix resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(_resliceMatrix);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(0, resliceAxesPatientOrientation[0, 0]);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(1, resliceAxesPatientOrientation[0, 1]);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(2, resliceAxesPatientOrientation[0, 2]);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(3, resliceAxesPatientOrientation[1, 0]);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(4, resliceAxesPatientOrientation[1, 1]);
			_instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(5, resliceAxesPatientOrientation[1, 2]);

			// assign Image Position (Patient)
			Vector3D topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoints[0], volume, slicerParams);
			_instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(0, topLeftOfSlicePatient.X);
			_instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(1, topLeftOfSlicePatient.Y);
			_instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(2, topLeftOfSlicePatient.Z);

			// assign Number of Frames
			_instanceDataSet[DicomTags.NumberOfFrames].SetInt32(0, throughPoints.Count);

			// assign a new SOP instance UID
			_instanceDataSet[DicomTags.SopInstanceUid].SetString(0, DicomUid.GenerateUid().UID);
		}
コード例 #16
0
            private Volume LoadCore(VolumeLoadProgressCallback callback)
            {
                // TODO (CR Apr 2013): Same comment as with Fusion - shouldn't actually need to lock for
                // the duration of volume creation. Should be enough to set a _loading flag, exit the lock,
                // then re-enter the lock to reset the _loading flag and set any necessary fields.
                // Locking for the duration means the memory manager could get hung up while trying to unload
                // a big volume that is in the process of being created.

                lock (_syncRoot)
                {
                    if (_volumeReference != null)
                    {
                        return(_volumeReference.Volume);
                    }

                    Progress = 0;

                    using (var volume = Volume.Create(_frames, (n, total) =>
                    {
                        Progress = Math.Min(100f, 100f * n / total);
                        if (callback != null)
                        {
                            callback.Invoke(this, n, total);
                        }
                        _largeObjectContainerData.UpdateLastAccessTime();

#if UNIT_TESTS
                        if (ThrowAsyncVolumeLoadException)
                        {
                            ThrowAsyncVolumeLoadException = false;
                            throw new CreateVolumeException("User manually triggered exception");
                        }
#endif
                    }))
                    {
                        _volumeReference = volume.CreateReference();

                        _largeObjectContainerData.LargeObjectCount = 1;
                        _largeObjectContainerData.BytesHeldCount   = 2 * volume.ArrayLength;
                        _largeObjectContainerData.UpdateLastAccessTime();
                        MemoryManager.Add(this);
                    }

                    Progress = 100f;

                    return(_volumeReference.Volume);
                }
            }
コード例 #17
0
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }

            if (_volumeReference != null)
            {
                _volumeReference.Dispose();
                _volumeReference = null;
            }

            _sliceArgs            = null;
            _imagePositionPatient = null;
        }
コード例 #18
0
ファイル: VolumeSlice.cs プロジェクト: UIKit0/ClearCanvas
		internal VolumeSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, Vector3D throughPoint)
		{
			Platform.CheckForNullReference(throughPoint, "throughPoint");
			var volume = volumeReference.Volume;

			_volumeReference = volumeReference;
			_slicerParams = slicerParams;
			_throughPoint = throughPoint;

			// keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management
			_prototypeDataSet = volume.DataSet;

			// JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames.
			// We need to support multi-valued Slice Location in the base viewer first.
			// When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices)
			// and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes.
			// Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size)

			// compute Rows and Columns to reflect actual output size
			var frameSize = GetSliceExtent(volume, slicerParams);
			Colums = frameSize.Width;
			Rows = frameSize.Height;

			// compute Image Orientation (Patient)
			var matrix = new Matrix(slicerParams.SlicingPlaneRotation);
			matrix[3, 0] = _throughPoint.X;
			matrix[3, 1] = _throughPoint.Y;
			matrix[3, 2] = _throughPoint.Z;

			var resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(matrix);
			var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient);
			orientation.SetFloat32(0, resliceAxesPatientOrientation[0, 0]);
			orientation.SetFloat32(1, resliceAxesPatientOrientation[0, 1]);
			orientation.SetFloat32(2, resliceAxesPatientOrientation[0, 2]);
			orientation.SetFloat32(3, resliceAxesPatientOrientation[1, 0]);
			orientation.SetFloat32(4, resliceAxesPatientOrientation[1, 1]);
			orientation.SetFloat32(5, resliceAxesPatientOrientation[1, 2]);
			ImageOrientationPatient = orientation.ToString();

			// compute Image Position (Patient)
			var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, _throughPoint, volume, slicerParams);
			var position = new DicomAttributeDS(DicomTags.ImagePositionPatient);
			position.SetFloat32(0, topLeftOfSlicePatient.X);
			position.SetFloat32(1, topLeftOfSlicePatient.Y);
			position.SetFloat32(2, topLeftOfSlicePatient.Z);
			ImagePositionPatient = position.ToString();
		}
コード例 #19
0
ファイル: VolumeSlice.cs プロジェクト: skwakftys/ClearCanvas
        protected void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }

            if (_volumeReference != null)
            {
                _volumeReference.Dispose();
                _volumeReference = null;
            }

            _prototypeDataSet = null;
            _slicerParams     = null;
            _throughPoint     = null;
        }
コード例 #20
0
        /// <summary>
        /// Creates an implementation of <see cref="IVolumeSlicerCore"/> for slicing the requested volume.
        /// </summary>
        /// <param name="volumeReference">Reference to the <see cref="Volume"/> to be resliced.</param>
        /// <param name="args">The requested reslicing parameters.</param>
        public static IVolumeSlicerCore Create(IVolumeReference volumeReference, VolumeSliceArgs args)
        {
            if (_coreProviders == null)
            {
                try
                {
                    _coreProviders = new VolumeSlicerCoreProviderExtensionPoint().CreateExtensions().Cast <IVolumeSlicerCoreProvider>().ToList();
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, ex, "Failed to initialize implementations on VolumeSlicerCoreProviderExtensionPoint");
                }
            }

            if (_coreProviders == null || !_coreProviders.Any())
            {
#if UNIT_TESTS
                // ensures the VTK version is loaded if possible
                TypeRef.Get("ClearCanvas.ImageViewer.Vtk.VtkVolumeSlicerCoreProvider, ClearCanvas.ImageViewer.VTK").Resolve();

                // ensures that unit tests running under a custom extension factory will always have a slicer implementation where available
                _coreProviders = Platform.PluginManager.ExtensionPoints
                                 .First(e => e.ExtensionPointClass == typeof(VolumeSlicerCoreProviderExtensionPoint))
                                 .ListExtensions().Select(x => Activator.CreateInstance(x.ExtensionClass.Resolve()))
                                 .Cast <IVolumeSlicerCoreProvider>().ToList();

                if (_coreProviders == null || !_coreProviders.Any())
                {
                    throw new NotSupportedException("No implementations of IVolumeSlicerCoreProvider were found.");
                }
#else
                throw new NotSupportedException("No implementations of IVolumeSlicerCoreProvider were found.");
#endif
            }

            try
            {
                return(_coreProviders.First(c => c.IsSupported(args)).CreateSlicerCore(volumeReference, args));
            }
            catch (Exception ex)
            {
                throw new NotSupportedException("No suitable implementation of IVolumeSlicerCoreProvider was found.", ex);
            }
        }
コード例 #21
0
ファイル: VolumeSlice.cs プロジェクト: m-berkani/ClearCanvas
		internal VolumeSlice(IVolumeReference volumeReference, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float? spacingBetweenSlices)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");
			Platform.CheckForNullReference(sliceArgs, "slicerArgs");
			Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient");

			_volumeReference = volumeReference;
			_sliceArgs = sliceArgs;
			_imagePositionPatient = imagePositionPatient;

			// compute Rows and Columns to reflect actual output size
			Columns = sliceArgs.Columns;
			Rows = sliceArgs.Rows;

			// compute Slice Thickness
			var sliceThickness = sliceArgs.SliceThickness;
			SliceThickness = new DicomAttributeDS(DicomTags.SliceThickness) {Values = sliceThickness}.ToString();
			SpacingBetweenSlices = spacingBetweenSlices.HasValue ? new DicomAttributeDS(DicomTags.SpacingBetweenSlices) {Values = spacingBetweenSlices.Value}.ToString() : string.Empty;

			// compute Pixel Spacing
			var spacing = new DicomAttributeDS(DicomTags.PixelSpacing);
			spacing.SetFloat32(0, sliceArgs.RowSpacing);
			spacing.SetFloat32(1, sliceArgs.ColumnSpacing);
			PixelSpacing = spacing.ToString();

			// compute Image Orientation (Patient)
			var rowOrientation = sliceArgs.RowOrientationPatient;
			var columnOrientation = sliceArgs.ColumnOrientationPatient;
			var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient);
			orientation.SetFloat32(0, rowOrientation.X);
			orientation.SetFloat32(1, rowOrientation.Y);
			orientation.SetFloat32(2, rowOrientation.Z);
			orientation.SetFloat32(3, columnOrientation.X);
			orientation.SetFloat32(4, columnOrientation.Y);
			orientation.SetFloat32(5, columnOrientation.Z);
			ImageOrientationPatient = orientation.ToString();

			// compute Image Position (Patient)
			var position = new DicomAttributeDS(DicomTags.ImagePositionPatient);
			position.SetFloat32(0, _imagePositionPatient.X);
			position.SetFloat32(1, _imagePositionPatient.Y);
			position.SetFloat32(2, _imagePositionPatient.Z);
			ImagePositionPatient = position.ToString();
		}
コード例 #22
0
            /// <summary>
            /// Called when all references to the cached item are destroyed, and thus all held source frames and volume can be released.
            /// </summary>
            private void Dispose()
            {
                MemoryManager.Remove(this);

                if (_volumeReference != null)
                {
                    _volumeReference.Dispose();
                    _volumeReference = null;
                }

                if (_frames != null)
                {
                    foreach (var frameReference in _frames)
                    {
                        frameReference.Dispose();
                    }
                    _frames.Clear();
                    _frames = null;
                }
            }
コード例 #23
0
ファイル: MprSliceSet.cs プロジェクト: hksonngan/Xian
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_sliceSops != null)
                {
                    _sliceSops.ItemAdded    -= OnItemAdded;
                    _sliceSops.ItemChanged  -= OnItemChanged;
                    _sliceSops.ItemChanging -= OnItemChanging;
                    _sliceSops.ItemRemoved  -= OnItemRemoved;
                    _sliceSops.Dispose();
                    _sliceSops = null;
                }

                if (_volume != null)
                {
                    _volume.Dispose();
                    _volume = null;
                }
            }
        }
コード例 #24
0
            private Volume LoadCore(VolumeLoadProgressCallback callback)
            {
                if (_volumeReference != null)
                {
                    return(_volumeReference.Volume);
                }

                lock (_syncRoot)
                {
                    if (_volumeReference != null)
                    {
                        return(_volumeReference.Volume);
                    }

                    Progress = 0;

                    using (var volume = Volume.Create(_frames, (n, total) =>
                    {
                        Progress = Math.Min(100f, 100f * n / total);
                        if (callback != null)
                        {
                            callback.Invoke(this, n, total);
                        }
                    }))
                    {
                        _volumeReference = volume.CreateTransientReference();

                        _largeObjectContainerData.LargeObjectCount = 1;
                        _largeObjectContainerData.BytesHeldCount   = 2 * volume.SizeInVoxels;
                        _largeObjectContainerData.UpdateLastAccessTime();
                        MemoryManager.Add(this);
                    }

                    Progress = 100f;

                    return(_volumeReference.Volume);
                }
            }
コード例 #25
0
ファイル: VolumeSlicer.cs プロジェクト: m-berkani/ClearCanvas
		private static VolumeSlice CreateSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, float thicknessAndSpacing, Vector3D throughPoint)
		{
			// compute Rows and Columns to reflect actual output size
			var frameSize = GetSliceExtent(volumeReference, slicerParams);

			// compute Pixel Spacing
			var effectiveSpacing = GetEffectiveSpacing(volumeReference);

			// compute Image Orientation (Patient)
			var matrix = new Matrix(slicerParams.SlicingPlaneRotation);
			matrix[3, 0] = throughPoint.X;
			matrix[3, 1] = throughPoint.Y;
			matrix[3, 2] = throughPoint.Z;
			var resliceAxesPatientOrientation = volumeReference.RotateToPatientOrientation(matrix);

			// compute Image Position (Patient)
			var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoint, volumeReference, slicerParams);

			var args = new VolumeSliceArgs(frameSize.Height, frameSize.Width, effectiveSpacing, effectiveSpacing,
			                               new Vector3D(resliceAxesPatientOrientation[0, 0], resliceAxesPatientOrientation[0, 1], resliceAxesPatientOrientation[0, 2]),
			                               new Vector3D(resliceAxesPatientOrientation[1, 0], resliceAxesPatientOrientation[1, 1], resliceAxesPatientOrientation[1, 2]),
			                               thicknessAndSpacing, Convert(slicerParams.InterpolationMode));

			return new VolumeSlice(volumeReference, true, args, topLeftOfSlicePatient, thicknessAndSpacing);
		}
コード例 #26
0
		/// <summary>
		/// Creates an implementation of <see cref="IVolumeSlicerCore"/> for slicing the requested volume.
		/// </summary>
		/// <param name="volumeReference">Reference to the <see cref="Volume"/> to be resliced.</param>
		/// <param name="args">The requested reslicing parameters.</param>
		public static IVolumeSlicerCore Create(IVolumeReference volumeReference, VolumeSliceArgs args)
		{
			if (_coreProviders == null)
			{
				try
				{
					_coreProviders = new VolumeSlicerCoreProviderExtensionPoint().CreateExtensions().Cast<IVolumeSlicerCoreProvider>().ToList();
				}
				catch (Exception ex)
				{
					Platform.Log(LogLevel.Error, ex, "Failed to initialize implementations on VolumeSlicerCoreProviderExtensionPoint");
				}
			}

			if (_coreProviders == null || !_coreProviders.Any())
			{
#if UNIT_TESTS
				// ensures that unit tests running under a custom extension factory will always have a slicer implementation where available
				_coreProviders = Platform.PluginManager.ExtensionPoints
					.First(e => e.ExtensionPointClass == typeof (VolumeSlicerCoreProviderExtensionPoint))
					.ListExtensions().Select(x => Activator.CreateInstance(x.ExtensionClass.Resolve()))
					.Cast<IVolumeSlicerCoreProvider>().ToList();

				if (_coreProviders == null || !_coreProviders.Any())
					throw new NotSupportedException("No implementations of IVolumeSlicerCoreProvider were found.");
#else
				throw new NotSupportedException("No implementations of IVolumeSlicerCoreProvider were found.");
#endif
			}

			try
			{
				return _coreProviders.First(c => c.IsSupported(args)).CreateSlicerCore(volumeReference, args);
			}
			catch (Exception ex)
			{
				throw new NotSupportedException("No suitable implementation of IVolumeSlicerCoreProvider was found.", ex);
			}
		}
コード例 #27
0
		/// <summary>
		/// Creates <see cref="VolumeSlice"/>s representing slices in a <see cref="Volume"/>.
		/// </summary>
		/// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
		/// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
		public IList<VolumeSlice> CreateSlices(IVolumeReference volumeReference)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");

			return CreateSlicesCore(volumeReference, null, null, 0).ToList();
		}
コード例 #28
0
		public IVolumeSlicerCore CreateSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
		{
			return new VtkVolumeSlicerCore(volumeReference, args);
		}
コード例 #29
0
ファイル: VolumeSlicer.cs プロジェクト: UIKit0/ClearCanvas
		public VolumeSlicer(Volume volume, IVolumeSlicerParams slicerParams)
		{
			_volume = volume.CreateTransientReference();
			_slicerParams = slicerParams;
		}
コード例 #30
0
 public VolumeSlicer(Volume volume, IVolumeSlicerParams slicerParams)
 {
     _volume       = volume.CreateTransientReference();
     _slicerParams = slicerParams;
 }
コード例 #31
0
		/// <summary>
		/// Gets the pixel data representing a thin slice of the volume.
		/// </summary>
		private static byte[] GetSlicePixelData(IVolumeReference volumeReference, Matrix resliceAxes, int rows, int columns, float rowSpacing, float columnSpacing, VolumeInterpolationMode interpolation)
		{
			using (var reslicer = new vtkImageReslice())
			using (var resliceAxesMatrix = new vtkMatrix4x4())
			using (var executive = reslicer.GetExecutive())
			using (var volume = volumeReference.Volume.CreateVtkVolumeHandle())
			{
				// update the reslice axes matrix with the values from the slicing orientation
				resliceAxesMatrix.SetElements(resliceAxes);

				// register for errors on the reslicer
				reslicer.RegisterVtkErrorEvents();

				// set input to the volume
				reslicer.SetInput(volume.vtkImageData);
				reslicer.SetInformationInput(volume.vtkImageData);

				// instruct reslicer to output 2D images
				reslicer.SetOutputDimensionality(2);

				// use the volume's padding value for all pixels that are outside the volume
				reslicer.SetBackgroundLevel(volumeReference.PaddingValue);

				// ensure the slicer outputs at our desired spacing
				reslicer.SetOutputSpacing(columnSpacing, rowSpacing, Math.Min(columnSpacing, rowSpacing));

				// set the reslice axes
				reslicer.SetResliceAxes(resliceAxesMatrix);

				// clamp the output based on the slice extent
				reslicer.SetOutputExtent(0, columns - 1, 0, rows - 1, 0, 0);

				// set the output origin to the slice through-point (output image will be centered on this location)
				// VTK output origin is derived from the center image being 0,0
				reslicer.SetOutputOrigin(-columns*columnSpacing/2, -rows*rowSpacing/2, 0);

				// select the requested interpolation mode
				switch (interpolation)
				{
					case VolumeInterpolationMode.NearestNeighbor:
						reslicer.SetInterpolationModeToNearestNeighbor();
						break;
					case VolumeInterpolationMode.Linear:
						reslicer.SetInterpolationModeToLinear();
						break;
					case VolumeInterpolationMode.Cubic:
						reslicer.SetInterpolationModeToCubic();
						break;
				}

				// register for errors on the reslicer executive
				executive.RegisterVtkErrorEvents();
				executive.Update();

				// get the slice output
				using (var imageData = reslicer.GetOutput())
				{
					var pixelData = ReadVtkImageData(imageData);
					imageData.ReleaseData();
					return pixelData;
				}
			}
		}
コード例 #32
0
 public VolumeSlicer(Volumes.Volume volume, IVolumeSlicerParams slicerParams)
 {
     _volume       = volume.CreateReference();
     _slicerParams = slicerParams;
 }
コード例 #33
0
        /// <summary>
        /// Gets the pixel data representing a thin slice of the volume.
        /// </summary>
        private static byte[] GetSlicePixelData(IVolumeReference volumeReference, Matrix resliceAxes, int rows, int columns, float rowSpacing, float columnSpacing, VolumeInterpolationMode interpolation)
        {
            using (var reslicer = new vtkImageReslice())
                using (var resliceAxesMatrix = new vtkMatrix4x4())
                    using (var executive = reslicer.GetExecutive())
                        using (var volume = volumeReference.Volume.CreateVtkVolumeHandle())
                        {
                            // update the reslice axes matrix with the values from the slicing orientation
                            resliceAxesMatrix.SetElements(resliceAxes);

                            // register for errors on the reslicer
                            reslicer.RegisterVtkErrorEvents();

                            // set input to the volume
                            reslicer.SetInput(volume.vtkImageData);
                            reslicer.SetInformationInput(volume.vtkImageData);

                            // instruct reslicer to output 2D images
                            reslicer.SetOutputDimensionality(2);

                            // use the volume's padding value for all pixels that are outside the volume
                            reslicer.SetBackgroundLevel(volumeReference.PaddingValue);

                            // ensure the slicer outputs at our desired spacing
                            reslicer.SetOutputSpacing(columnSpacing, rowSpacing, Math.Min(columnSpacing, rowSpacing));

                            // set the reslice axes
                            reslicer.SetResliceAxes(resliceAxesMatrix);

                            // clamp the output based on the slice extent
                            reslicer.SetOutputExtent(0, columns - 1, 0, rows - 1, 0, 0);

                            // set the output origin to the slice through-point (output image will be centered on this location)
                            // VTK output origin is derived from the center image being 0,0
                            reslicer.SetOutputOrigin(-columns * columnSpacing / 2, -rows * rowSpacing / 2, 0);

                            // select the requested interpolation mode
                            switch (interpolation)
                            {
                            case VolumeInterpolationMode.NearestNeighbor:
                                reslicer.SetInterpolationModeToNearestNeighbor();
                                break;

                            case VolumeInterpolationMode.Linear:
                                reslicer.SetInterpolationModeToLinear();
                                break;

                            case VolumeInterpolationMode.Cubic:
                                reslicer.SetInterpolationModeToCubic();
                                break;
                            }

                            // register for errors on the reslicer executive
                            executive.RegisterVtkErrorEvents();
                            executive.Update();

                            // get the slice output
                            using (var imageData = reslicer.GetOutput())
                            {
                                var pixelData = ReadVtkImageData(imageData);
                                imageData.ReleaseData();
                                return(pixelData);
                            }
                        }
        }
コード例 #34
0
		/// <summary>
		/// Creates <see cref="VolumeSlice"/>s representing slices around a specified position in a <see cref="Volume"/>.
		/// </summary>
		/// <remarks>
		/// If extent of the slices is not fixed in any way (e.g. via specifying <see cref="Columns"/>, <see cref="SliceWidth"/>, etc.),
		/// then <paramref name="position"/> is effectively ignored and the slices will cover the entirety of the volume.
		/// </remarks>
		/// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
		/// <param name="position">Reference position, in patient coordinates, around which slices will be created.</param>
		/// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="position"/> is null.</exception>
		public IList<VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D position)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");
			Platform.CheckForNullReference(position, "position");

			return CreateSlicesCore(volumeReference, position, null, 0).ToList();
		}
コード例 #35
0
ファイル: VolumeSlice.cs プロジェクト: UIKit0/ClearCanvas
		protected void Dispose(bool disposing)
		{
			if (!disposing) return;

			if (_volumeReference != null)
			{
				_volumeReference.Dispose();
				_volumeReference = null;
			}

			_prototypeDataSet = null;
			_slicerParams = null;
			_throughPoint = null;
		}
コード例 #36
0
		/// <summary>
		/// Creates <see cref="VolumeSlice"/>s representing a number of slices starting from the specified position in a <see cref="Volume"/>.
		/// </summary>
		/// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
		/// <param name="startPosition">Position, in patient coordinates, of the first slice.</param>
		/// <param name="count">The number of slices to be created.</param>
		/// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="startPosition"/> is null.</exception>
		/// <exception cref="ArgumentException">Thrown if <paramref name="count"/> is less than or equal to zero.</exception>
		public IList<VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D startPosition, int count)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");
			Platform.CheckForNullReference(startPosition, "startPosition");
			Platform.CheckPositive(count, "count");

			return CreateSlicesCore(volumeReference, startPosition, null, count).ToList();
		}
コード例 #37
0
		/// <summary>
		/// Creates <see cref="VolumeSlice"/>s representing slices between two positions in a <see cref="Volume"/>.
		/// </summary>
		/// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
		/// <param name="startPosition">Position, in patient coordinates, of the first slice.</param>
		/// <param name="endPosition">Position, in patient coordinates, of the last slice.</param>
		/// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="startPosition"/> is null.</exception>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="endPosition"/> is null.</exception>
		public IList<VolumeSlice> CreateSlices(IVolumeReference volumeReference, Vector3D startPosition, Vector3D endPosition)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");
			Platform.CheckForNullReference(startPosition, "startPosition");
			Platform.CheckForNullReference(endPosition, "endPosition");

			return CreateSlicesCore(volumeReference, startPosition, endPosition, 0).ToList();
		}
コード例 #38
0
ファイル: VolumeSlicer.cs プロジェクト: hksonngan/Xian
 public VolumeSlicer(Volume vol, IVolumeSlicerParams slicerParams, string seriesInstanceUid)
 {
     _volume            = vol.CreateTransientReference();
     _slicerParams      = slicerParams;
     _seriesInstanceUid = seriesInstanceUid;
 }
コード例 #39
0
ファイル: VolumeSlicer.cs プロジェクト: tcchau/ClearCanvas
		public VolumeSlicer(Volume vol, IVolumeSlicerParams slicerParams, string seriesInstanceUid)
		{
			_volume = vol.CreateTransientReference();
			_slicerParams = slicerParams;
			_seriesInstanceUid = seriesInstanceUid;
		}
コード例 #40
0
 public IVolumeSlicerCore CreateSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
 {
     return(new VtkVolumeSlicerCore(volumeReference, args));
 }
コード例 #41
0
ファイル: VolumeSlicer.cs プロジェクト: tcchau/ClearCanvas
		public VolumeSlicer(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, string seriesInstanceUid)
		{
			_volume = volumeReference.Clone();
			_slicerParams = slicerParams;
			_seriesInstanceUid = seriesInstanceUid;
		}
コード例 #42
0
ファイル: MprSliceSet.cs プロジェクト: m-berkani/ClearCanvas
		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (_sliceSops != null)
				{
					_sliceSops.ItemAdded -= OnItemAdded;
					_sliceSops.ItemChanged -= OnItemChanged;
					_sliceSops.ItemChanging -= OnItemChanging;
					_sliceSops.ItemRemoved -= OnItemRemoved;
					_sliceSops.Dispose();
					_sliceSops = null;
				}

				if (_volume != null)
				{
					_volume.Dispose();
					_volume = null;
				}
			}
		}
コード例 #43
0
 public VolumeSlicer(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams)
 {
     _volume       = volumeReference.Clone();
     _slicerParams = slicerParams;
 }
コード例 #44
0
		/// <summary>
		/// Creates a <see cref="VolumeSlice"/> representing the slice at the specified position in a <see cref="Volume"/>.
		/// </summary>
		/// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
		/// <param name="position">The position, in patient coordinates, of the slice to be created.</param>
		/// <returns>A <see cref="VolumeSlice"/> instance representing the requested slice.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="position"/> is null.</exception>
		public VolumeSlice CreateSlice(IVolumeReference volumeReference, Vector3D position)
		{
			Platform.CheckForNullReference(volumeReference, "volumeReference");
			Platform.CheckForNullReference(position, "position");

			return CreateSlicesCore(volumeReference, position, null, 1).Single();
		}
コード例 #45
0
		/// <summary>
		/// Gets the pixel data representing a thick slice (a.k.a. slab) of the volume.
		/// </summary>
		private static byte[] GetSlabPixelData(IVolumeReference volumeReference, Matrix resliceAxes, Vector3D stackOrientation, int rows, int columns, int subsamples, float rowSpacing, float columnSpacing, float sliceThickness, VolumeInterpolationMode interpolation, VolumeProjectionMode projection)
		{
			if (subsamples <= 1) return GetSlicePixelData(volumeReference, resliceAxes, rows, columns, rowSpacing, columnSpacing, interpolation);
			var subsampleSpacing = sliceThickness/(subsamples - 1);

			using (var reslicer = new vtkImageReslice())
			using (var resliceAxesMatrix = new vtkMatrix4x4())
			using (var executive = reslicer.GetExecutive())
			using (var volume = volumeReference.Volume.CreateVtkVolumeHandle())
			{
				// update the reslice axes matrix with the values from the slicing orientation
				resliceAxesMatrix.SetElements(resliceAxes);

				// determine offset for start of slab (we centre the slab on the requested slice position, as DICOM defines "image position (patient)" to be centre of the thick slice)
				var slabOffset = volumeReference.RotateToVolumeOrientation(-sliceThickness/2f*stackOrientation) + new Vector3D(resliceAxes[0, 3], resliceAxes[1, 3], resliceAxes[2, 3]);
				resliceAxesMatrix.SetElement(0, 3, slabOffset.X);
				resliceAxesMatrix.SetElement(1, 3, slabOffset.Y);
				resliceAxesMatrix.SetElement(2, 3, slabOffset.Z);

				// register for errors on the reslicer
				reslicer.RegisterVtkErrorEvents();

				// set input to the volume
				reslicer.SetInput(volume.vtkImageData);
				reslicer.SetInformationInput(volume.vtkImageData);

				// instruct reslicer to output a 3D slab volume
				reslicer.SetOutputDimensionality(3);

				// use the volume's padding value for all pixels that are outside the volume
				reslicer.SetBackgroundLevel(volumeReference.PaddingValue);

				// ensure the slicer outputs at our desired spacing
				reslicer.SetOutputSpacing(columnSpacing, rowSpacing, subsampleSpacing);

				// set the reslice axes
				reslicer.SetResliceAxes(resliceAxesMatrix);

				// clamp the output based on the slice extent
				reslicer.SetOutputExtent(0, columns - 1, 0, rows - 1, 0, subsamples - 1);

				// set the output origin to the slice through-point (output image will be centered on this location)
				// VTK output origin is derived from the center image being 0,0
				reslicer.SetOutputOrigin(-columns*columnSpacing/2, -rows*rowSpacing/2, 0);

				// select the requested interpolation mode
				switch (interpolation)
				{
					case VolumeInterpolationMode.NearestNeighbor:
						reslicer.SetInterpolationModeToNearestNeighbor();
						break;
					case VolumeInterpolationMode.Linear:
						reslicer.SetInterpolationModeToLinear();
						break;
					case VolumeInterpolationMode.Cubic:
						reslicer.SetInterpolationModeToCubic();
						break;
				}

				// select the requested slab projection mode
				Action<IntPtr, byte[], int, int, int, bool> slabAggregator;
				switch (projection)
				{
					case VolumeProjectionMode.Maximum:
						slabAggregator = SlabProjection.AggregateSlabMaximumIntensity;
						break;
					case VolumeProjectionMode.Minimum:
						slabAggregator = SlabProjection.AggregateSlabMinimumIntensity;
						break;
					case VolumeProjectionMode.Average:
					default:
						slabAggregator = SlabProjection.AggregateSlabAverageIntensity;
						break;
				}

				// register for errors on the reslicer executive
				executive.RegisterVtkErrorEvents();
				executive.Update();

				// get the slice output
				using (var imageData = reslicer.GetOutput())
				{
					var pixelData = SlabVtkImageData(imageData, slabAggregator, volumeReference.BitsPerVoxel, volumeReference.Signed);
					imageData.ReleaseData();
					return pixelData;
				}
			}
		}
コード例 #46
0
ファイル: VolumeSlicer.cs プロジェクト: m-berkani/ClearCanvas
		public VolumeSlicer(Volumes.Volume volume, IVolumeSlicerParams slicerParams)
		{
			_volume = volume.CreateReference();
			_slicerParams = slicerParams;
		}
コード例 #47
0
		/// <summary>
		/// Initializes a new instance of <see cref="VtkVolumeSlicerCore"/>.
		/// </summary>
		/// <param name="volumeReference"></param>
		/// <param name="args"></param>
		public VtkVolumeSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
			: base(volumeReference, args) {}
コード例 #48
0
        private IEnumerable <VolumeSlice> CreateSlicesCore(IVolumeReference volumeReference, Vector3D startPosition, Vector3D endPosition, int count)
        {
            // get the axes of the output plane and its normal in patient coordinates - these are the axes of the slicer frame
            var slicerAxisX = (RowOrientationPatient ?? volumeReference.VolumeOrientationPatientX).Normalize();
            var slicerAxisY = (ColumnOrientationPatient ?? volumeReference.VolumeOrientationPatientY).Normalize();
            var slicerAxisZ = (StackOrientationPatient ?? slicerAxisX.Cross(slicerAxisY)).Normalize();

            // get the pixel spacing (defaults to isotropic spacing based on smallest volume spacing dimension)
            var pixelSpacing = GetPixelSpacing(volumeReference);

            // get the spacing between slices (defaults to smallest volume spacing dimension)
            var sliceSpacing = GetSliceSpacing(volumeReference, slicerAxisZ);

            // get the thickness of each slice (defaults to slice spacing)
            var sliceThickness = SliceThickness ?? sliceSpacing;

            // get the ideal subsampling for the slice thickness
            var sliceSubsamples = Math.Max(1, (int)(sliceThickness / GetIdealSliceSpacing(volumeReference, slicerAxisZ) + 0.5));

            // project the corners of the volume on to the slicer axes to determine the bounds of the volume in the slicer frame
            float minBoundsX = float.MaxValue, minBoundsY = float.MaxValue, minBoundsZ = float.MaxValue;
            float maxBoundsX = float.MinValue, maxBoundsY = float.MinValue, maxBoundsZ = float.MinValue;
            var   volumeDimensions = volumeReference.VolumeSize;

            foreach (var corner in new[]
            {
                new Vector3D(0, 0, 0),
                new Vector3D(0, 0, volumeDimensions.Z),
                new Vector3D(0, volumeDimensions.Y, 0),
                new Vector3D(0, volumeDimensions.Y, volumeDimensions.Z),
                new Vector3D(volumeDimensions.X, 0, 0),
                new Vector3D(volumeDimensions.X, 0, volumeDimensions.Z),
                new Vector3D(volumeDimensions.X, volumeDimensions.Y, 0),
                new Vector3D(volumeDimensions.X, volumeDimensions.Y, volumeDimensions.Z)
            }.Select(volumeReference.ConvertToPatient))
            {
                var projection = corner.Dot(slicerAxisX);
                if (minBoundsX > projection)
                {
                    minBoundsX = projection;
                }
                if (maxBoundsX < projection)
                {
                    maxBoundsX = projection;
                }

                projection = corner.Dot(slicerAxisY);
                if (minBoundsY > projection)
                {
                    minBoundsY = projection;
                }
                if (maxBoundsY < projection)
                {
                    maxBoundsY = projection;
                }

                projection = corner.Dot(slicerAxisZ);
                if (minBoundsZ > projection)
                {
                    minBoundsZ = projection;
                }
                if (maxBoundsZ < projection)
                {
                    maxBoundsZ = projection;
                }
            }

            // get the origin of the slicer frame in patient coordinates
            var slicerOrigin = minBoundsX * slicerAxisX + minBoundsY * slicerAxisY + minBoundsZ * slicerAxisZ;

            // get the dimensions (in patient units) of the region that bounds the volume projected to the slicer frame - i.e. the dimensions of the stack of output slices
            var stackWidth  = SliceWidth.HasValue ? SliceWidth.Value : maxBoundsX - minBoundsX;
            var stackHeight = SliceHeight.HasValue ? SliceHeight.Value : maxBoundsY - minBoundsY;
            var stackDepth  = maxBoundsZ - minBoundsZ;

            // get the rows and columns of the slice output
            var sliceColumns = Columns ?? (int)(Math.Abs(1.0 * stackWidth / pixelSpacing.Width) + 0.5);
            var sliceRows    = Rows ?? (int)(Math.Abs(1.0 * stackHeight / pixelSpacing.Height) + 0.5);

            // capture all the slicer parameters in an args object
            var args = new VolumeSliceArgs(sliceRows, sliceColumns, pixelSpacing.Height, pixelSpacing.Width, slicerAxisX, slicerAxisY, sliceThickness, sliceSubsamples, Interpolation, Projection);

            // compute the image position patient for each output slice and create the slices
            return(GetSlicePositions(slicerOrigin, slicerAxisX, slicerAxisY, slicerAxisZ, stackDepth, sliceRows, sliceColumns, pixelSpacing, sliceSpacing, sliceThickness, startPosition, endPosition, count)
                   .Select(p => new VolumeSlice(volumeReference.Clone(), true, args, p, sliceSpacing)));
        }
コード例 #49
0
ファイル: VolumeSlicer.cs プロジェクト: UIKit0/ClearCanvas
		public VolumeSlicer(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams)
		{
			_volume = volumeReference.Clone();
			_slicerParams = slicerParams;
		}
コード例 #50
0
		private IEnumerable<VolumeSlice> CreateSlicesCore(IVolumeReference volumeReference, Vector3D startPosition, Vector3D endPosition, int count)
		{
			// get the axes of the output plane and its normal in patient coordinates - these are the axes of the slicer frame
			var slicerAxisX = (RowOrientationPatient ?? volumeReference.VolumeOrientationPatientX).Normalize();
			var slicerAxisY = (ColumnOrientationPatient ?? volumeReference.VolumeOrientationPatientY).Normalize();
			var slicerAxisZ = (StackOrientationPatient ?? slicerAxisX.Cross(slicerAxisY)).Normalize();

			// get the pixel spacing (defaults to isotropic spacing based on smallest volume spacing dimension)
			var pixelSpacing = GetPixelSpacing(volumeReference);

			// get the spacing between slices (defaults to projecting voxel diagonal on to normal axis)
			var sliceSpacing = GetSliceSpacing(volumeReference, slicerAxisZ);

			// get the thickness of each slice (defaults to slice spacing)
			var sliceThickness = SliceThickness ?? sliceSpacing;

			// get the ideal subsampling for the slice thickness (if thickness exceeds threshold, create thin slices and aggregate them as a slab)
			var sliceSubsamples = Math.Max(1, (int) (sliceThickness/GetIdealSliceSpacing(volumeReference, slicerAxisZ) + 0.5));
			if (sliceSubsamples > 1) sliceSubsamples *= 2; // if slabbing required, double the subsampling rate to achieve Nyquist sampling and ensure we don't miss any data

			// project the corners of the volume on to the slicer axes to determine the bounds of the volume in the slicer frame
			float minBoundsX = float.MaxValue, minBoundsY = float.MaxValue, minBoundsZ = float.MaxValue;
			float maxBoundsX = float.MinValue, maxBoundsY = float.MinValue, maxBoundsZ = float.MinValue;
			var volumeDimensions = volumeReference.VolumeSize;
			foreach (var corner in new[]
			                       	{
			                       		new Vector3D(0, 0, 0),
			                       		new Vector3D(0, 0, volumeDimensions.Z),
			                       		new Vector3D(0, volumeDimensions.Y, 0),
			                       		new Vector3D(0, volumeDimensions.Y, volumeDimensions.Z),
			                       		new Vector3D(volumeDimensions.X, 0, 0),
			                       		new Vector3D(volumeDimensions.X, 0, volumeDimensions.Z),
			                       		new Vector3D(volumeDimensions.X, volumeDimensions.Y, 0),
			                       		new Vector3D(volumeDimensions.X, volumeDimensions.Y, volumeDimensions.Z)
			                       	}.Select(volumeReference.ConvertToPatient))
			{
				var projection = corner.Dot(slicerAxisX);
				if (minBoundsX > projection) minBoundsX = projection;
				if (maxBoundsX < projection) maxBoundsX = projection;

				projection = corner.Dot(slicerAxisY);
				if (minBoundsY > projection) minBoundsY = projection;
				if (maxBoundsY < projection) maxBoundsY = projection;

				projection = corner.Dot(slicerAxisZ);
				if (minBoundsZ > projection) minBoundsZ = projection;
				if (maxBoundsZ < projection) maxBoundsZ = projection;
			}

			// get the origin of the slicer frame in patient coordinates
			var slicerOrigin = minBoundsX*slicerAxisX + minBoundsY*slicerAxisY + minBoundsZ*slicerAxisZ;

			// get the dimensions (in patient units) of the region that bounds the volume projected to the slicer frame - i.e. the dimensions of the stack of output slices
			var stackWidth = SliceWidth.HasValue ? SliceWidth.Value : maxBoundsX - minBoundsX;
			var stackHeight = SliceHeight.HasValue ? SliceHeight.Value : maxBoundsY - minBoundsY;
			var stackDepth = maxBoundsZ - minBoundsZ;

			// get the rows and columns of the slice output
			var sliceColumns = Columns ?? (int) (Math.Abs(1.0*stackWidth/pixelSpacing.Width) + 0.5);
			var sliceRows = Rows ?? (int) (Math.Abs(1.0*stackHeight/pixelSpacing.Height) + 0.5);

			// capture all the slicer parameters in an args object
			var args = new VolumeSliceArgs(sliceRows, sliceColumns, pixelSpacing.Height, pixelSpacing.Width, slicerAxisX, slicerAxisY, sliceThickness, sliceSubsamples, Interpolation, Projection);

			// compute the image position patient for each output slice and create the slices
			var slicePositions = GetSlicePositions(slicerOrigin, slicerAxisX, slicerAxisY, slicerAxisZ, stackDepth, sliceRows, sliceColumns, pixelSpacing, sliceSpacing, sliceThickness, startPosition, endPosition, count).ToList();
			return slicePositions.Select(p => new VolumeSlice(volumeReference.Clone(), true, args, p, slicePositions.Count > 1 ? (float?) sliceSpacing : null));
		}
コード例 #51
0
        /// <summary>
        /// Gets the pixel data representing a thick slice (a.k.a. slab) of the volume.
        /// </summary>
        private static byte[] GetSlabPixelData(IVolumeReference volumeReference, Matrix resliceAxes, Vector3D stackOrientation, int rows, int columns, int subsamples, float rowSpacing, float columnSpacing, float sliceThickness, VolumeInterpolationMode interpolation, VolumeProjectionMode projection)
        {
            if (subsamples == 0)
            {
                return(GetSlicePixelData(volumeReference, resliceAxes, rows, columns, rowSpacing, columnSpacing, interpolation));
            }
            var subsampleSpacing = sliceThickness / (subsamples - 1);

            using (var reslicer = new vtkImageReslice())
                using (var resliceAxesMatrix = new vtkMatrix4x4())
                    using (var executive = reslicer.GetExecutive())
                        using (var volume = volumeReference.Volume.CreateVtkVolumeHandle())
                        {
                            // update the reslice axes matrix with the values from the slicing orientation
                            resliceAxesMatrix.SetElements(resliceAxes);

                            // determine offset for start of slab (we centre the slab on the requested slice position, as DICOM defines "image position (patient)" to be centre of the thick slice)
                            var slabOffset = volumeReference.RotateToVolumeOrientation(-sliceThickness / 2f * stackOrientation) + new Vector3D(resliceAxes[0, 3], resliceAxes[1, 3], resliceAxes[2, 3]);
                            resliceAxesMatrix.SetElement(0, 3, slabOffset.X);
                            resliceAxesMatrix.SetElement(1, 3, slabOffset.Y);
                            resliceAxesMatrix.SetElement(2, 3, slabOffset.Z);

                            // register for errors on the reslicer
                            reslicer.RegisterVtkErrorEvents();

                            // set input to the volume
                            reslicer.SetInput(volume.vtkImageData);
                            reslicer.SetInformationInput(volume.vtkImageData);

                            // instruct reslicer to output a 3D slab volume
                            reslicer.SetOutputDimensionality(3);

                            // use the volume's padding value for all pixels that are outside the volume
                            reslicer.SetBackgroundLevel(volumeReference.PaddingValue);

                            // ensure the slicer outputs at our desired spacing
                            reslicer.SetOutputSpacing(columnSpacing, rowSpacing, subsampleSpacing);

                            // set the reslice axes
                            reslicer.SetResliceAxes(resliceAxesMatrix);

                            // clamp the output based on the slice extent
                            reslicer.SetOutputExtent(0, columns - 1, 0, rows - 1, 0, subsamples - 1);

                            // set the output origin to the slice through-point (output image will be centered on this location)
                            // VTK output origin is derived from the center image being 0,0
                            reslicer.SetOutputOrigin(-columns * columnSpacing / 2, -rows * rowSpacing / 2, 0);

                            // select the requested interpolation mode
                            switch (interpolation)
                            {
                            case VolumeInterpolationMode.NearestNeighbor:
                                reslicer.SetInterpolationModeToNearestNeighbor();
                                break;

                            case VolumeInterpolationMode.Linear:
                                reslicer.SetInterpolationModeToLinear();
                                break;

                            case VolumeInterpolationMode.Cubic:
                                reslicer.SetInterpolationModeToCubic();
                                break;
                            }

                            // select the requested slab projection mode
                            Action <IntPtr, byte[], int, int, int, bool> slabAggregator;
                            switch (projection)
                            {
                            case VolumeProjectionMode.Maximum:
                                slabAggregator = SlabProjection.AggregateSlabMaximumIntensity;
                                break;

                            case VolumeProjectionMode.Minimum:
                                slabAggregator = SlabProjection.AggregateSlabMinimumIntensity;
                                break;

                            case VolumeProjectionMode.Average:
                            default:
                                slabAggregator = SlabProjection.AggregateSlabAverageIntensity;
                                break;
                            }

                            // register for errors on the reslicer executive
                            executive.RegisterVtkErrorEvents();
                            executive.Update();

                            // get the slice output
                            using (var imageData = reslicer.GetOutput())
                            {
                                var pixelData = SlabVtkImageData(imageData, slabAggregator, volumeReference.BitsPerVoxel, volumeReference.Signed);
                                imageData.ReleaseData();
                                return(pixelData);
                            }
                        }
        }
コード例 #52
0
        /// <summary>
        /// Creates <see cref="VolumeSlice"/>s representing slices in a <see cref="Volume"/>.
        /// </summary>
        /// <param name="volumeReference">A <see cref="IVolumeReference"/> for the <see cref="Volume"/>.</param>
        /// <returns>A list of <see cref="VolumeSlice"/> instances representing the slices.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="volumeReference"/> is null.</exception>
        public IList <VolumeSlice> CreateSlices(IVolumeReference volumeReference)
        {
            Platform.CheckForNullReference(volumeReference, "volumeReference");

            return(CreateSlicesCore(volumeReference, null, null, 0).ToList());
        }
コード例 #53
0
 /// <summary>
 /// Initializes a new instance of <see cref="VtkVolumeSlicerCore"/>.
 /// </summary>
 /// <param name="volumeReference"></param>
 /// <param name="args"></param>
 public VtkVolumeSlicerCore(IVolumeReference volumeReference, VolumeSliceArgs args)
     : base(volumeReference, args)
 {
 }
コード例 #54
0
ファイル: VolumeSlice.cs プロジェクト: m-berkani/ClearCanvas
		public VolumeSlice(IVolumeReference volumeReference, bool ownReference, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float? spacingBetweenSlices = null)
			: this(ownReference ? volumeReference : volumeReference.Clone(), sliceArgs, imagePositionPatient, spacingBetweenSlices) {}
コード例 #55
0
 public VolumeSlice(IVolumeReference volumeReference, bool ownReference, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float?spacingBetweenSlices = null)
     : this(ownReference ? volumeReference : volumeReference.Clone(), sliceArgs, imagePositionPatient, spacingBetweenSlices)
 {
 }
コード例 #56
0
ファイル: VolumeSlice.cs プロジェクト: m-berkani/ClearCanvas
		protected virtual void Dispose(bool disposing)
		{
			if (!disposing) return;

			if (_volumeReference != null)
			{
				_volumeReference.Dispose();
				_volumeReference = null;
			}

			_sliceArgs = null;
			_imagePositionPatient = null;
		}