Пример #1
0
        internal static void Launch(IDesktopWindow desktopWindow, List <IClipboardItem> clipboardItems)
        {
            Platform.CheckForNullReference(desktopWindow, "desktopWindow");
            Platform.CheckForNullReference(clipboardItems, "clipboardItems");

            if (_multipleImageExporter != null)
            {
                desktopWindow.ShowMessageBox(SR.MessageImageExportStillRunning, MessageBoxActions.Ok);
                return;
            }

            int numberOfImagesToExport = GetNumberOfImagesToExport(clipboardItems);

            Platform.CheckPositive(numberOfImagesToExport, "numberOfImagesToExport");

            string title = SR.TitleExportImages;

            if (numberOfImagesToExport == 1)
            {
                title = SR.TitleExportSingleImage;
            }

            //initialize the component.
            ImageExportComponent component = new ImageExportComponent();

            component.ItemsToExport          = clipboardItems;
            component.NumberOfImagesToExport = numberOfImagesToExport;

            // give the width and height values from the first image to be exported
            if (clipboardItems.Count > 0)
            {
                object item = clipboardItems[0].Item;
                if (item is IImageGraphicProvider)
                {
                    IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)item;
                    component.Height = imageGraphicProvider.ImageGraphic.Rows;
                    component.Width  = imageGraphicProvider.ImageGraphic.Columns;
                }
                else if (item is IDisplaySet)
                {
                    foreach (IPresentationImage image in ((IDisplaySet)item).PresentationImages)
                    {
                        if (image is IImageGraphicProvider)
                        {
                            IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image;
                            component.Height = imageGraphicProvider.ImageGraphic.Rows;
                            component.Width  = imageGraphicProvider.ImageGraphic.Columns;
                            break;
                        }
                    }
                }
            }

            if (ApplicationComponentExitCode.Accepted != LaunchAsDialog(desktopWindow, component, title))
            {
                return;
            }

            component.Export();
        }
Пример #2
0
        private void AnalyzeInternal()
        {
            IPresentationImage       presImage            = this.ImageViewer.SelectedPresentationImage;
            IImageGraphicProvider    imageGraphicProvider = presImage as IImageGraphicProvider;
            GrayscaleImageGraphic    imageGraphic         = imageGraphicProvider.ImageGraphic as GrayscaleImageGraphic;
            IOverlayGraphicsProvider overlayProvider      = presImage as IOverlayGraphicsProvider;

            CadOverlayGraphic cadOverlay = GetCadOverlayGraphic(overlayProvider);

            if (cadOverlay == null)
            {
                cadOverlay = new CadOverlayGraphic(imageGraphic);
                overlayProvider.OverlayGraphics.Add(cadOverlay);
            }

            MemorableUndoableCommand command = new MemorableUndoableCommand(cadOverlay);

            command.BeginState   = cadOverlay.CreateMemento();
            cadOverlay.Threshold = (int)this.Threshold;
            cadOverlay.Opacity   = (int)this.Opacity;
            cadOverlay.Analyze();
            command.EndState = cadOverlay.CreateMemento();

            this.ImageViewer.CommandHistory.AddCommand(command);
        }
Пример #3
0
		/// <summary>
		/// Constructs a new region of interest, specifying an <see cref="IPresentationImage"/> as the source of the pixel data.
		/// </summary>
		/// <param name="presentationImage">The image containing the source pixel data.</param>
		protected Roi(IPresentationImage presentationImage)
		{
			IImageGraphicProvider provider = presentationImage as IImageGraphicProvider;
			if (provider == null)
				return;

			_imageRows = provider.ImageGraphic.Rows;
			_imageColumns = provider.ImageGraphic.Columns;
			_presentationImage = presentationImage;

			_pixelData = provider.ImageGraphic.PixelData;
			if (presentationImage is IModalityLutProvider)
				_modalityLut = ((IModalityLutProvider) presentationImage).ModalityLut;

			if (presentationImage is IImageSopProvider)
			{
				Frame frame = ((IImageSopProvider) presentationImage).Frame;
				_normalizedPixelSpacing = frame.NormalizedPixelSpacing;
				_pixelAspectRatio = frame.PixelAspectRatio;
				_modality = frame.ParentImageSop.Modality;
				_modalityLutUnits = frame.RescaleUnits;
				_subnormalModalityLut = frame.IsSubnormalRescale;
			}
			else
			{
				_normalizedPixelSpacing = new PixelSpacing(0, 0);
				_pixelAspectRatio = new PixelAspectRatio(0, 0);
				_modalityLutUnits = RescaleUnits.None;
				_subnormalModalityLut = false;
			}
		}
        private static void TestVolume(bool signed, VolumeFunction f, IEnumerable <IVolumeSlicerParams> slicerParams, string testName, ImageKernelFunction imageKernel, VolumeKernelFunction volumeKernel)
        {
            const int      FULL_SCALE         = 65535;
            VolumeFunction normalizedFunction = f.Normalize(100);

            using (Volume volume = normalizedFunction.CreateVolume(100, signed))
            {
                float offset = signed ? -32768 : 0;
                foreach (IVolumeSlicerParams slicing in slicerParams)
                {
                    List <double> list = new List <double>();
                    using (VolumeSlicer slicer = new VolumeSlicer(volume, slicing, DicomUid.GenerateUid().UID))
                    {
                        foreach (ISopDataSource slice in slicer.CreateSlices())
                        {
                            using (ImageSop imageSop = new ImageSop(slice))
                            {
                                foreach (IPresentationImage image in PresentationImageFactory.Create(imageSop))
                                {
                                    IImageSopProvider     imageSopProvider     = (IImageSopProvider)image;
                                    IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image;
                                    DicomImagePlane       dip = DicomImagePlane.FromImage(image);

                                    for (int y = 1; y < imageSopProvider.Frame.Rows - 1; y++)
                                    {
                                        for (int x = 1; x < imageSopProvider.Frame.Columns - 1; x++)
                                        {
                                            // pixels on the extreme sides of the volume tend to have more interpolation error due to MPR padding values
                                            Vector3D vector = dip.ConvertToPatient(new PointF(x, y));                                             // +new Vector3D(-0.5f, -0.5f, 0);
                                            if (Between(vector.X, 1, 98) && Between(vector.Y, 1, 98) && Between(vector.Z, 1, 98))
                                            {
                                                float expected = volumeKernel.Invoke(normalizedFunction, vector.X, vector.Y, vector.Z) + offset;
                                                float actual   = imageKernel.Invoke(imageGraphicProvider.ImageGraphic.PixelData, x, y);
                                                list.Add(Math.Abs(expected - actual));
                                            }
                                        }
                                    }

                                    image.Dispose();
                                }
                            }
                            slice.Dispose();
                        }
                    }

                    Statistics stats = new Statistics(list);
                    Trace.WriteLine(string.Format("Testing {0}", testName));
                    Trace.WriteLine(string.Format("\tFunction/Slicing: {0} / {1}", normalizedFunction.Name, slicing.Description));
                    Trace.WriteLine(string.Format("\t       Pixel Rep: {0}", signed ? "signed" : "unsigned"));
                    Trace.WriteLine(string.Format("\t Voxels Compared: {0}", list.Count));
                    Trace.WriteLine(string.Format("\t      Mean Delta: {0:f2} ({1:p2} of full scale)", stats.Mean, stats.Mean / FULL_SCALE));
                    Trace.WriteLine(string.Format("\t    StdDev Delta: {0:f2} ({1:p2} of full scale)", stats.StandardDeviation, stats.StandardDeviation / FULL_SCALE));
                    Assert.Less(stats.Mean, FULL_SCALE * 0.05, "Mean delta exceeds 5% of full scale ({0})", FULL_SCALE);
                    Assert.Less(stats.StandardDeviation, FULL_SCALE * 0.05, "StdDev delta exceeds 5% of full scale ({0})", FULL_SCALE);
                }
            }
        }
Пример #5
0
        protected static void ValidateVolumeSlicePoints(Volumes.Volume volume, IVolumeSlicerParams slicerParams, IList <KnownSample> expectedPoints,
                                                        double xAxialGantryTilt, double yAxialGantryTilt, bool gantryTiltInDegrees)
        {
            if (gantryTiltInDegrees)
            {
                xAxialGantryTilt *= Math.PI / 180;
                yAxialGantryTilt *= Math.PI / 180;
            }

            Trace.WriteLine(string.Format("Using slice plane: {0}", slicerParams.Description));
            using (VolumeSlicer slicer = new VolumeSlicer(volume, slicerParams))
            {
                foreach (ISopDataSource slice in slicer.CreateSliceSops())
                {
                    using (ImageSop imageSop = new ImageSop(slice))
                    {
                        foreach (IPresentationImage image in PresentationImageFactory.Create(imageSop))
                        {
                            IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image;
                            DicomImagePlane       dip = DicomImagePlane.FromImage(image);

                            foreach (KnownSample sample in expectedPoints)
                            {
                                Vector3D patientPoint = sample.Point;
                                if (xAxialGantryTilt != 0 && yAxialGantryTilt == 0)
                                {
                                    float cos = (float)Math.Cos(xAxialGantryTilt);
                                    float sin = (float)Math.Sin(xAxialGantryTilt);
                                    patientPoint = new Vector3D(patientPoint.X,
                                                                patientPoint.Y * cos + (xAxialGantryTilt > 0 ? 100 * sin : 0),
                                                                patientPoint.Z / cos - patientPoint.Y * sin - (xAxialGantryTilt > 0 ? 100 * sin * sin / cos : 0));
                                }
                                else if (yAxialGantryTilt != 0)
                                {
                                    Assert.Fail("Unit test not designed to work with gantry tilts about Y (i.e. slew)");
                                }

                                Vector3D slicedPoint = dip.ConvertToImagePlane(patientPoint);
                                if (slicedPoint.Z > -0.5 && slicedPoint.Z < 0.5)
                                {
                                    int actual = imageGraphicProvider.ImageGraphic.PixelData.GetPixel((int)slicedPoint.X, (int)slicedPoint.Y);
                                    Trace.WriteLine(string.Format("Sample {0} @{1} (SLICE: {2}; PATIENT: {3})", actual, FormatVector(sample.Point), FormatVector(slicedPoint), FormatVector(patientPoint)));
                                    Assert.AreEqual(sample.Value, actual, "Wrong colour sample @{0}", sample.Point);
                                }
                            }

                            image.Dispose();
                        }
                    }
                    slice.Dispose();
                }
            }
        }
Пример #6
0
        internal static void Launch(IDesktopWindow desktopWindow, ClipboardItem clipboardItem)
        {
            Platform.CheckForNullReference(clipboardItem, "clipboardItem");
            IDisplaySet displaySet = clipboardItem.Item as IDisplaySet;

            if (displaySet == null)
            {
                throw new ArgumentException("The item being exported must be a display set.");
            }

            if (_progressComponentShelf != null)
            {
                desktopWindow.ShowMessageBox(SR.MessageVideoExportStillRunning, MessageBoxActions.Ok);
                return;
            }

            if (displaySet.PresentationImages.Count <= 1)
            {
                desktopWindow.ShowMessageBox(SR.MessageDisplaySetTooFewImagesForVideo, MessageBoxActions.Ok);
                return;
            }

            AviExportComponent component = new AviExportComponent(clipboardItem);

            component.LoadSettings();
            if (component.SelectedCodec == null)
            {
                desktopWindow.ShowMessageBox(SR.MessageNoAcceptableCodecsInstalled, MessageBoxActions.Ok);
                return;
            }

            // give the width and height values from the item to be exported
            foreach (IPresentationImage image in (displaySet.PresentationImages))
            {
                if (image is IImageGraphicProvider)
                {
                    IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image;
                    component.Height = imageGraphicProvider.ImageGraphic.Rows;
                    component.Width  = imageGraphicProvider.ImageGraphic.Columns;
                    break;
                }
            }

            if (ApplicationComponentExitCode.Accepted != LaunchAsDialog(desktopWindow, component, SR.TitleExportToVideo))
            {
                return;
            }

            component.Export();
        }
Пример #7
0
        private void AddUnsignedSliceToVolume(ushort[] volumeData, IImageGraphicProvider slice, int imageIndex)
        {
            byte[] sliceData = slice.ImageGraphic.PixelData.Raw;
            int    start     = imageIndex * sliceData.Length / 2;
            int    end       = start + sliceData.Length / 2;

            int j = 0;

            for (int i = start; i < end; i++)
            {
                ushort lowbyte  = sliceData[j];
                ushort highbyte = sliceData[j + 1];
                volumeData[i] = (ushort)((highbyte << 8) | lowbyte);
                j            += 2;
            }
        }
        private void AddPinwheelGraphic()
        {
            IPresentationImage selectedImage = base.SelectedPresentationImage;

            if (selectedImage == null)
            {
                return;
            }

            if (!base.IsMprImage(selectedImage))
            {
                return;
            }

            MprDisplaySet displaySet = (MprDisplaySet)selectedImage.ParentDisplaySet;

            if (displaySet.Identifier == MprDisplaySetIdentifier.Oblique)
            {
                return;
            }

            IOverlayGraphicsProvider overlayProvider      = selectedImage as IOverlayGraphicsProvider;
            IImageGraphicProvider    imageGraphicProvider = selectedImage as IImageGraphicProvider;

            if (overlayProvider != null && imageGraphicProvider != null)
            {
                _currentPinwheelGraphic = new PinwheelGraphic();

                int width  = imageGraphicProvider.ImageGraphic.Columns;
                int height = imageGraphicProvider.ImageGraphic.Rows;

                overlayProvider.OverlayGraphics.Add(_currentPinwheelGraphic);
                _currentPinwheelGraphic.CoordinateSystem = CoordinateSystem.Source;
                _currentPinwheelGraphic.Rotation         = GetRotationAngle();
                _currentPinwheelGraphic.Draw();
            }
        }
Пример #9
0
        public static Bitmap DrawToBitmap(IPresentationImage image, ExportImageParams exportParams)
        {
            Platform.CheckForNullReference(image, "image");
            Platform.CheckForNullReference(exportParams, "exportParams");

            if (!(image is ISpatialTransformProvider) || !(image is IImageGraphicProvider))
            {
                throw new ArgumentException("The image must implement IImageGraphicProvider and have a valid ImageSpatialTransform in order to be exported.");
            }

            if (exportParams.ExportOption == ExportOption.TrueSize)
            {
                var imageSopProvider = image as IImageSopProvider;
                var pixelSpacing     = imageSopProvider == null ? null : imageSopProvider.Frame.NormalizedPixelSpacing;
                if (pixelSpacing == null || pixelSpacing.IsNull)
                {
                    throw new ArgumentException("The image does not contain pixel spacing information.  TrueSize export is not possible.");
                }
            }

            ImageSpatialTransform transform = ((ISpatialTransformProvider)image).SpatialTransform as ImageSpatialTransform;

            if (transform == null)
            {
                throw new ArgumentException("The image must have a valid ImageSpatialTransform in order to be exported.");
            }

            if (exportParams.ExportOption == ExportOption.TrueSize)
            {
                return(DrawTrueSizeImageToBitmap(image, exportParams.OutputSize, exportParams.Dpi));
            }

            if (exportParams.SizeMode == SizeMode.Scale)
            {
                // TODO: Refactor ImageExporter, so there only the displayRectangle and OutputRectangle are provided
                //		Scale can be automatically figured out.
                //		A "Padded" option can be provided to distinguish between the current Fixed and ScaleToFit options
                // TODO: Refactor ImageExporter, so there are separate exporters for each ExportOption.
                //		The ExportImageParams is getting too many options and not all of them are applicable to each exporter
                //		Instead, each exporter should have its own parameters.

                if (exportParams.ExportOption == ExportOption.Wysiwyg)
                {
                    return(DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, exportParams.Scale, exportParams.Dpi));
                }
                else
                {
                    return(DrawCompleteImageToBitmap(image, exportParams.Scale, exportParams.Dpi));
                }
            }
            else if (exportParams.SizeMode == SizeMode.ScaleToFit)
            {
                if (exportParams.ExportOption == ExportOption.Wysiwyg)
                {
                    var scale = ScaleToFit(exportParams.DisplayRectangle.Size, exportParams.OutputSize);
                    return(DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, scale, exportParams.Dpi));
                }
                else
                {
                    var sourceImage = (IImageGraphicProvider)image;
                    var scale       = ScaleToFit(new Size(sourceImage.ImageGraphic.Columns, sourceImage.ImageGraphic.Rows), exportParams.OutputSize);
                    return(DrawCompleteImageToBitmap(image, scale, exportParams.Dpi));
                }
            }
            else
            {
                Bitmap paddedImage = new Bitmap(exportParams.OutputSize.Width, exportParams.OutputSize.Height);
                using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(paddedImage))
                {
                    // paint background
                    using (Brush b = new SolidBrush(exportParams.BackgroundColor))
                    {
                        graphics.FillRectangle(b, new Rectangle(Point.Empty, exportParams.OutputSize));
                    }

                    // paint image portion
                    Bitmap bmp;
                    if (exportParams.ExportOption == ExportOption.Wysiwyg)
                    {
                        float scale = ScaleToFit(exportParams.DisplayRectangle.Size, exportParams.OutputSize);
                        bmp = DrawWysiwygImageToBitmap(image, exportParams.DisplayRectangle, scale, exportParams.Dpi);
                    }
                    else
                    {
                        IImageGraphicProvider sourceImage = (IImageGraphicProvider)image;
                        float scale = ScaleToFit(new Size(sourceImage.ImageGraphic.Columns, sourceImage.ImageGraphic.Rows), exportParams.OutputSize);
                        bmp = DrawCompleteImageToBitmap(image, scale, exportParams.Dpi);
                    }
                    graphics.DrawImageUnscaledAndClipped(bmp, new Rectangle(CenterRectangles(bmp.Size, exportParams.OutputSize), bmp.Size));
                    bmp.Dispose();
                }

                return(paddedImage);
            }
        }
Пример #10
0
        public bool ComputeProfile()
        {
            IPointsGraphic line = GetSelectedPolyline();

            // For now, make sure the ROI is a polyline
            if (line == null || line.Points.Count != 2)
            {
                this.Enabled = false;
                return(false);
            }

            IImageGraphicProvider imageGraphicProvider =
                line.ParentPresentationImage as IImageGraphicProvider;

            if (imageGraphicProvider == null)
            {
                this.Enabled = false;
                return(false);
            }

            // For now, only allow ROIs of grayscale images
            GrayscaleImageGraphic image = imageGraphicProvider.ImageGraphic as GrayscaleImageGraphic;

            if (image == null)
            {
                this.Enabled = false;
                return(false);
            }

            line.CoordinateSystem = CoordinateSystem.Source;
            Point pt1 = new Point((int)line.Points[0].X, (int)line.Points[0].Y);
            Point pt2 = new Point((int)line.Points[1].X, (int)line.Points[1].Y);

            if (pt1.X < 0 || pt1.X > image.Columns - 1 ||
                pt2.X < 0 || pt2.X > image.Columns - 1 ||
                pt1.Y < 0 || pt1.Y > image.Rows - 1 ||
                pt2.Y < 0 || pt2.Y > image.Rows - 1)
            {
                this.Enabled = false;
                return(false);
            }


            List <Point> pixels = BresenhamLine(pt1, pt2);

            _pixelIndices = new int[pixels.Count];
            _pixelValues  = new double[pixels.Count];

            int i = 0;

            foreach (Point pixel in pixels)
            {
                int rawPixelValue = image.PixelData.GetPixel(pixel.X, pixel.Y);
                _pixelIndices[i] = i;
                _pixelValues[i]  = (int)image.ModalityLut[rawPixelValue];
                i++;
            }

            this.Enabled = true;
            return(true);
        }
Пример #11
0
		private void AddSignedSliceToVolume(ushort[] volumeData, IImageGraphicProvider slice, int imageIndex)
		{
			byte[] sliceData = slice.ImageGraphic.PixelData.Raw;
			int start = imageIndex * sliceData.Length / 2;
			int end = start + sliceData.Length / 2;

			int j = 0;

			for (int i = start; i < end; i++)
			{
				ushort lowbyte = sliceData[j];
				ushort highbyte = sliceData[j + 1];

				short val = (short)((highbyte << 8) | lowbyte);
				volumeData[i] = (ushort)(val - _minimumPixelValue);

				j += 2;
			}
		}