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)); }
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; }
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; }
public DicomVoiLuts(IImageSopProvider image) { _image = image; }
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; }
/// <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; }
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; }
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); }
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); }
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")))); }
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; }
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); }