/// <summary> /// Initializes a new instance of <see cref="Frame"/> with the /// specified parameters. /// </summary> /// <param name="parentImageSop">The parent <see cref="ImageSop"/>.</param> /// <param name="frameNumber">The first frame is frame 1.</param> protected internal Frame(ImageSop parentImageSop, int frameNumber) { Platform.CheckForNullReference(parentImageSop, "parentImageSop"); Platform.CheckPositive(frameNumber, "frameNumber"); _parentImageSop = parentImageSop; _frameNumber = frameNumber; }
protected override void Dispose(bool disposing) { if (disposing) { _frame = null; _dicomFile = null; if (_imageSop != null) { _imageSop.Dispose(); _imageSop = null; } if (_sopDataSource != null) { _sopDataSource.Dispose(); _sopDataSource = null; } if (_filename != null) { if (File.Exists(_filename)) File.Delete(_filename); _filename = null; } } base.Dispose(disposing); }
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); } } }
public TestPresentationImage() : base(TestPattern.CreateRGBKCorners(new Size(_width, _height))) { DicomFile dcf = new DicomFile(); dcf.DataSet[DicomTags.StudyInstanceUid].SetStringValue("1"); dcf.DataSet[DicomTags.SeriesInstanceUid].SetStringValue("2"); dcf.DataSet[DicomTags.SopInstanceUid].SetStringValue("3"); dcf.DataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid); dcf.DataSet[DicomTags.InstanceNumber].SetStringValue("1"); dcf.DataSet[DicomTags.NumberOfFrames].SetStringValue("1"); dcf.MetaInfo[DicomTags.TransferSyntaxUid].SetStringValue(TransferSyntax.ImplicitVrLittleEndianUid); dcf.MetaInfo[DicomTags.MediaStorageSopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid); dcf.MetaInfo[DicomTags.MediaStorageSopInstanceUid].SetStringValue("3"); _imageSop = new ImageSop(new TestDataSource(dcf)); }
public override bool Start(IMouseInformation mouseInformation) { if (this.SelectedImageGraphicProvider == null) return false; _selectedTile = mouseInformation.Tile as Tile; _selectedTile.InformationBox = new InformationBox(); _selectedImageGraphic = this.SelectedImageGraphicProvider.ImageGraphic; _selectedImageSop = (this.SelectedPresentationImage as IImageSopProvider).ImageSop; Probe(mouseInformation.Location); return true; }
public MockDicomPresentationImage(string filename) : base(new GrayscaleImageGraphic(10, 10)) { if (Path.IsPathRooted(filename)) _filename = filename; else _filename = Path.Combine(Environment.CurrentDirectory, filename); _dicomFile = new DicomFile(); _dicomFile.DataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid); _dicomFile.DataSet[DicomTags.SopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); _dicomFile.MetaInfo[DicomTags.MediaStorageSopClassUid].SetStringValue(_dicomFile.DataSet[DicomTags.SopClassUid].ToString()); _dicomFile.MetaInfo[DicomTags.MediaStorageSopInstanceUid].SetStringValue(_dicomFile.DataSet[DicomTags.SopInstanceUid].ToString()); _dicomFile.Save(_filename); _sopDataSource = new LocalSopDataSource(_dicomFile); _imageSop = new ImageSop(_sopDataSource); _frame = new MockFrame(_imageSop, 1); }
private static DynamicTePresentationImage CreateT2Image(ImageSop imageSop, Frame frame) { DicomFile pdMap = FindMap(imageSop.StudyInstanceUID, frame.SliceLocation, "PD"); pdMap.Load(DicomReadOptions.Default); DicomFile t2Map = FindMap(imageSop.StudyInstanceUID, frame.SliceLocation, "T2"); t2Map.Load(DicomReadOptions.Default); DicomFile probMap = FindMap(imageSop.StudyInstanceUID, frame.SliceLocation, "CHI2PROB"); probMap.Load(DicomReadOptions.Default); DynamicTePresentationImage t2Image = new DynamicTePresentationImage( frame, (byte[])pdMap.DataSet[DicomTags.PixelData].Values, (byte[])t2Map.DataSet[DicomTags.PixelData].Values, (byte[])probMap.DataSet[DicomTags.PixelData].Values); t2Image.DynamicTe.Te = 50.0f; return t2Image; }
public List<BitmapSource> ReturnImageListFromFile(string filePath) { List<BitmapSource> bmpImageList = new List<BitmapSource>(); LocalSopDataSource dicomDataSource = new LocalSopDataSource(filePath); ImageSop imageSop = new ImageSop(dicomDataSource); IEnumerable images = PresentationImageFactory.Create(imageSop).ToArray(); int i = 1; foreach (IPresentationImage presentationImage in images) { int width = imageSop.Frames[i].Columns; int height = imageSop.Frames[i].Rows; Bitmap bmp = presentationImage.DrawToBitmap(width, height); dicomImages.Add(new DicomImage { Bitmap = Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(width, height)) }); i++; } return bmpImageList; }
protected internal byte[] GetOverlay(Frame baseFrame, out OverlayFrameParams overlayFrameParams) { var volume = this.Volume; // compute the bounds of the target base image frame in patient coordinates var baseTopLeft = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, 0)); var baseTopRight = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(baseFrame.Columns, 0)); var baseBottomLeft = baseFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, baseFrame.Rows)); var baseFrameCentre = (baseTopRight + baseBottomLeft)/2; // compute the rotated volume slicing basis axes var volumeXAxis = (volume.ConvertToVolume(baseTopRight) - volume.ConvertToVolume(baseTopLeft)).Normalize(); var volumeYAxis = (volume.ConvertToVolume(baseBottomLeft) - volume.ConvertToVolume(baseTopLeft)).Normalize(); var volumeZAxis = volumeXAxis.Cross(volumeYAxis); var @params = new VolumeSlicerParams(volumeXAxis, volumeYAxis, volumeZAxis); using (var slice = new VolumeSliceSopDataSource(volume, @params, volume.ConvertToVolume(baseFrameCentre))) { using (var sliceSop = new ImageSop(slice)) { using (var overlayFrame = sliceSop.Frames[1]) { // compute the bounds of the target overlay image frame in patient coordinates var overlayTopLeft = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, 0)); var overlayTopRight = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(overlayFrame.Columns, 0)); var overlayBottomLeft = overlayFrame.ImagePlaneHelper.ConvertToPatient(new PointF(0, overlayFrame.Rows)); var overlayOffset = overlayTopLeft - baseTopLeft; // compute the overlay and base image resolution in pixels per unit patient space (mm). var overlayResolutionX = overlayFrame.Columns/(overlayTopRight - overlayTopLeft).Magnitude; var overlayResolutionY = overlayFrame.Rows/(overlayBottomLeft - overlayTopLeft).Magnitude; var baseResolutionX = baseFrame.Columns/(baseTopRight - baseTopLeft).Magnitude; var baseResolutionY = baseFrame.Rows/(baseBottomLeft - baseTopLeft).Magnitude; // compute parameters to register the overlay on the base image var scale = new PointF(baseResolutionX/overlayResolutionX, baseResolutionY/overlayResolutionY); var offset = new PointF(overlayOffset.X*overlayResolutionX, overlayOffset.Y*overlayResolutionY); //TODO (CR Sept 2010): could this be negative? // validate computed transform parameters Platform.CheckTrue(overlayOffset.Z < 0.5f, "Compute OffsetZ != 0"); overlayFrameParams = new OverlayFrameParams( overlayFrame.Rows, overlayFrame.Columns, overlayFrame.BitsAllocated, overlayFrame.BitsStored, overlayFrame.HighBit, overlayFrame.PixelRepresentation != 0 ? true : false, overlayFrame.PhotometricInterpretation == PhotometricInterpretation.Monochrome1 ? true : false, overlayFrame.RescaleSlope, overlayFrame.RescaleIntercept, scale, offset); return overlayFrame.GetNormalizedPixelData(); } } } }
protected internal AsyncFrame(ImageSop parentImageSop, int frameNumber) : base(parentImageSop, frameNumber) { SupportsAsync = ParentImageSop.DataSource.GetFrameData(FrameNumber) is IAsyncSopFrameData; }
public StoredLayout GetLayout(ImageSop imageSop) { if (imageSop == null) return this.DefaultLayout; return GetLayout(imageSop.Modality); }
private static void AssertExposureParameter(string expectedValue, ImageSop imageSop, ExposureParameterGetter function, string message) { Assert.AreEqual(expectedValue, function.Invoke(imageSop.Frames[1], @"{0}"), message); }
/// <summary> /// Creates an appropriate subclass of <see cref="BasicPresentationImage"/> /// for each <see cref="Frame"/> in the input <see cref="ImageSop"/>. /// </summary> public static List<IPresentationImage> Create(ImageSop imageSop) { return _defaultInstance.CreateImages(imageSop); }
/// <summary> /// Creates the presentation images for a given image SOP. /// </summary> /// <param name="imageSop">The image SOP from which presentation images are to be created.</param> /// <returns>A list of created presentation images.</returns> protected virtual List<IPresentationImage> CreateImages(ImageSop imageSop) { return CollectionUtils.Map(imageSop.Frames, (Frame frame) => CreateImage(frame)); }
public static bool IsValid(TreeNode node) { try { LocalSopDataSource _dicomDataSource = new LocalSopDataSource(((FileInfo)node.Tag).FullName); ImageSop isop = new ImageSop(_dicomDataSource); //DicomFile dcf = new DicomFile(((FileInfo)node.Tag).FullName); //dcf.Load(DicomReadOptions.DoNotStorePixelDataInDataSet); //00:00:01.5625000 //00:00:01.7625000 //00:00:00.0468750 } catch (Exception ex) { return false; } return true; }
public static bool ConvertDcmToPng(DbStudy study) { try { string dcmPath = ADCM.GetStoreString(); string studyPath = Path.Combine(dcmPath, study.study_uid); if (!Directory.Exists(studyPath)) throw new Exception("Study path not found"); var allSeriesPaths = Directory.GetDirectories(studyPath); if (allSeriesPaths.Length < 1) throw new Exception("No series subdirectories"); foreach (var s in allSeriesPaths) { var dcmFiles = Directory.GetFiles(s, "*.dcm"); if (dcmFiles.Length < 1) throw new Exception("No DCM files inside series path: " + s); DicomFile tempdcm = new DicomFile(dcmFiles[0]); tempdcm.Load(); var seriesName = tempdcm.DataSet[DicomTags.SeriesDescription].GetString(0, null); var seriesUID = s.Substring(s.LastIndexOf(Path.DirectorySeparatorChar) + 1); if (string.IsNullOrEmpty(seriesName)) seriesName = "Unamed_Series"; APetaPoco.SetConnectionString("cn1"); var bm = APetaPoco.PpRetrieveOne<DbSeries>("Series", "[case_id] = '" + study.case_id + "' AND [series_uid] = '" + seriesUID + "'"); DbSeries dbseries = null; if (bm.Success) { dbseries = (DbSeries)bm.Data; } string outputPath = Path.Combine(dcmPath, "OUTPUT", study.case_id, study.study_uid, seriesUID); if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath); //int fileCount = 0; for (int k = 0; k < dcmFiles.Length; k++) { DicomFile dcmFile = new DicomFile(dcmFiles[k]); dcmFile.Load(); int fileCount = 0; var windowWidth = dcmFile.DataSet[DicomTags.WindowWidth].ToString(); if (!string.IsNullOrEmpty(windowWidth)) { var tempSplitString = windowWidth.Split('\\'); windowWidth = tempSplitString[0]; } var windowCenter = dcmFile.DataSet[DicomTags.WindowCenter].ToString(); if (!string.IsNullOrEmpty(windowCenter)) { var tempSplitString = windowCenter.Split('\\'); windowCenter = tempSplitString[0]; } var ww = dcmFile.DataSet[DicomTags.WindowWidth].GetFloat32(0, 0); var wc = dcmFile.DataSet[DicomTags.WindowCenter].GetFloat32(0, 0); if (ww == 0 && !string.IsNullOrEmpty(windowWidth)) { if (windowWidth.Contains(".")) { var tempSplitString = windowWidth.Split('.'); ww = int.Parse(tempSplitString[0]); } else { ww = int.Parse(windowWidth); } } if (wc == 0 && !string.IsNullOrEmpty(windowCenter)) { if (windowCenter.Contains(".")) { var tempSplitString = windowCenter.Split('.'); wc = int.Parse(tempSplitString[0]); } else { wc = int.Parse(windowCenter); } } LocalSopDataSource localds = new LocalSopDataSource(dcmFile); if (!localds.IsImage) { continue; } ImageSop sop = new ImageSop(localds); int frameCount = sop.Frames.Count; var fileName = dcmFile.DataSet[DicomTags.InstanceNumber].GetInt16(0, 0); if (frameCount > 1) { for (int j = 1; j <= frameCount; j++) { GC.Collect(); Frame f = sop.Frames[j]; var jpgPath = Path.Combine(outputPath, fileName + "." + j + ".png"); Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { if(dbseries != null && dbseries.crop_h != null && dbseries.crop_w != null && dbseries.crop_x != null && dbseries.crop_y != null) { bmp = Crop(bmp, dbseries.crop_x.Value, dbseries.crop_y.Value, dbseries.crop_w.Value, dbseries.crop_h.Value); } SaveImage(bmp, jpgPath); } fileCount += 1; GC.Collect(); } } else { GC.Collect(); var jpgPath = Path.Combine(outputPath, fileName + ".png"); Frame f = sop.Frames[1]; Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { if (dbseries != null && dbseries.crop_h != null && dbseries.crop_w != null && dbseries.crop_x != null && dbseries.crop_y != null) { bmp = Crop(bmp, dbseries.crop_x.Value, dbseries.crop_y.Value, dbseries.crop_w.Value, dbseries.crop_h.Value); } SaveImage(bmp, jpgPath); } fileCount += 1; GC.Collect(); } } } LOG.InsertEvent("Successfully converted study from DCM to PNG", "IMG", null, study.case_id, study.study_uid); return true; } catch (Exception ex) { string errorString = "Error at :" + System.Reflection.MethodBase.GetCurrentMethod().Name; LOG.Write(errorString); LOG.Write(ex.Message); LOG.InsertEvent(errorString, "IMG", ex.Message, study.case_id, study.study_uid); return false; } }
public static byte[] GetImageBytesFromDcm(string dcmPath) { DicomFile dcmFile = new DicomFile(dcmPath); dcmFile.Load(); int fileCount = 0; var windowWidth = dcmFile.DataSet[DicomTags.WindowWidth].ToString(); if (!string.IsNullOrEmpty(windowWidth)) { var tempSplitString = windowWidth.Split('\\'); windowWidth = tempSplitString[0]; } var windowCenter = dcmFile.DataSet[DicomTags.WindowCenter].ToString(); if (!string.IsNullOrEmpty(windowCenter)) { var tempSplitString = windowCenter.Split('\\'); windowCenter = tempSplitString[0]; } var ww = dcmFile.DataSet[DicomTags.WindowWidth].GetFloat32(0, 0); var wc = dcmFile.DataSet[DicomTags.WindowCenter].GetFloat32(0, 0); if (ww == 0 && !string.IsNullOrEmpty(windowWidth)) { if (windowWidth.Contains(".")) { var tempSplitString = windowWidth.Split('.'); ww = int.Parse(tempSplitString[0]); } else { ww = int.Parse(windowWidth); } } if (wc == 0 && !string.IsNullOrEmpty(windowCenter)) { if (windowCenter.Contains(".")) { var tempSplitString = windowCenter.Split('.'); wc = int.Parse(tempSplitString[0]); } else { wc = int.Parse(windowCenter); } } LocalSopDataSource localds = new LocalSopDataSource(dcmFile); if (!localds.IsImage) { return null; } ImageSop sop = new ImageSop(localds); int frameCount = sop.Frames.Count; if (frameCount > 1) { int midFrame = Convert.ToInt32(frameCount / 2); GC.Collect(); Frame f = sop.Frames[midFrame]; //var jpgPath = Path.Combine(outputPath, fileName + "." + j + ".png"); Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { return ImageToByte2(bmp); } } else { GC.Collect(); Frame f = sop.Frames[1]; Bitmap bmp = null; if (string.IsNullOrEmpty(windowWidth) || string.IsNullOrEmpty(windowCenter)) { bmp = DrawDefaultFrame(f); } else { bmp = DrawLutFrame(f, ww, wc); } if (bmp != null) { return ImageToByte2(bmp); } fileCount += 1; GC.Collect(); } return null; }
/// <summary> /// Creates a <see cref="ImageSopInstanceReferenceMacro"/> to the given <see cref="ImageSop"/>. /// </summary> /// <param name="sop">The image SOP to which a reference is to be constructed.</param> /// <returns>An image SOP instance reference macro item.</returns> protected static ImageSopInstanceReferenceMacro CreateImageSopInstanceReference(ImageSop sop) { ImageSopInstanceReferenceMacro imageReference = new ImageSopInstanceReferenceMacro(); imageReference.ReferencedSopClassUid = sop.SopClassUid; imageReference.ReferencedSopInstanceUid = sop.SopInstanceUid; return imageReference; }
public MockFrame(ImageSop parent, int number) : base(parent, number) {}
public SingleImageDisplaySetDescriptor(ISeriesIdentifier sourceSeries, ImageSop imageSop, int position) : base(sourceSeries) { Platform.CheckForNullReference(sourceSeries, "sourceSeries"); Platform.CheckForNullReference(imageSop, "imageSop"); _sopInstanceUid = imageSop.SopInstanceUid; _seriesInstanceUid = imageSop.SeriesInstanceUid; _position = position; string laterality = imageSop.ImageLaterality; string viewPosition = imageSop.ViewPosition; if (string.IsNullOrEmpty(viewPosition)) { DicomAttributeSQ codeSequence = imageSop[DicomTags.ViewCodeSequence] as DicomAttributeSQ; if (codeSequence != null && !codeSequence.IsNull && codeSequence.Count > 0) viewPosition = codeSequence[0][DicomTags.CodeMeaning].GetString(0, null); } string lateralityViewPosition = null; if (!String.IsNullOrEmpty(laterality) && !String.IsNullOrEmpty(viewPosition)) lateralityViewPosition = String.Format("{0}/{1}", laterality, viewPosition); else if (!String.IsNullOrEmpty(laterality)) lateralityViewPosition = laterality; else if (!String.IsNullOrEmpty(viewPosition)) lateralityViewPosition = viewPosition; if (sourceSeries.SeriesInstanceUid == imageSop.SeriesInstanceUid) { if (lateralityViewPosition != null) _suffix = String.Format(SR.SuffixFormatSingleImageDisplaySetWithLateralityViewPosition, lateralityViewPosition, imageSop.InstanceNumber); else _suffix = String.Format(SR.SuffixFormatSingleImageDisplaySet, imageSop.InstanceNumber); } else { //this is a referenced image (e.g. key image). if (lateralityViewPosition != null) _suffix = String.Format(SR.SuffixFormatSingleReferencedImageDisplaySetWithLateralityViewPosition, lateralityViewPosition, imageSop.SeriesNumber, imageSop.InstanceNumber); else _suffix = String.Format(SR.SuffixFormatSingleReferencedImageDisplaySet, imageSop.SeriesNumber, imageSop.InstanceNumber); } }
public KeyImageReference(ImageSop imageSop, int? frameNumber) : base(imageSop) { _frameNumber = frameNumber; }
private static void InitializeDerivationImageFunctionalGroup(FunctionalGroupsSequenceItem functionalGroupsSequenceItem, ImageSop imageSop, int frameNumber) { var derivationImageFunctionalGroup = functionalGroupsSequenceItem.GetFunctionalGroup<DerivationImageFunctionalGroup>(); var derivationImageSequenceItem = derivationImageFunctionalGroup.CreateDerivationImageSequenceItem(); var derivationCodeSequence = derivationImageSequenceItem.CreateDerivationCodeSequence(); derivationCodeSequence.CodeValue = "113076"; derivationCodeSequence.CodeMeaning = "Segmentation"; derivationCodeSequence.CodingSchemeDesignator = "DCM"; derivationImageSequenceItem.DerivationCodeSequence = derivationCodeSequence; var sourceImageSequenceItem = derivationImageSequenceItem.CreateSourceImageSequenceItem(); sourceImageSequenceItem.ReferencedSopClassUid = imageSop.SopClassUid; sourceImageSequenceItem.ReferencedSopInstanceUid = imageSop.SopInstanceUid; if (frameNumber != 1) sourceImageSequenceItem.ReferencedFrameNumber2 = new[] {frameNumber}; // TODO: FIXME: replace with stock implementation when available var purposeOfReferenceCodeSequence = new Func<CodeSequenceMacro>(() => { var dicomAttribute = sourceImageSequenceItem.DicomAttributeProvider[DicomTags.PurposeOfReferenceCodeSequence]; if (dicomAttribute.IsNull || dicomAttribute.IsEmpty) { var dicomSequenceItem = new DicomSequenceItem(); dicomAttribute.Values = new[] {dicomSequenceItem}; return new CodeSequenceMacro(dicomSequenceItem); } return new CodeSequenceMacro(((DicomSequenceItem[]) dicomAttribute.Values)[0]); }).Invoke(); purposeOfReferenceCodeSequence.CodeValue = "121322"; purposeOfReferenceCodeSequence.CodeMeaning = "Source image for image processing operation"; purposeOfReferenceCodeSequence.CodingSchemeDesignator = "DCM"; derivationImageSequenceItem.SourceImageSequence = new[] {sourceImageSequenceItem}; derivationImageFunctionalGroup.DerivationImageSequence = new[] {derivationImageSequenceItem}; }
private static DisposableList<IPresentationImage> CreateImages(DicomFile dicomFile) { using (var dataSource = new LocalSopDataSource(dicomFile)) { using (var sop = new ImageSop(dataSource)) { return new DisposableList<IPresentationImage>(PresentationImageFactory.Create(sop)); } } }
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(); } } }
public IPresentationImage CreateSecondaryCapture(IPresentationImage image) { var imageSopProvider = image as IImageSopProvider; if (imageSopProvider == null) { const string msg = "image must implement IImageSopProvider"; throw new ArgumentException(msg, "image"); } SeriesInfo seriesInfo; var seriesKey = MakeSeriesKey(imageSopProvider.Frame.StudyInstanceUid, imageSopProvider.Sop.Modality); if (!_seriesInfo.TryGetValue(seriesKey, out seriesInfo)) _seriesInfo[seriesKey] = seriesInfo = new SeriesInfo(_nextSeriesNumberDelegate.Invoke(imageSopProvider.Frame.StudyInstanceUid)); var dcf = CreatePrototypeFile(imageSopProvider.Sop.DataSource); FillGeneralSeriesModule(dcf.DataSet, imageSopProvider.Frame, seriesInfo); FillScEquipmentModule(dcf.DataSet, Manufacturer, ManufacturersModelName, SoftwareVersions); FillFrameOfReferenceModule(dcf.DataSet, imageSopProvider.Frame); FillGeneralImageModule(dcf.DataSet, imageSopProvider.Frame, seriesInfo); FillScImageModule(dcf.DataSet, imageSopProvider.Frame); FillImagePlaneModule(dcf.DataSet, imageSopProvider.Frame); FillSopCommonModule(dcf.DataSet, SopClass.SecondaryCaptureImageStorageUid); FillAuxiliaryImageData(dcf.DataSet, imageSopProvider.Frame); if (image is GrayscalePresentationImage) { FillModalityLutModule(dcf.DataSet, imageSopProvider.Frame); FillVoiLutModule(dcf.DataSet, imageSopProvider.Frame); // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleGrayscale(dcf.DataSet, imageSopProvider.Frame); } else if (image is ColorPresentationImage) { // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleColor(dcf.DataSet, imageSopProvider.Frame); } else { // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleRasterRgb(dcf.DataSet, image); } dcf.MediaStorageSopClassUid = dcf.DataSet[DicomTags.SopClassUid].ToString(); dcf.MediaStorageSopInstanceUid = dcf.DataSet[DicomTags.SopInstanceUid].ToString(); _files.Add(dcf); using (var sop = new ImageSop(new LocalSopDataSource(dcf))) { var secondaryCapture = PresentationImageFactory.Create(sop).Single(); try { var presentationState = DicomSoftcopyPresentationState.IsSupported(image) ? DicomSoftcopyPresentationState.Create(image) : null; if (presentationState != null) { presentationState.DeserializeOptions |= DicomSoftcopyPresentationStateDeserializeOptions.IgnoreImageRelationship; presentationState.Deserialize(secondaryCapture); // override the spatial transform of the secondary capture because the presentation state doesn't save exact parameters var sourceTransform = image as ISpatialTransformProvider; var targetTransform = secondaryCapture as ISpatialTransformProvider; if (sourceTransform != null && targetTransform != null) { targetTransform.SpatialTransform.CenterOfRotationXY = sourceTransform.SpatialTransform.CenterOfRotationXY; targetTransform.SpatialTransform.FlipX = sourceTransform.SpatialTransform.FlipX; targetTransform.SpatialTransform.FlipY = sourceTransform.SpatialTransform.FlipY; targetTransform.SpatialTransform.RotationXY = sourceTransform.SpatialTransform.RotationXY; targetTransform.SpatialTransform.Scale = sourceTransform.SpatialTransform.Scale; targetTransform.SpatialTransform.TranslationX = sourceTransform.SpatialTransform.TranslationX; targetTransform.SpatialTransform.TranslationY = sourceTransform.SpatialTransform.TranslationY; var sourceImageTransform = sourceTransform as IImageSpatialTransform; var targetImageTransform = targetTransform as IImageSpatialTransform; if (sourceImageTransform != null && targetImageTransform != null) targetImageTransform.ScaleToFit = sourceImageTransform.ScaleToFit; } } // force a render to update the client rectangle and scaling of the image secondaryCapture.RenderImage(image.ClientRectangle).Dispose(); } catch (Exception ex) { Platform.Log(LogLevel.Warn, ex, "An error has occurred while deserializing the image presentation state."); } return secondaryCapture; } }