Beispiel #1
0
        public long GetOptimalQFactor(int imageWidth, int imageHeight, IImageSopProvider sop)
        {
            // TODO: It's probably better to adjust this dynamically
            // based on: connection speed, bitdepth and pixel value range, 
            // zoom level (can be more aggressive at 5x than at 1x or otherwise), 
            // action: zoom, stack, pan

            // We don't need to change the quality if the previous image
            // already < 32K
            //if (_prevImageSize >0 && _prevImageSize < 1024*30)
            //{
            //    return _quality;
            //}

            //float zoomLevel = 1.0f;
            //if (sop is ISpatialTransformProvider)
            //    zoomLevel = (sop as ISpatialTransformProvider).SpatialTransform.Scale;

            long lowestQuality = 50L;
            int highBit = sop.Frame.HighBit;

            if (highBit <= 8)
            {
                foreach (long k in _8bitImageSizeToQMap.Keys)
                {
                    if (k > imageWidth * imageHeight)
                        return _8bitImageSizeToQMap[k];

                    lowestQuality = _8bitImageSizeToQMap[k];
                }

                return lowestQuality;
            }
            if (highBit <= 12)
            {
                foreach (long k in _12bitImageSizeToQMap.Keys)
                {
                    if (k > imageWidth * imageHeight)
                        return _12bitImageSizeToQMap[k];
                    lowestQuality = _12bitImageSizeToQMap[k];
                }

                return lowestQuality;
            }
            foreach (long k in _16bitImageSizeToQMap.Keys)
            {
                if (k > imageWidth * imageHeight)
                    return _16bitImageSizeToQMap[k];

                lowestQuality = _16bitImageSizeToQMap[k];
            }

            return lowestQuality;
        }
 public static IAnnotationLayout CreateLayoutByImageSop(IImageSopProvider imageSopProvider)
 {
     return(DicomAnnotationLayoutFactory.CreateLayout(imageSopProvider));
 }
Beispiel #3
0
		internal DicomVoiLuts(IImageSopProvider image)
		{
			_image = image;
		}
		public string GetMatchingStoredLayoutId(IImageSopProvider dicomImage)
		{
			if (dicomImage == null)
				return null;

			var filterCandidates = new List<KeyValuePair<string, string>>
			                       	{
			                       		new KeyValuePair<string, string>("Modality", dicomImage.ImageSop.Modality)
			                       	};

			// these are hard-coded as the only filter candidates for now, until more general use cases are identified.
			var patientOrientation = dicomImage.Frame.PatientOrientation;
			if (!patientOrientation.IsEmpty)
			{
				filterCandidates.Add(new KeyValuePair<string, string>("PatientOrientation_Row", patientOrientation.PrimaryRow));
				filterCandidates.Add(new KeyValuePair<string, string>("PatientOrientation_Col", patientOrientation.PrimaryColumn));
			}

			return GetMatchingStoredLayoutId(filterCandidates);
		}
		public StoredLayout GetLayout(IImageSopProvider imageSopProvider)
		{
			if (imageSopProvider == null)
				return this.DefaultLayout;

			return GetLayout(imageSopProvider.ImageSop);
		}
        private static aim_dotnet.ImageSeries CreateSeries(IImageSopProvider image)
        {
            Platform.CheckForNullReference(image, "Image");
            var aimSeries = new aim_dotnet.ImageSeries();
            aimSeries.InstanceUID = image.ImageSop.SeriesInstanceUid;

            return aimSeries;
        }
        private static aim_dotnet.ImageAnnotation CreateImageAnnotation(IImageSopProvider imageSop, AimAnnotationCreationContext creationContext)
        {
            // Create Basic Image Annotation
            Platform.CheckTrue(creationContext.SelectedAnnotationKind == aim_dotnet.AnnotationKind.AK_ImageAnnotation, "ImageAnnotationKind");
            Platform.CheckForEmptyString(creationContext.AnnotationName, "AnnotationName");
            var imgAnnotation = new aim_dotnet.ImageAnnotation();
            imgAnnotation.CodeValue = creationContext.AnnotationTypeCode.CodeValue;
            imgAnnotation.CodeMeaning = creationContext.AnnotationTypeCode.CodeMeaning;
            imgAnnotation.CodingSchemeDesignator = creationContext.AnnotationTypeCode.CodingSchemeDesignator;
            imgAnnotation.CodingSchemeVersion = creationContext.AnnotationTypeCode.CodingSchemeVersion;
            imgAnnotation.UniqueIdentifier = DicomUid.GenerateUid().UID;
            imgAnnotation.Name = creationContext.AnnotationName;
            imgAnnotation.DateTime = DateTime.Now;
            imgAnnotation.Patient = CreatePatient(imageSop);
            imgAnnotation.Equipment = CreateEquipment();
            if (creationContext.AnnotationUser != null)
                imgAnnotation.User = new aim_dotnet.User(creationContext.AnnotationUser);
            if (!string.IsNullOrEmpty(creationContext.AnnotationComment))
                imgAnnotation.Comment = creationContext.AnnotationComment;
            if (creationContext.SelectedAnatomicEntities != null)
                imgAnnotation.AnatomyEntityCollection = new List<aim_dotnet.AnatomicEntity>(creationContext.SelectedAnatomicEntities);
            if (creationContext.SelectedImagingObservations != null)
                imgAnnotation.ImagingObservationCollection = new List<aim_dotnet.ImagingObservation>(creationContext.SelectedImagingObservations);
            if (creationContext.SelectedInferences != null)
                imgAnnotation.InferenceCollection = new List<aim_dotnet.Inference>(creationContext.SelectedInferences);

            return imgAnnotation;
        }
        private static bool AddDicomImageReference(aim_dotnet.ImageAnnotation imageAnnotation, IImageSopProvider image)
        {
            Platform.CheckForNullReference(imageAnnotation, "ImageAnnotation");
            if (imageAnnotation.ImageReferenceCollection == null)
                imageAnnotation.ImageReferenceCollection = new List<aim_dotnet.ImageReference>();
            var imageReferences = imageAnnotation.ImageReferenceCollection;
            aim_dotnet.ImageStudy aimImageStudy = null;
            foreach (var imgRef in imageReferences)
            {
                var dicomImgRef = imgRef as aim_dotnet.DICOMImageReference;
                if (dicomImgRef != null)
                {
                    if (dicomImgRef.Study.InstanceUID == image.ImageSop.StudyInstanceUid &&
                        dicomImgRef.Study.Series.InstanceUID == image.ImageSop.SeriesInstanceUid)
                        aimImageStudy = dicomImgRef.Study;
                }
            }
            if (aimImageStudy == null)
            {
                aimImageStudy = CreateStudy(image);
                aimImageStudy.Series = CreateSeries(image);
                aimImageStudy.Series.ImageCollection = new List<aim_dotnet.Image>();
                var dicomImgRef = new aim_dotnet.DICOMImageReference();
                dicomImgRef.Study = aimImageStudy;
                imageReferences.Add(dicomImgRef);
            }
            foreach (var existingImage in aimImageStudy.Series.ImageCollection)
            {
                if (existingImage.SopInstanceUID == image.ImageSop.SopInstanceUid)
                    return false;
            }
            var aimImage = CreateImage(image);
            aimImageStudy.Series.ImageCollection.Add(aimImage);

            return true;
        }
        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 (Volumes.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))
                    {
                        foreach (ISopDataSource slice in slicer.CreateSliceSops())
                        {
                            using (ImageSop imageSop = new ImageSop(slice))
                            {
                                // assert tags inserted by slicer
                                AssertAreEqual("WSD", imageSop.DataSource, DicomTags.ConversionType);
                                AssertAreEqual("ClearCanvas Inc.", imageSop.DataSource, DicomTags.SecondaryCaptureDeviceManufacturer);
                                AssertAreEqual(@"DERIVED\SECONDARY", imageSop.DataSource, DicomTags.ImageType);
                                AssertAreEqual("Multiplanar Reformatting", imageSop.DataSource, DicomTags.DerivationDescription);

                                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);
                }
            }
        }
        private bool SendAnnotationsToLocalStorageAndPacs(List <aim_dotnet.Annotation> annotations)
        {
            // NOTE: This code assumes that all images came from the same server.

            // 0. Save each annotation to a temp DICOM file
            DcmModel model = new DcmModel();
            // Map of InstanceUID=>fileName
            Dictionary <string, string> instanceInfos = new Dictionary <string, string>();

            foreach (aim_dotnet.Annotation annotation in annotations)
            {
                // Save annotation to a temp file first
                string tempFileName = System.IO.Path.GetTempFileName();
                try
                {
                    model.WriteAnnotationToFile(annotation, tempFileName);
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, "Failed to save annotation to temp file.", ex);
                    try
                    {
                        System.IO.File.Delete(tempFileName);
                    }
                    catch
                    {
                    }
                    continue;
                }

                // Get SOP Instance UID of our annotation
                DicomFile annFile = new DicomFile(tempFileName);
                annFile.Load(DicomReadOptions.Default | DicomReadOptions.DoNotStorePixelDataInDataSet);
                string annSopInstanceUid = annFile.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);
                annFile = null;

                instanceInfos.Add(annSopInstanceUid, tempFileName);
            }
            model = null;

            if (instanceInfos.Count < 1)
            {
                return(false);                // Save failed
            }
            // Get AE Title for remote storage. NOTE: we use AE Title of the first image for all images
            string            imageAeTitle     = string.Empty;
            IImageSopProvider imageSopProvider = this.ImageViewer.SelectedPresentationImage as IImageSopProvider;

            if (imageSopProvider != null)
            {
                //imageAeTitle = imageSopProvider.ImageSop[DicomTags.SourceApplicationEntityTitle].GetString(0, string.Empty);
                ILocalSopDataSource localSopDataSource = imageSopProvider.ImageSop.DataSource as ILocalSopDataSource;                 //NativeDicomObject as DicomFile;
                if (localSopDataSource != null)
                {
                    imageAeTitle = localSopDataSource.File.SourceApplicationEntityTitle.Trim("\n\r".ToCharArray());
                }
            }

            // 1. Import into the local storage
            using (LocalDataStoreServiceClient localClient = new LocalDataStoreServiceClient())
            {
                try
                {
                    localClient.Open();
                    FileImportRequest request = new FileImportRequest();
                    request.BadFileBehaviour    = BadFileBehaviour.Delete;
                    request.FileImportBehaviour = FileImportBehaviour.Move;
                    List <string> filePaths = new List <string>();
                    foreach (KeyValuePair <string, string> instanceInfo in instanceInfos)
                    {
                        string annSopInstanceUid = instanceInfo.Key;
                        string tempFileName      = instanceInfo.Value;

                        filePaths.Add(tempFileName);
                        // Store destination AE title for the annotaion
                        if (!string.IsNullOrEmpty(imageAeTitle))
                        {
                            lock (_mapLock)
                                _sopInstanceUidToAeTitle.Add(annSopInstanceUid, imageAeTitle);
                        }
                    }
                    request.FilePaths    = filePaths.ToArray();
                    request.IsBackground = true;
                    request.Recursive    = false;
                    localClient.Import(request);
                    localClient.Close();
                }
                catch (Exception ex)
                {
                    localClient.Abort();
                    Platform.Log(LogLevel.Error, ex);
                    this.DesktopWindow.ShowMessageBox("Failed to store your annotation(s).", "Annotation Import Error", MessageBoxActions.Ok);
                    return(false);
                }
            }

            // 2. Saving to PACS happens after the SOP Instance is imported (OnSopInstanceImported)

            return(true);
        }
 public static StoredLayout GetLayout(IImageSopProvider imageSopProvider)
 {
     return (StoredLayout)getLayoutMethod.Invoke(defaultInstance, new object[] { imageSopProvider });
 }
 internal DicomVoiLuts(IImageSopProvider image)
 {
     _image = image;
 }
Beispiel #13
0
        private void Dump()
        {
            if (this.ContextBase is IImageViewerToolContext)
            {
                IImageViewerToolContext context = this.ContextBase as IImageViewerToolContext;
                _desktopWindow = context.DesktopWindow;
                IImageSopProvider image = context.Viewer.SelectedPresentationImage as IImageSopProvider;
                if (image == null)
                {
                    _desktopWindow.ShowMessageBox(SR.MessagePleaseSelectAnImage, MessageBoxActions.Ok);
                    return;
                }

                IDicomMessageSopDataSource dataSource = image.ImageSop.DataSource as IDicomMessageSopDataSource;
                if (dataSource == null || dataSource.SourceMessage == null)
                {
                    _desktopWindow.ShowMessageBox(SR.MessageUnknownDataSource, MessageBoxActions.Ok);
                    return;
                }

                //Fix for Ticket #623 - HH - It turns out that for memory usage optimization the pixel data tag is stripped from the in memory dataset.
                //So while there are probably many better ways to address the missing pixel data tag a small hack was introduced because this entire utility will
                //be completely refactored in the very near future to make use of the methods the pacs uses to parse the tags.
                //Addendum to Comment above - HH 07/27/07 - Turns out that our implementation continues to remove the pixel data for optimization at this time so
                //the workaround is still needed.
                //Addendum to Comment above - JY 09/16/08 - Somewhere along the line, things were changed that made this line redundant - the only reference to
                //it after this point is at +11 lines or so, and all it does is get file.Filename. Therefore, I am commenting this line out.
                //file = new DicomFile(file.Filename);

                if (_component == null)
                {
                    _component = new DicomEditorComponent();
                }
                else
                {
                    _component.Clear();
                }

                _component.Load(dataSource.SourceMessage);
            }
            else if (this.ContextBase is ILocalImageExplorerToolContext)
            {
                ILocalImageExplorerToolContext context = this.ContextBase as ILocalImageExplorerToolContext;
                _desktopWindow = context.DesktopWindow;
                List <string> files = new List <string>();

                if (context.SelectedPaths.Count == 0)
                {
                    return;
                }

                foreach (string rawPath in context.SelectedPaths)
                {
                    if (string.IsNullOrEmpty(rawPath))
                    {
                        continue;
                    }

                    FileProcessor.Process(rawPath, "*.*", files.Add, true);
                }

                if (files.Count == 0)
                {
                    context.DesktopWindow.ShowMessageBox(SR.MessageNoFilesSelected, MessageBoxActions.Ok);
                    return;
                }

                if (_component == null)
                {
                    _component = new DicomEditorComponent();
                }
                else
                {
                    _component.Clear();
                }

                bool userCancelled = false;

                BackgroundTask task = new BackgroundTask(delegate(IBackgroundTaskContext backgroundcontext)
                {
                    int i = 0;

                    foreach (string file in files)
                    {
                        if (backgroundcontext.CancelRequested)
                        {
                            backgroundcontext.Cancel();
                            userCancelled = true;
                            return;
                        }
                        try
                        {
                            _component.Load(file);
                        }
                        catch (DicomException e)
                        {
                            backgroundcontext.Error(e);
                            return;
                        }
                        backgroundcontext.ReportProgress(new BackgroundTaskProgress((int)(((double)(i + 1) / (double)files.Count) * 100.0), SR.MessageDumpProgressBar));
                        i++;
                    }

                    backgroundcontext.Complete(null);
                }, true);

                try
                {
                    ProgressDialog.Show(task, _desktopWindow, true);
                }
                catch (Exception e)
                {
                    ExceptionHandler.Report(e, SR.MessageFailedDump, _desktopWindow);
                    return;
                }

                if (userCancelled == true)
                {
                    return;
                }
            }

            //common to both contexts
            if (_shelf != null)
            {
                _shelf.Activate();
            }
            else
            {
                _shelf = ApplicationComponent.LaunchAsShelf(
                    _desktopWindow,
                    _component,
                    SR.TitleDicomEditor,
                    "Dicom Editor",
                    ShelfDisplayHint.DockRight | ShelfDisplayHint.DockAutoHide);
                _shelf.Closed += OnShelfClosed;
            }

            _component.UpdateComponent();
        }
			public StudyInfo(IImageSopProvider provider, NextSeriesNumberDelegate nextSeriesNumberDelegate = null)
			{
				_provider = provider;
				_nextSeriesNumberDelegate = nextSeriesNumberDelegate ?? new DefaultNextSeriesNumberGetter().GetNextSeriesNumber;
				_studyInstanceUid = provider.Sop.StudyInstanceUid;
				_originServer = ServerDirectory.GetRemoteServersByAETitle(provider.Sop[DicomTags.SourceApplicationEntityTitle].ToString()).FirstOrDefault();
				_sourceServer = provider.Sop.DataSource.Server;

				KeyObjectSeriesUid = DicomUid.GenerateUid().UID;
				KeyObjectSeriesDateTime = Platform.Time;
				PresentationSeriesUid = DicomUid.GenerateUid().UID;
				PresentationSeriesDateTime = Platform.Time;
			}
        public static IAnnotationLayout CreateLayout(IImageSopProvider dicomImage)
        {
            string layoutId = DicomFilteredAnnotationLayoutStore.Instance.GetMatchingStoredLayoutId(dicomImage);

            return(AnnotationLayoutFactory.CreateLayout(layoutId));
        }
		private static aim_dotnet.Image CreateImage(IImageSopProvider image)
		{
			Platform.CheckForNullReference(image, "Image");

			aim_dotnet.Image aimImage = new aim_dotnet.Image();

			aimImage.SopClassUID = image.ImageSop.SopClassUid;
			aimImage.SopInstanceUID = image.ImageSop.SopInstanceUid;

			// TODO - get Image View and Image View Modifiers
			//string sValue;
			//bool bExist;
			//image.ImageSop.GetTag(DicomTags.ViewCodeSequence, out sValue, out bExist);

			return aimImage;
		}
Beispiel #17
0
		public DicomVoiLuts(IImageSopProvider image)
		{
			_image = image;
		}
Beispiel #18
0
        public void ShowImageWithAnnotation(string aimUid)
        {
            if (_activeViewer == null)
            {
                return;
            }

            // Find Annotation
            IAimAnnotationInstance annotationToShow = AvailableAnnotations.FirstOrDefault(annotation => annotation.UniqueIdentifier == aimUid);

            if (annotationToShow == null)
            {
                _activeViewer.DesktopWindow.ShowMessageBox("Could not locate annotation (UID = " + aimUid + ").", MessageBoxActions.Ok);
                return;
            }

            string studyInstanceUid;
            string seriesInstanceUid;
            string sopInstanceUid = null;
            int    frameNumber    = 1;

            if (annotationToShow is IAimImageAnnotationInstace)
            {
                var imageAnnotationToShow = (IAimImageAnnotationInstace)annotationToShow;
                studyInstanceUid  = imageAnnotationToShow.ImageStudyUid;
                seriesInstanceUid = imageAnnotationToShow.ImageSeriesUid;
                sopInstanceUid    = imageAnnotationToShow.FirstImageSopInstanceUid;
                frameNumber       = imageAnnotationToShow.FirstFrameNumber;
            }
            else
            {
                studyInstanceUid  = annotationToShow.ParentAimDocument.StudyInstanceUid;
                seriesInstanceUid = annotationToShow.ParentAimDocument.SeriesInstanceUid;
            }

            if (studyInstanceUid == null || seriesInstanceUid == null)
            {
                _activeViewer.DesktopWindow.ShowMessageBox("Error reading image information (annotation UID = " + aimUid + ").", MessageBoxActions.Ok);
                return;
            }

            // Search displayed images first
            foreach (IImageBox imageBox in _activeViewer.PhysicalWorkspace.ImageBoxes)
            {
                if (imageBox.DisplaySet == null || imageBox.DisplaySet.PresentationImages == null || imageBox.DisplaySet.PresentationImages.Count == 0)
                {
                    continue;
                }

                IImageSopProvider imageSopProvider = imageBox.DisplaySet.PresentationImages[0] as IImageSopProvider;
                if (imageSopProvider == null)
                {
                    continue;
                }

                if (imageSopProvider.ImageSop.StudyInstanceUid == studyInstanceUid &&
                    imageSopProvider.ImageSop.SeriesInstanceUid == seriesInstanceUid)
                {
                    foreach (IPresentationImage presentationImage in imageBox.DisplaySet.PresentationImages)
                    {
                        imageSopProvider = presentationImage as IImageSopProvider;
                        if (imageSopProvider == null)
                        {
                            continue;
                        }
                        // Note: will select the first image if there is no SOP Instance UID
                        if (sopInstanceUid == null ||
                            (imageSopProvider.ImageSop.SopInstanceUid == sopInstanceUid && imageSopProvider.Frame.FrameNumber == frameNumber))
                        {
                            try
                            {
                                // Unselect selected in a different image box
                                if (!imageBox.Selected)
                                {
                                    UnselectCurrentGraphics(_activeViewer.PhysicalWorkspace.SelectedImageBox);
                                }

                                imageBox.TopLeftPresentationImage = presentationImage;
                                imageBox.Tiles[0].Select();
                                SelectAimGraphic(presentationImage, aimUid);
                                imageBox.Draw();

                                return;
                            }
                            catch (Exception ex)
                            {
                                ExceptionHandler.Report(ex, _desktopWindow);
                            }
                        }
                    }
                }
            }

            // Search other available images
            foreach (IImageSet imageSet in _activeViewer.LogicalWorkspace.ImageSets)
            {
                foreach (IDisplaySet displaySet in imageSet.DisplaySets)
                {
                    if (displaySet.PresentationImages.Count > 0)
                    {
                        IImageSopProvider imageSopProvider = displaySet.PresentationImages[0] as IImageSopProvider;
                        if (imageSopProvider == null)
                        {
                            continue;
                        }

                        if (imageSopProvider.ImageSop.StudyInstanceUid == studyInstanceUid &&
                            imageSopProvider.ImageSop.SeriesInstanceUid == seriesInstanceUid)
                        {
                            foreach (IPresentationImage presentationImage in displaySet.PresentationImages)
                            {
                                imageSopProvider = presentationImage as IImageSopProvider;
                                if (imageSopProvider == null)
                                {
                                    continue;
                                }
                                // Note: will select the first image if there is no SOP Instance UID
                                if (sopInstanceUid == null ||
                                    (imageSopProvider.ImageSop.SopInstanceUid == sopInstanceUid && imageSopProvider.Frame.FrameNumber == frameNumber))
                                {
                                    try
                                    {
                                        IImageBox targetImageBox = _activeViewer.PhysicalWorkspace.SelectedImageBox ??
                                                                   (_activeViewer.PhysicalWorkspace.ImageBoxes.Count > 0 ? _activeViewer.PhysicalWorkspace.ImageBoxes[0] : null);
                                        if (targetImageBox == null)
                                        {
                                            _activeViewer.DesktopWindow.ShowMessageBox("Failed to find available display", MessageBoxActions.Ok);
                                            Platform.Log(LogLevel.Error, "Failed to locate a target ImageBox to display requested annotation (aimUID=" + aimUid + ").");
                                            return;
                                        }

                                        IDisplaySet        targetDisplaySet        = displaySet.CreateFreshCopy();
                                        IPresentationImage targetPresentationImage = FindRequiredImage(targetDisplaySet.PresentationImages,
                                                                                                       studyInstanceUid, seriesInstanceUid,
                                                                                                       sopInstanceUid, frameNumber);
                                        if (targetPresentationImage == null)
                                        {
                                            _activeViewer.DesktopWindow.ShowMessageBox("Failed to find required image", MessageBoxActions.Ok);
                                            Platform.Log(LogLevel.Error, "Failed to locate a target ImageBox to display requested annotation (aimUID=" + aimUid + ").");
                                            return;
                                        }

                                        // Unselect selected in a different image box
                                        if (!targetImageBox.Selected)
                                        {
                                            UnselectCurrentGraphics(_activeViewer.PhysicalWorkspace.SelectedImageBox);
                                        }

                                        targetImageBox.DisplaySet = targetDisplaySet;
                                        targetImageBox.TopLeftPresentationImage = targetPresentationImage;
                                        targetImageBox.Tiles[0].Select();
                                        SelectAimGraphic(targetPresentationImage, aimUid);
                                        targetImageBox.Draw();

                                        return;
                                    }
                                    catch (Exception ex)
                                    {
                                        ExceptionHandler.Report(ex, _desktopWindow);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private static aim_dotnet.Image CreateImage(IImageSopProvider image)
        {
            Platform.CheckForNullReference(image, "Image");
            var aimImage = new aim_dotnet.Image();
            aimImage.SopClassUID = image.ImageSop.SopClassUid;
            aimImage.SopInstanceUID = image.ImageSop.SopInstanceUid;

            return aimImage;
        }
Beispiel #20
0
        /// <summary>
        /// Tests the <see cref="Roi.Contains(System.Drawing.PointF)"/> method for a given shape. The image is used to provide a basis for the coordinate space.
        /// </summary>
        protected void TestRoiContains(ImageKey key, T shapeData, string name)
        {
            using (IPresentationImage image = GetImage(key))
            {
                IImageSopProvider provider = (IImageSopProvider)image;
                using (Bitmap bmp = new Bitmap(provider.Frame.Columns, provider.Frame.Rows))
                {
                    using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
                    {
                        g.Clear(Color.Black);

                        // baseline ROI using GDI's GraphicsPath
                        using (GraphicsPath graphicsPath = new GraphicsPath())
                        {
                            AddShapeToGraphicsPath(graphicsPath, shapeData);
                            g.FillPath(Brushes.Blue, graphicsPath);
                        }
                    }

                    // simulates ROIs that an end-user would create using graphics constructed by the tools
                    Roi userRoi = CreateRoiFromGraphic((IOverlayGraphicsProvider)image, shapeData);
                    userRoi.PixelData.ForEachPixel(delegate(int i, int x, int y, int pixelIndex)
                    {
                        if (userRoi.Contains(x, y))
                        {
                            bmp.SetPixel(x, y, ShiftColor(bmp.GetPixel(x, y), true, false, false));
                        }
                    });

                    // simulates ROIs that a programmer might create using the SDK directly, rather than via graphics
                    Roi sdkRoi = CreateRoiFromImage(image, shapeData);
                    sdkRoi.PixelData.ForEachPixel(delegate(int i, int x, int y, int pixelIndex)
                    {
                        if (sdkRoi.Contains(x, y))
                        {
                            bmp.SetPixel(x, y, ShiftColor(bmp.GetPixel(x, y), false, true, false));
                        }
                    });

                    string filename = string.Format("{0}.{1}.containment.test.png", name, this.ShapeName).TrimStart('.');
                    bmp.Save(filename);
                    Trace.WriteLine(string.Format("Pixel containment map has been dumped to {0}.", filename));

                    int totalCount = 0;
                    int errorCount = 0;
                    for (int y = 0; y < bmp.Height; y++)
                    {
                        for (int x = 0; x < bmp.Width; x++)
                        {
                            Color c = bmp.GetPixel(x, y);
                            if (c.R > 0 || c.G > 0 || c.B > 0)
                            {
                                totalCount++;
                                if (c.R < 255 || c.G < 255 || c.B < 255)
                                {
                                    errorCount++;
                                }
                            }
                        }
                    }

                    if (errorCount > 0)
                    {
                        WriteLine("The pixel containment test results are not perfect. {0} differences were found out of {1} pixels.", errorCount, totalCount);
                        WriteLine("The image should be mostly a white shape on a black background.");
                        WriteLine("Any coloured areas indicate locations where Roi.Contains(...) did not return perfectly coincident results.");
                        WriteLine("There will invariably be such areas along shape boundaries, but the shape should be white overall.");
                        WriteLine("Red channel is painted by user mode ROI. Green channel is painted by SDK. Blue channel is painted by GDI+.");
                    }
                    Assert.AreEqual(0, errorCount, 0.01 * totalCount, "Automated pixel containment test failed. Please review the test output manually.");
                }
            }
        }
        private static aim_dotnet.Person CreatePatient(IImageSopProvider image)
        {
            Platform.CheckForNullReference(image, "Image");
            var patient = new aim_dotnet.Person();
            patient.Id = image.Frame.ParentImageSop.PatientId;
            DateTime birthDate;
            DateParser.Parse(image.Frame.ParentImageSop.PatientsBirthDate, out birthDate);
            patient.BirthDate = birthDate;
            patient.Name = image.Frame.ParentImageSop.PatientsName;
            patient.Sex = image.Frame.ParentImageSop.PatientsSex;
            patient.EthnicGroup = image.ImageSop[DicomTags.EthnicGroup].ToString();

            return patient;
        }
Beispiel #22
0
 public static StoredLayout GetLayout(IImageSopProvider imageSopProvider)
 {
     return((StoredLayout)getLayoutMethod.Invoke(defaultInstance, new object[] { imageSopProvider }));
 }
        private static aim_dotnet.ImageStudy CreateStudy(IImageSopProvider image)
        {
            Platform.CheckForNullReference(image, "Image");
            var aimStudy = new aim_dotnet.ImageStudy();
            aimStudy.InstanceUID = image.ImageSop.StudyInstanceUid;
            DateTime studyDate;
            if (DateTimeParser.ParseDateAndTime(null, image.ImageSop.StudyDate, image.ImageSop.StudyTime, out studyDate))
                aimStudy.StartDate = studyDate;

            return aimStudy;
        }
Beispiel #24
0
        private byte[] CreateImage()
        {
            if (_tile.PresentationImage == null)
            {
                DisposeSurface();
            }

            if (Surface == null)
            {
                return(null);
            }

            if (_refreshingClient)
            {
                return(GetCurrentTileBitmap());
            }

            IImageSopProvider sop = _tile.PresentationImage as IImageSopProvider;

            if (sop != null)
            {
                //TODO (CR May 2010): sops are shared between users and threads.  This will be an issue
                //for dynamic quality changes.
                DicomAttribute attrib      = sop.ImageSop[DicomTags.LossyImageCompression];
                DicomAttribute ratioAttrib = sop.ImageSop[DicomTags.LossyImageCompressionRatio];
                bool           lossy       = false;
                if (_mimeType.Equals("image/jpeg"))
                {
                    lossy = true;
                }
                if (lossy)
                {
                    attrib.SetStringValue("01");
                }
                else
                {
                    if (ratioAttrib.IsEmpty)
                    {
                        attrib.SetEmptyValue();
                    }
                }
            }

            WebViewStudyStatistics stats = new WebViewStudyStatistics(_mimeType);

            //long t0 = Environment.TickCount;
            stats.DrawToBitmapTime.Start();

            Bitmap bitmap = Bitmap;

            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
            {
                Surface.ContextID     = graphics.GetHdc();
                Surface.ClipRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

                DrawArgs drawArgs = new DrawArgs(Surface, null, Rendering.DrawMode.Render);
                CurrentImage.Draw(drawArgs);
                drawArgs = new DrawArgs(Surface, null, Rendering.DrawMode.Refresh);
                CurrentImage.Draw(drawArgs);
                graphics.ReleaseHdc(Surface.ContextID);
            }

            stats.DrawToBitmapTime.End();

            Bitmap bmp1 = null;

            if (DiagnosticsSettings.Default.CompareImageQuality)
            {
                // make a copy in case Bitmap.Save() has any side effects.
                bmp1 = (Bitmap)Bitmap.Clone();
            }

            //TODO (CR May 2010): should be in using and/or closed.  Separate function?
            MemoryStream ms = new MemoryStream();

            _quality = _defaultJpegQFactor;
            if (_isMouseDown && IsDynamicImageQualityEnabled)
            {
                _quality = GetOptimalQFactor(Bitmap.Width, Bitmap.Height, sop);

                InitOrUpdateRefreshClientTimer();
            }

            stats.SaveTime.Start();
            if (_mimeType.Equals("image/jpeg"))
            {
                EncoderParameters eps = new EncoderParameters(1);
                eps.Param[0] = new EncoderParameter(Encoder.Quality, _quality);
                ImageCodecInfo ici = GetEncoderInfo(_mimeType);

                bitmap.Save(ms, ici, eps);
            }
            else if (_mimeType.Equals("image/png"))
            {
                bitmap.Save(ms, ImageFormat.Png);
            }
            stats.SaveTime.End();

            byte[] imageBuffer = ms.ToArray();

            if (Platform.IsLogLevelEnabled(LogLevel.Debug))
            {
                Platform.Log(LogLevel.Debug, "Render Frame #{0}. Size= {1}bytes. Q={2} {3}. Highbit={4}",
                             sop.ImageSop.InstanceNumber, imageBuffer.Length, _quality, _isMouseDown && IsDynamicImageQualityEnabled ? "[Dynamic]" : "",
                             sop.Frame.HighBit);
            }

            ms.Position     = 0;
            stats.ImageSize = (ulong)imageBuffer.LongLength;
            _stats.AddSubStats(stats);

            //StatisticsLogger.Log(LogLevel.Info, false, stats);
            if (_stats.SubStatistics.Count > 20)
            {
                _stats.CalculateAverage();
                //StatisticsLogger.Log(LogLevel.Info, false, _stats);
                _stats = new StatisticsSet("AverageRender");
            }

            //Console.WriteLine("Tile {0} : DrawToBitmap (size: {3}, mime: {2}):{1}ms", tile.Identifier,Environment.TickCount - t0,mimeType, ms.Length);

            //TODO (CR May 2010): #if DEBUG?
            if (DiagnosticsSettings.Default.CompareImageQuality)
            {
                Bitmap bmp2 = new Bitmap(ms);
                ImageComparisonResult result = BitmapComparison.Compare(ref bmp1, ref bmp2);
                //TODO (CR May 2010): ConsoleHelper
                Console.WriteLine("BMP vs {0} w/ client size: {1}x{2}", _mimeType, bmp2.Height, bmp2.Width);
                Console.WriteLine("\tR: MinError={2:0.00} MaxError={3:0.00}  Mean={0:0.00}  STD={1:0.00}", result.Channels[0].MeanError, result.Channels[0].StdDeviation, Math.Abs(result.Channels[0].MinError), Math.Abs(result.Channels[0].MaxError));
                Console.WriteLine("\tG: MinError={2:0.00} MaxError={3:0.00}  Mean={0:0.00}  STD={1:0.00}", result.Channels[1].MeanError, result.Channels[1].StdDeviation, Math.Abs(result.Channels[1].MinError), Math.Abs(result.Channels[1].MaxError));
                Console.WriteLine("\tB: MinError={2:0.00} MaxError={3:0.00}  Mean={0:0.00}  STD={1:0.00}", result.Channels[2].MeanError, result.Channels[2].StdDeviation, Math.Abs(result.Channels[2].MinError), Math.Abs(result.Channels[2].MaxError));
            }

            return(imageBuffer);
        }
Beispiel #25
0
		private static GrayscaleImageGraphic CreateGrayscaleImageGraphic(IImageSopProvider frameReference)
		{
			return new GrayscaleImageGraphic(
				frameReference.Frame.Rows,
				frameReference.Frame.Columns,
				frameReference.Frame.BitsAllocated,
				frameReference.Frame.BitsStored,
				frameReference.Frame.HighBit,
				frameReference.Frame.PixelRepresentation != 0 ? true : false,
				frameReference.Frame.PhotometricInterpretation == PhotometricInterpretation.Monochrome1 ? true : false,
				frameReference.Frame.RescaleSlope,
				frameReference.Frame.RescaleIntercept,
				frameReference.Frame.GetNormalizedPixelData);
		}
Beispiel #26
0
        public override string GetAnnotationText(IPresentationImage presentationImage)
        {
            if (presentationImage == null)
            {
                return(String.Empty);
            }

            IImageSopProvider imageSopProvider = presentationImage as IImageSopProvider;

            if (imageSopProvider == null)
            {
                return(String.Empty);
            }

            ISpatialTransformProvider spatialTransformProvider = presentationImage as ISpatialTransformProvider;

            if (spatialTransformProvider == null)
            {
                return(String.Empty);
            }

            ImageSpatialTransform transform = spatialTransformProvider.SpatialTransform as ImageSpatialTransform;

            if (transform == null)
            {
                return(String.Empty);
            }

            if (transform.RotationXY % 90 != 0)
            {
                return(SR.ValueNotApplicable);
            }

            Frame        frame = imageSopProvider.Frame;
            PixelSpacing normalizedPixelSpacing = frame.NormalizedPixelSpacing;

            if (normalizedPixelSpacing.IsNull)
            {
                return(String.Empty);
            }

            RectangleF sourceRectangle      = new RectangleF(0, 0, frame.Columns, frame.Rows);
            RectangleF destinationRectangle = transform.ConvertToDestination(sourceRectangle);

            destinationRectangle = RectangleUtilities.Intersect(destinationRectangle, presentationImage.ClientRectangle);

            //Convert the displayed width and height to source dimensions
            SizeF widthInSource  = transform.ConvertToSource(new SizeF(destinationRectangle.Width, 0));
            SizeF heightInSource = transform.ConvertToSource(new SizeF(0, destinationRectangle.Height));

            //The displayed FOV is given by the magnitude of each line in source coordinates, but
            //for each of the 2 lines, one of x or y will be zero, so we can optimize.

            float x1 = Math.Abs(widthInSource.Width);
            float y1 = Math.Abs(widthInSource.Height);
            float x2 = Math.Abs(heightInSource.Width);
            float y2 = Math.Abs(heightInSource.Height);

            double displayedFieldOfViewX, displayedFieldOfViewY;

            if (x1 > y1)             //the image is not rotated
            {
                displayedFieldOfViewX = x1 * normalizedPixelSpacing.Column / 10;
                displayedFieldOfViewY = y2 * normalizedPixelSpacing.Row / 10;
            }
            else             //the image is rotated by 90 or 270 degrees
            {
                displayedFieldOfViewX = x2 * normalizedPixelSpacing.Column / 10;
                displayedFieldOfViewY = y1 * normalizedPixelSpacing.Row / 10;
            }

            return(String.Format(SR.FormatCentimeters, String.Format(SR.Format2Dimensions, displayedFieldOfViewX.ToString("F1"), displayedFieldOfViewY.ToString("F1"))));
        }
Beispiel #27
0
			private static IEnumerable<VoiWindow> ComputeNormalizedVoiWindows(IImageSopProvider frame, double normalizedSlope, double normalizedIntercept)
			{
				var normalizedWindows = new List<VoiWindow>(VoiWindow.GetWindows(frame.Frame));
				if (frame.ImageSop.Modality == @"PT" && frame.Frame.IsSubnormalRescale)
				{
					// for PET images with subnormal rescale, the VOI window will always be applied directly to the original stored pixel values
					// since MPR will not have access to original stored pixel values, we compute the VOI window through original modality LUT and inverted normalized modality LUT
					var normalizedVoiSlope = frame.Frame.RescaleSlope/normalizedSlope;
					var normalizedVoiIntercept = (frame.Frame.RescaleIntercept - normalizedIntercept)/normalizedSlope;
					for (var i = 0; i < normalizedWindows.Count; ++i)
					{
						var window = normalizedWindows[i]; // round the computed windows - the extra precision is not useful for display anyway
						normalizedWindows[i] = new VoiWindow(Math.Ceiling(window.Width*normalizedVoiSlope), Math.Round(window.Center*normalizedVoiSlope + normalizedVoiIntercept), window.Explanation);
					}
				}
				return normalizedWindows;
			}
Beispiel #28
0
        private List <IDisplaySet> DoCreateSingleImageDisplaySets(Series series)
        {
            List <IDisplaySet> displaySets = new List <IDisplaySet>();
            int position = 0;

            foreach (Sop sop in series.Sops)
            {
                List <IPresentationImage> images = PresentationImageFactory.CreateImages(sop);
                if (images.Count == 0)
                {
                    continue;
                }

                if (sop.IsImage)
                {
                    ImageSop imageSop = (ImageSop)sop;
                    DicomDisplaySetDescriptor descriptor;

                    if (imageSop.NumberOfFrames == 1)
                    {
                        descriptor = new SingleImageDisplaySetDescriptor(series.GetIdentifier(), imageSop, position++);
                    }
                    else
                    {
                        descriptor = new MultiframeDisplaySetDescriptor(series.GetIdentifier(), sop.SopInstanceUid, sop.InstanceNumber);
                    }

                    DisplaySet displaySet = new DisplaySet(descriptor);
                    foreach (IPresentationImage image in images)
                    {
                        displaySet.PresentationImages.Add(image);
                    }

                    displaySets.Add(displaySet);
                }
                else
                {
                    //The sop is actually a container for other referenced sops, like key images.
                    foreach (IPresentationImage image in images)
                    {
                        DisplaySetDescriptor descriptor = null;
                        if (image is IImageSopProvider)
                        {
                            IImageSopProvider provider = (IImageSopProvider)image;
                            if (provider.ImageSop.NumberOfFrames == 1)
                            {
                                descriptor = new SingleImageDisplaySetDescriptor(series.GetIdentifier(), provider.ImageSop, position++);
                            }
                            else
                            {
                                descriptor = new SingleFrameDisplaySetDescriptor(series.GetIdentifier(), provider.Frame, position++);
                            }
                        }
                        else
                        {
                            //TODO (CR Jan 2010): this because the design here is funny... the factory here should actually know something about the key object series it is building for
                            ISeriesIdentifier sourceSeries = series.GetIdentifier();
                            descriptor             = new BasicDisplaySetDescriptor();
                            descriptor.Description = sourceSeries.SeriesDescription;
                            descriptor.Name        = string.Format("{0}: {1}", sourceSeries.SeriesNumber, sourceSeries.SeriesDescription);
                            descriptor.Number      = sourceSeries.SeriesNumber.GetValueOrDefault(0);
                            descriptor.Uid         = sourceSeries.SeriesInstanceUid;
                        }

                        DisplaySet displaySet = new DisplaySet(descriptor);
                        displaySet.PresentationImages.Add(image);
                        displaySets.Add(displaySet);
                    }
                }
            }

            if (displaySets.Count == 1)
            {
                //Degenerate case; single image series, which we're not supposed to create.
                displaySets[0].Dispose();
                displaySets.Clear();
            }

            return(displaySets);
        }
		public static IAnnotationLayout CreateLayout(IImageSopProvider dicomImage)
		{
			string layoutId = DicomFilteredAnnotationLayoutStore.Instance.GetMatchingStoredLayoutId(dicomImage);
			return AnnotationLayoutFactory.CreateLayout(layoutId);
		}
		public static IAnnotationLayout CreateLayoutByImageSop(IImageSopProvider imageSopProvider)
		{
			return DicomAnnotationLayoutFactory.CreateLayout(imageSopProvider);
		}