Ejemplo n.º 1
0
            /// <summary>
            /// Builds the volume array. Takes care of Gantry Tilt correction (pads rows at top/bottom accordingly)
            /// </summary>
            private ushort[] BuildVolumeArray(ushort pixelPadValue, double normalizedSlope, double normalizedIntercept, out int minVolumeValue, out int maxVolumeValue)
            {
                var volumeSize = VolumeSize;
                var volumeData = MemoryManager.Allocate <ushort>(volumeSize.Volume, TimeSpan.FromSeconds(10));

                var refFramePos = _frames[0].Frame.ImagePlaneHelper.ImagePositionPatientVector;
                var paddingRows = PaddingRows;
                var skewAngleY  = SkewAngleY;

                var volumePaddedFrameSize = volumeSize.Width * volumeSize.Height;

                var progressCallback = new FrameCopyProgressTracker(_frames.Count, _callback);
                var frameRanges      = Enumerable.Range(0, _frames.Count)
                                       .AsParallel2()
                                       .Select(n =>
                {
                    var position    = n * volumePaddedFrameSize;
                    var sourceFrame = _frames[n].Frame;

                    int paddingTopRows = 0, paddingBottomRows = 0;
                    if (paddingRows > 0)
                    {
                        // determine the number of rows to be padded at top and bottom
                        var framePadRowsMm = Math.Sin(skewAngleY) * (refFramePos - sourceFrame.ImagePlaneHelper.ImagePositionPatientVector).Magnitude;
                        var framePadRows   = Math.Min(paddingRows, (int)(Math.Abs(framePadRowsMm / VoxelSpacing.Y) + 0.5f));

                        // when the skew angle is negative, the above calculation gives the rows to pad at the top of the frame
                        paddingTopRows    = skewAngleY < 0 ? framePadRows : paddingRows - framePadRows;
                        paddingBottomRows = paddingRows - paddingTopRows;
                    }

                    int frameMinPixelValue, frameMaxPixelValue;
                    using (var lutFactory = LutFactory.Create())                                                         // lut factory isn't thread safe, so we create one when needed in the worker thread
                        FillVolumeFrame(volumeData, position, volumeSize.Width, sourceFrame, pixelPadValue, normalizedSlope, normalizedIntercept, paddingTopRows, paddingBottomRows, lutFactory, out frameMinPixelValue, out frameMaxPixelValue);
                    progressCallback.IncrementAndNotify();
                    return(new { Min = frameMinPixelValue, Max = frameMaxPixelValue });
                }).ToList();

                minVolumeValue = frameRanges.Select(r => r.Min).Min();
                maxVolumeValue = frameRanges.Select(r => r.Max).Max();
                return(volumeData);
            }
Ejemplo n.º 2
0
			/// <summary>
			/// Builds the volume array. Takes care of Gantry Tilt correction (pads rows at top/bottom accordingly)
			/// </summary>
			private ushort[] BuildVolumeArray(ushort pixelPadValue, double normalizedSlope, double normalizedIntercept, out int minVolumeValue, out int maxVolumeValue)
			{
				var volumeSize = VolumeSize;
				var volumeData = MemoryManager.Allocate<ushort>(volumeSize.Volume, TimeSpan.FromSeconds(10));

				var refFramePos = _frames[0].Frame.ImagePlaneHelper.ImagePositionPatientVector;
				var paddingRows = PaddingRows;
				var skewAngleY = SkewAngleY;

				var volumePaddedFrameSize = volumeSize.Width*volumeSize.Height;

				var progressCallback = new FrameCopyProgressTracker(_frames.Count, _callback);
				var frameRanges = Enumerable.Range(0, _frames.Count)
				                            .AsParallel2()
				                            .Select(n =>
				                                    {
					                                    var position = n*volumePaddedFrameSize;
					                                    var sourceFrame = _frames[n].Frame;

					                                    int paddingTopRows = 0, paddingBottomRows = 0;
					                                    if (paddingRows > 0)
					                                    {
						                                    // determine the number of rows to be padded at top and bottom
						                                    var framePadRowsMm = Math.Sin(skewAngleY)*(refFramePos - sourceFrame.ImagePlaneHelper.ImagePositionPatientVector).Magnitude;
						                                    var framePadRows = Math.Min(paddingRows, (int) (Math.Abs(framePadRowsMm/VoxelSpacing.Y) + 0.5f));

						                                    // when the skew angle is negative, the above calculation gives the rows to pad at the top of the frame
						                                    paddingTopRows = skewAngleY < 0 ? framePadRows : paddingRows - framePadRows;
						                                    paddingBottomRows = paddingRows - paddingTopRows;
					                                    }

					                                    int frameMinPixelValue, frameMaxPixelValue;
					                                    using (var lutFactory = LutFactory.Create()) // lut factory isn't thread safe, so we create one when needed in the worker thread
						                                    FillVolumeFrame(volumeData, position, volumeSize.Width, sourceFrame, pixelPadValue, normalizedSlope, normalizedIntercept, paddingTopRows, paddingBottomRows, lutFactory, out frameMinPixelValue, out frameMaxPixelValue);
					                                    progressCallback.IncrementAndNotify();
					                                    return new {Min = frameMinPixelValue, Max = frameMaxPixelValue};
				                                    }).ToList();

				minVolumeValue = frameRanges.Select(r => r.Min).Min();
				maxVolumeValue = frameRanges.Select(r => r.Max).Max();
				return volumeData;
			}