Exemple #1
0
			/// <summary>
			/// Validates and prepares the provided frames for the <see cref="VolumeBuilder"/>.
			/// </summary>
			/// <exception cref="CreateVolumeException">Thrown if something is wrong with the source frames.</exception>
			public static void PrepareFrames(List<IFrameReference> _frames)
			{
				// ensure we have at least 3 frames
				if (_frames.Count < 3)
					throw new InsufficientFramesException();

				// ensure all frames have are from the same series, and have the same frame of reference
				string studyInstanceUid = _frames[0].Frame.StudyInstanceUid;
				string seriesInstanceUid = _frames[0].Frame.SeriesInstanceUid;
				string frameOfReferenceUid = _frames[0].Frame.FrameOfReferenceUid;

				if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid))
					throw new NullSourceSeriesException();
				if (string.IsNullOrEmpty(frameOfReferenceUid))
					throw new NullFrameOfReferenceException();

				foreach (IFrameReference frame in _frames)
				{
					if (frame.Frame.StudyInstanceUid != studyInstanceUid)
						throw new MultipleSourceSeriesException();
					if (frame.Frame.SeriesInstanceUid != seriesInstanceUid)
						throw new MultipleSourceSeriesException();
					if (frame.Frame.FrameOfReferenceUid != frameOfReferenceUid)
						throw new MultipleFramesOfReferenceException();
				}

				// ensure all frames are of the same supported format
				foreach (IFrameReference frame in _frames)
				{
					if (frame.Frame.BitsAllocated != 16)
						throw new UnsupportedPixelFormatSourceImagesException();
				}

				// ensure all frames have the same orientation
				ImageOrientationPatient orient = _frames[0].Frame.ImageOrientationPatient;
				foreach (IFrameReference frame in _frames)
				{
					if (frame.Frame.ImageOrientationPatient.IsNull)
					{
						if (frame.ImageSop.NumberOfFrames > 1)
							throw new UnsupportedMultiFrameSourceImagesException(new NullImageOrientationException());
						throw new NullImageOrientationException();
					}
					if (!frame.Frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance))
						throw new MultipleImageOrientationsException();
					if (frame.Frame.PixelSpacing.IsNull)
						throw new UncalibratedFramesException();
					if (Math.Abs(frame.Frame.PixelSpacing.AspectRatio - 1) > _minimumSliceSpacing)
						throw new AnisotropicPixelAspectRatioException();
				}

				// ensure all frames are sorted by slice location
				SliceLocationComparer sliceLocationComparer = new SliceLocationComparer();
				_frames.Sort(delegate(IFrameReference x, IFrameReference y) { return sliceLocationComparer.Compare(x.Frame, y.Frame); });

				// ensure all frames are equally spaced
				float? nominalSpacing = null;
				for (int i = 1; i < _frames.Count; i++)
				{
					float currentSpacing = CalcSpaceBetweenPlanes(_frames[i].Frame, _frames[i - 1].Frame);
					if (currentSpacing < _minimumSliceSpacing)
					{
						if (_frames[i].ImageSop.NumberOfFrames > 1)
							throw new UnsupportedMultiFrameSourceImagesException(new UnevenlySpacedFramesException());
						throw new UnevenlySpacedFramesException();
					}

					if (!nominalSpacing.HasValue)
						nominalSpacing = currentSpacing;
					if (!FloatComparer.AreEqual(currentSpacing, nominalSpacing.Value, _sliceSpacingTolerance))
						throw new UnevenlySpacedFramesException();
				}

				// ensure frames are not tilted about unsupposed axis combinations (the gantry correction algorithm only supports rotations about X)
				if (!IsSupportedGantryTilt(_frames)) // suffices to check first one... they're all co-planar now!!
					throw new UnsupportedGantryTiltAxisException();
			}
			/// <summary>
			/// Validates and prepares the provided frames for the <see cref="VolumeBuilder"/>.
			/// </summary>
			/// <exception cref="CreateVolumeException">Thrown if something is wrong with the source frames.</exception>
			public static void PrepareFrames(List<IFrameReference> frames)
			{
				// ensure we have at least 3 frames
				if (frames.Count < 3)
					throw new InsufficientFramesException();

				// ensure all frames have are from the same series, and have the same frame of reference
				string studyInstanceUid = frames[0].Frame.StudyInstanceUid;
				string seriesInstanceUid = frames[0].Frame.SeriesInstanceUid;
				string frameOfReferenceUid = frames[0].Frame.FrameOfReferenceUid;

				if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid))
					throw new NullSourceSeriesException();
				if (string.IsNullOrEmpty(frameOfReferenceUid))
					throw new NullFrameOfReferenceException();

				foreach (IFrameReference frame in frames)
				{
					if (frame.Frame.StudyInstanceUid != studyInstanceUid)
						throw new MultipleSourceSeriesException();
					if (frame.Frame.SeriesInstanceUid != seriesInstanceUid)
						throw new MultipleSourceSeriesException();
					if (frame.Frame.FrameOfReferenceUid != frameOfReferenceUid)
						throw new MultipleFramesOfReferenceException();
				}

				// ensure all frames are of the same supported format
				if (frames.Any(frame => frame.Frame.BitsAllocated != 16))
					throw new UnsupportedPixelFormatSourceImagesException();

				// ensure all frames have the same rescale function units
				if (frames.Select(frame => frame.Frame.RescaleUnits).Distinct().Count() > 1)
					throw new InconsistentRescaleFunctionTypeException();

				// ensure all frames have the same orientation
				var orient = frames[0].Frame.ImageOrientationPatient;
				var laterality = frames[0].Frame.Laterality;
				foreach (IFrameReference frame in frames)
				{
					if (frame.Frame.ImageOrientationPatient.IsNull)
						throw new NullImageOrientationException();
					if (!frame.Frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance))
						throw new MultipleImageOrientationsException();
					if (frame.Frame.PixelSpacing.IsNull)
						throw new UncalibratedFramesException();
					if (Math.Abs(frame.Frame.PixelSpacing.AspectRatio - 1) > _sliceSpacingTolerance)
						throw new AnisotropicPixelAspectRatioException();
					if (laterality != frame.Frame.Laterality)
						throw new InconsistentImageLateralityException();
				}

				// ensure all frames are sorted by slice location
				SliceLocationComparer sliceLocationComparer = new SliceLocationComparer();
				frames.Sort((x, y) => sliceLocationComparer.Compare(x.Frame, y.Frame));

				// ensure all frames are evenly spaced
				var spacing = new float[frames.Count - 1];
				for (int i = 1; i < frames.Count; i++)
				{
					float currentSpacing = CalcSpaceBetweenPlanes(frames[i].Frame, frames[i - 1].Frame);
					if (currentSpacing < _minimumSliceSpacing)
						throw new UnevenlySpacedFramesException();

					spacing[i - 1] = currentSpacing;
				}
				if (spacing.Max() - spacing.Min() > 2*_sliceSpacingTolerance)
					throw new UnevenlySpacedFramesException();

				// ensure frames are not skewed about unsupported axis combinations (this volume builder only normalizes for skew between the Y-axis and XZ-plane in the source data)
				if (!IsSupportedSourceSkew(frames))
					throw new UnsupportedGantryTiltAxisException();
			}