public static IPresentationImage PresentationImageFromPositionOrientation( double[] imagePositionPatientValues, double[] imageOrientationPatientValues, IDisplaySet displaySet, string frameOfReferenceUid) { Platform.CheckForNullReference(displaySet, "displaySet"); if (imagePositionPatientValues != null && imagePositionPatientValues.Length > 2 && imageOrientationPatientValues != null && imageOrientationPatientValues.Length > 5) { var imagePositionPatient = new ImagePositionPatient( imagePositionPatientValues[0], imagePositionPatientValues[1], imagePositionPatientValues[2]); var imageOrientationPatient = new ImageOrientationPatient( imageOrientationPatientValues[0], imageOrientationPatientValues[1], imageOrientationPatientValues[2], imageOrientationPatientValues[3], imageOrientationPatientValues[4], imageOrientationPatientValues[5]); return(PresentationImageFromPositionOrientation( imagePositionPatient, imageOrientationPatient, displaySet, frameOfReferenceUid)); } return(null); }
/// <summary> /// Sets the slicing plane for the specified slice set based on two points on the specified source image. /// </summary> private static void SetSlicePlane(IMprStandardSliceSet sliceSet, IPresentationImage sourceImage, Vector3D startPoint, Vector3D endPoint) { IImageSopProvider imageSopProvider = sourceImage as IImageSopProvider; if (imageSopProvider == null) { return; } ImageOrientationPatient orientation = imageSopProvider.Frame.ImageOrientationPatient; Vector3D orientationRow = new Vector3D((float)orientation.RowX, (float)orientation.RowY, (float)orientation.RowZ); Vector3D orientationColumn = new Vector3D((float)orientation.ColumnX, (float)orientation.ColumnY, (float)orientation.ColumnZ); if (sliceSet != null && !sliceSet.IsReadOnly) { IImageBox imageBox = FindImageBox(sliceSet, sourceImage.ImageViewer as MprViewerComponent); sliceSet.SlicerParams = VolumeSlicerParams.Create(sliceSet.VolumeHeader, orientationColumn, orientationRow, startPoint, endPoint); IPresentationImage closestImage = GetClosestSlice(startPoint + (endPoint - startPoint) * 2, imageBox.DisplaySet); if (closestImage == null) { imageBox.TopLeftPresentationImageIndex = imageBox.DisplaySet.PresentationImages.Count / 2; } else { imageBox.TopLeftPresentationImage = closestImage; } } }
public void TestNoOrientation() { NewTransform(); ImageOrientationPatient iop = new ImageOrientationPatient(0, 0, 0, 0, 0, 0); TestArbitraryImageOrientationPatient(iop, "", "", "", ""); }
private static void AssertVolumeSlice(VolumeSlice actualSlice, int expectedRows, int expectedColumns, Vector3D expectedPositionPatient, Vector3D expectedRowOrientationPatient, Vector3D expectedColumnOrientationPatient, float expectedRowSpacing, float expectedColumnSpacing, float expectedSliceThickness, float?expectedSpacingBetweenSlices, string message = null, params object[] args) { const float tolerance = 1e-5f; var msg = !string.IsNullOrEmpty(message) ? "{0} (" + string.Format(message, args) + ")" : "{0}"; Assert.AreEqual(expectedRows, actualSlice.Rows, msg, "Rows"); Assert.AreEqual(expectedColumns, actualSlice.Columns, msg, "Columns"); var imagePositionPatient = ImagePositionPatient.FromString(actualSlice.ImagePositionPatient); Assert.IsNotNull(imagePositionPatient, "ImagePositionPatient"); var actualPositionPatient = new Vector3D((float)imagePositionPatient.X, (float)imagePositionPatient.Y, (float)imagePositionPatient.Z); if (!Vector3D.AreEqual(expectedPositionPatient, actualPositionPatient, tolerance)) { Assert.AreEqual(expectedPositionPatient, actualPositionPatient, msg, "ImagePositionPatient"); } var imageOrientationPatient = ImageOrientationPatient.FromString(actualSlice.ImageOrientationPatient); Assert.IsNotNull(imageOrientationPatient, "ImageOrientationPatient"); var actualRowOrientationPatient = new Vector3D((float)imageOrientationPatient.RowX, (float)imageOrientationPatient.RowY, (float)imageOrientationPatient.RowZ); var actualColumnOrientationPatient = new Vector3D((float)imageOrientationPatient.ColumnX, (float)imageOrientationPatient.ColumnY, (float)imageOrientationPatient.ColumnZ); if (!Vector3D.AreEqual(expectedRowOrientationPatient, actualRowOrientationPatient, tolerance)) { Assert.AreEqual(expectedRowOrientationPatient, actualRowOrientationPatient, msg, "ImageOrientationPatient.Row"); } if (!Vector3D.AreEqual(expectedColumnOrientationPatient, actualColumnOrientationPatient, tolerance)) { Assert.AreEqual(expectedColumnOrientationPatient, actualColumnOrientationPatient, msg, "ImageOrientationPatient.Column"); } var actualPixelSpacing = PixelSpacing.FromString(actualSlice.PixelSpacing); Assert.IsNotNull(actualPixelSpacing, "PixelSpacing"); Assert.AreEqual(expectedRowSpacing, actualPixelSpacing.Row, tolerance, msg, "PixelSpacing.Row"); Assert.AreEqual(expectedColumnSpacing, actualPixelSpacing.Column, tolerance, msg, "PixelSpacing.Column"); Assert.AreEqual(expectedSliceThickness, float.Parse(actualSlice.SliceThickness), tolerance, msg, "SliceThickness"); if (expectedSpacingBetweenSlices.HasValue) { Assert.AreEqual(expectedSpacingBetweenSlices.Value, float.Parse(actualSlice.SpacingBetweenSlices), tolerance, msg, "SpacingBetweenSlices"); } else { Assert.IsEmpty(actualSlice.SpacingBetweenSlices, msg, "SpacingBetweenSlices"); } }
public PatientOrientationHelper(ISpatialTransform imageTransform, ImageOrientationPatient imageOrientationPatient) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); _imageTransform = imageTransform; _imageOrientationPatient = imageOrientationPatient; AngleTolerance = 1; }
public PatientOrientationHelper(SpatialTransform imageTransform, ImageOrientationPatient imageOrientationPatient) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); _imageTransform = imageTransform; _imageOrientationPatient = imageOrientationPatient; AngleTolerance = 1; }
public void TestCoronalView() { NewTransform(); ImageOrientationPatient iop = new ImageOrientationPatient(1, 0, 0, 0, 0, -1); TestArbitraryImageOrientationPatient(iop, SR.ValueDirectionalMarkersRight, SR.ValueDirectionalMarkersHead, SR.ValueDirectionalMarkersLeft, SR.ValueDirectionalMarkersFoot); }
public void TestSaggittalView() { NewTransform(); ImageOrientationPatient iop = new ImageOrientationPatient(0, 1, 0, 0, 0, -1); TestArbitraryImageOrientationPatient(iop, SR.ValueDirectionalMarkersAnterior, SR.ValueDirectionalMarkersHead, SR.ValueDirectionalMarkersPosterior, SR.ValueDirectionalMarkersFoot); }
private static Matrix ImageOrientationPatientToMatrix(ImageOrientationPatient orientation) { Vector3D xOrient = new Vector3D((float)orientation.RowX, (float)orientation.RowY, (float)orientation.RowZ); Vector3D yOrient = new Vector3D((float)orientation.ColumnX, (float)orientation.ColumnY, (float)orientation.ColumnZ); Vector3D zOrient = xOrient.Cross(yOrient); Matrix orientationMatrix = Math3D.OrientationMatrixFromVectors(xOrient, yOrient, zOrient); return(orientationMatrix); }
public void TestObliqueView() { NewTransform(); ImageOrientationPatient iop = new ImageOrientationPatient(0.789570, -0.608964, -0.075781, -0.084157, 0.014871, -0.996342); TestArbitraryImageOrientationPatient(iop, SR.ValueDirectionalMarkersRight + SR.ValueDirectionalMarkersPosterior, SR.ValueDirectionalMarkersHead + SR.ValueDirectionalMarkersLeft, SR.ValueDirectionalMarkersLeft + SR.ValueDirectionalMarkersAnterior, SR.ValueDirectionalMarkersFoot + SR.ValueDirectionalMarkersRight); }
public void TestAxialView() { NewTransform(); ImageOrientationPatient iop = new ImageOrientationPatient(1, 0, 0, 0, 1, 0); TestArbitraryImageOrientationPatient(iop, SR.ValueDirectionalMarkersRight, SR.ValueDirectionalMarkersAnterior, SR.ValueDirectionalMarkersLeft, SR.ValueDirectionalMarkersPosterior); }
public void TestCosines() { ImageOrientationPatient iop = new ImageOrientationPatient(0.1, 0.2, 0.7, 0.2, 0.3, 0.5); Assert.AreEqual(iop.RowX, 0.1); Assert.AreEqual(iop.RowY, 0.2); Assert.AreEqual(iop.RowZ, 0.7); Assert.AreEqual(iop.ColumnX, 0.2); Assert.AreEqual(iop.ColumnY, 0.3); Assert.AreEqual(iop.ColumnZ, 0.5); }
/// <summary> /// Constructor. /// </summary> public ImagePlaneHelper(ImagePositionPatient imagePositionPatient, ImageOrientationPatient imageOrientationPatient, PixelSpacing pixelSpacing) { Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); Platform.CheckForNullReference(pixelSpacing, "pixelSpacing"); PixelSpacing = pixelSpacing; ImageOrientationPatient = imageOrientationPatient; ImagePositionPatient = imagePositionPatient; ImagePositionPatientVector = new Vector3D((float)ImagePositionPatient.X, (float)ImagePositionPatient.Y, (float)ImagePositionPatient.Z); }
/// <summary> /// Gets the normal vector describing the plane of the image in patient coordinates. /// </summary> /// <returns>The normal vector, or null if the <see cref="Frame"/>'s position information is invalid.</returns> public static Vector3D GetNormalVector(ImageOrientationPatient imageOrientationPatient) { if (imageOrientationPatient.IsNull) { return(null); } var left = new Vector3D((float)imageOrientationPatient.RowX, (float)imageOrientationPatient.RowY, (float)imageOrientationPatient.RowZ); var normal = left.Cross(new Vector3D((float)imageOrientationPatient.ColumnX, (float)imageOrientationPatient.ColumnY, (float)imageOrientationPatient.ColumnZ)); return(FloatComparer.AreEqual(normal.Magnitude, 0) ? Vector3D.Null : normal.Normalize()); }
/// <summary> /// Called by GetAnnotationText (and also by Unit Test code). Making this function internal simply makes it easier /// to write unit tests for this class (don't have to implement a fake PresentationImage). /// </summary> /// <param name="imageTransform">the image transform</param> /// <param name="imageOrientationPatient">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(SpatialTransform imageTransform, ImageOrientationPatient imageOrientationPatient) { SizeF[] imageEdgeVectors = new SizeF[4]; for (int i = 0; i < 4; ++i) { imageEdgeVectors[i] = imageTransform.ConvertToDestination(_edgeVectors[i]); } //find out which source image edge got transformed to coincide with this viewport edge. ImageEdge transformedEdge = GetTransformedEdge(imageEdgeVectors); //get the marker for the appropriate (source) image edge. return(GetMarker(transformedEdge, imageOrientationPatient)); }
/// <summary> /// Initializes a new instance of <see cref="ImagePlaneHelper"/> from the specified image plane details. /// </summary> public ImagePlaneHelper(ImagePositionPatient imagePositionPatient, ImageOrientationPatient imageOrientationPatient, PixelSpacing pixelSpacing, int rows, int columns) { Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); Platform.CheckForNullReference(pixelSpacing, "pixelSpacing"); Platform.CheckPositive(rows, "rows"); Platform.CheckPositive(columns, "columns"); _rows = rows; _columns = columns; _pixelSpacing = pixelSpacing; _imageOrientationPatient = imageOrientationPatient; _imagePositionPatient = imagePositionPatient; }
public Vector3D ConvertToPatient(PointF positionPixels, int z) { ImagePositionPatient pos = this._sourceFrame.ImagePositionPatient; Vector3D _imagePositionPatient = new Vector3D((float)pos.X, (float)pos.Y, (float)pos.Z); ImageOrientationPatient orientation = this._sourceFrame.ImageOrientationPatient; Vector3D left = new Vector3D((float)orientation.RowX, (float)orientation.RowY, (float)orientation.RowZ); Vector3D normal = left.Cross(new Vector3D((float)orientation.ColumnX, (float)orientation.ColumnY, (float)orientation.ColumnZ)); PixelSpacing pixelSpacing = this._sourceFrame.PixelSpacing; if (orientation.IsNull || pixelSpacing.IsNull) { return(null); } Vector3D position = _imagePositionPatient; if (positionPixels.X == 0F && positionPixels.Y == 0F) { return(position); } Matrix _pixelToPatientTransform = new Matrix(4, 4); _pixelToPatientTransform.SetColumn(0, (float)(orientation.RowX * pixelSpacing.Column), (float)(orientation.RowY * pixelSpacing.Column), (float)(orientation.RowZ * pixelSpacing.Column), 0); _pixelToPatientTransform.SetColumn(1, (float)(orientation.ColumnX * pixelSpacing.Row), (float)(orientation.ColumnY * pixelSpacing.Row), (float)(orientation.ColumnZ * pixelSpacing.Row), 0); _pixelToPatientTransform.SetColumn(2, (float)(normal.X * pixelSpacing.Row), (float)(normal.Y * pixelSpacing.Row), (float)(normal.Z * pixelSpacing.Row), 0); _pixelToPatientTransform.SetColumn(3, position.X, position.Y, position.Z, 1F); Matrix columnMatrix = new Matrix(4, 1); columnMatrix.SetColumn(0, positionPixels.X, positionPixels.Y, z, 1F); Matrix result = _pixelToPatientTransform * columnMatrix; return(new Vector3D(result[0, 0], result[1, 0], result[2, 0])); }
public static IPresentationImage PresentationImageFromPositionOrientation( ImagePositionPatient imagePositionPatient, ImageOrientationPatient imageOrientationPatient, IDisplaySet displaySet, string frameOfReferenceUid) { var point = new Vector3D( (float)imagePositionPatient.X, (float)imagePositionPatient.Y, (float)imagePositionPatient.Z); if (displaySet != null) { var firstSop = displaySet.PresentationImages.OfType <IImageSopProvider>().FirstOrDefault(); // Match Frame of Reference UID, if present if (firstSop == null || string.IsNullOrEmpty(frameOfReferenceUid) || string.IsNullOrEmpty(firstSop.Frame.FrameOfReferenceUid) || frameOfReferenceUid == firstSop.Frame.FrameOfReferenceUid) { foreach (IPresentationImage image in displaySet.PresentationImages) { var sop = image as IImageSopProvider; if (sop != null) { Vector3D planeRow = new Vector3D( (float)sop.Frame.ImageOrientationPatient.RowX, (float)sop.Frame.ImageOrientationPatient.RowY, (float)sop.Frame.ImageOrientationPatient.RowZ).Normalize(); Vector3D planeColumn = new Vector3D( (float)sop.Frame.ImageOrientationPatient.ColumnX, (float)sop.Frame.ImageOrientationPatient.ColumnY, (float)sop.Frame.ImageOrientationPatient.ColumnZ).Normalize(); Vector3D planeNormal = planeRow.Cross(planeColumn); var planePosition = new Vector3D( (float)sop.Frame.ImagePositionPatient.X, (float)sop.Frame.ImagePositionPatient.Y, (float)sop.Frame.ImagePositionPatient.Z); if (PointIsInPlane(point, planeNormal, planePosition)) { return(image); } } } } } return(null); }
/// <summary> /// Initializes a new instance of <see cref="ImagePlaneHelper"/> from the specified image plane details. /// </summary> public ImagePlaneHelper(ImagePositionPatient imagePositionPatient, ImageOrientationPatient imageOrientationPatient, PixelSpacing pixelSpacing, int rows, int columns) { Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); Platform.CheckForNullReference(pixelSpacing, "pixelSpacing"); try { Platform.CheckPositive(rows, "rows"); Platform.CheckPositive(columns, "columns"); } catch (Exception ex) { Platform.Log(LogLevel.Error, "the row is " + rows.ToString()); } _rows = rows; _columns = columns; _pixelSpacing = pixelSpacing; _imageOrientationPatient = imageOrientationPatient; _imagePositionPatient = imagePositionPatient; }
public Localize(DicomImageViewControl control, int sliceNumber, float sliceWidth, float sliceSize, float xFOV, float yFOV) { this.Control = control; this.sliceNumber = sliceNumber; this.sliceWidth = (int)(sliceWidth / this.Control.CurrentDicomElement.ImageSop.Frames[1].PixelSpacing.Row); this.sliceSize = (int)(sliceSize / this.Control.CurrentDicomElement.ImageSop.Frames[1].PixelSpacing.Row); this.xFOV = (int)(xFOV / this.Control.CurrentDicomElement.ImageSop.Frames[1].PixelSpacing.Row); this.yFOV = (int)(yFOV / this.Control.CurrentDicomElement.ImageSop.Frames[1].PixelSpacing.Column); this.ImageOrientationPatientOfReferenceImage = new ImageOrientationPatient( this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.RowX, this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.RowY, this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.RowZ, this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.ColumnX, this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.ColumnY, this.Control.CurrentDicomElement.ImageSop.Frames[1].ImageOrientationPatient.ColumnZ ); CreateSplices3D(); }
/// <summary> /// Determines the (untransformed) marker for a particular image edge. /// </summary> /// <param name="imageEdge">the edge (image coordinates)</param> /// <param name="imageOrientationPatient">the direction cosines of the image</param> /// <returns>a string representation of the direction (a 'marker')</returns> private string GetMarker(ImageEdge imageEdge, ImageOrientationPatient imageOrientationPatient) { bool negativeDirection = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Top); bool rowValues = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Right); string markerText = ""; if (rowValues) { ImageOrientationPatient.Directions primary = imageOrientationPatient.GetPrimaryRowDirection(negativeDirection); ImageOrientationPatient.Directions secondary = imageOrientationPatient.GetSecondaryRowDirection(negativeDirection, 1); markerText += GetMarkerText(primary); markerText += GetMarkerText(secondary); } else { ImageOrientationPatient.Directions primary = imageOrientationPatient.GetPrimaryColumnDirection(negativeDirection); ImageOrientationPatient.Directions secondary = imageOrientationPatient.GetSecondaryColumnDirection(negativeDirection, 1); markerText += GetMarkerText(primary); markerText += GetMarkerText(secondary); } return(markerText); }
public static void CreateSeriesGraphicsForSeg(IPresentationImage presentationImage, Seg seg, SegmentationDocument segmentationDocument, IDicomMessageSopDataSource dicomMessageSopDataSourceSop) { Platform.CheckForNullReference(presentationImage, "presentationImage"); Platform.CheckForNullReference(seg, "seg"); Platform.CheckForNullReference(segmentationDocument, "segmentationDocument"); SegmentImageData segImageData = seg.SegmentImageData; if (segImageData == null) { Platform.Log(LogLevel.Error, "Cannot create segmentation graphics when no segmentation imaging data is provided"); return; } var imageSopProvider = presentationImage as IImageSopProvider; if (imageSopProvider == null) { Platform.Log(LogLevel.Error, "Failed to populate SegFrameGraphics collection. Image is not an ImageSopProvider"); return; } DicomPixelData segmentationPixelData = DicomPixelData.CreateFrom(dicomMessageSopDataSourceSop.SourceMessage); var rawPixelData = (byte[])dicomMessageSopDataSourceSop.SourceMessage.DataSet.GetAttribute(DicomTags.PixelData).Values; var pixelDataGetter = new Func <int, byte[]>(frameIndex => { if (segImageData.BitsStored == 1) { // Do unpacking int frameLength = segImageData.Rows * segImageData.Columns; var overlayData = new OverlayData(frameIndex * frameLength, segImageData.Rows, segImageData.Columns, false, rawPixelData); return(overlayData.Unpack()); } if (segImageData.BitsStored == 8) { return(segmentationPixelData.GetFrame(frameIndex)); } throw new InvalidDataException( "Segmentation objects need to have BitsStored as either 1 or 8"); }); // NOTE: SegmentFrameData was already sorted foreach (SegmentFrameData segmentFrameData in segImageData.SegmentFrameData) { IPresentationImage segPresentationImage = null; // Get the presentation image if we have an image reference string referencedSopInstanceUid = segmentFrameData.ReferencedSopInstanceUid; int referencedImageFrameNumber = segmentFrameData.ReferencedFrameNumber ?? 1; if (!string.IsNullOrEmpty(referencedSopInstanceUid)) { segPresentationImage = presentationImage.ParentDisplaySet.PresentationImages.OfType <IImageSopProvider>() .FirstOrDefault(curImageSopProvider => curImageSopProvider != null && curImageSopProvider.ImageSop.SopInstanceUid == referencedSopInstanceUid && curImageSopProvider.Frame.FrameNumber == referencedImageFrameNumber) as IPresentationImage; } // Location defaults to 0, 0 unless determined otherwise from image position and image orientation var segLocation = new PointF(); // Get the presentation image from the image position and orientation if (segmentFrameData.ImagePositionPatient != null && segmentFrameData.ImagePositionPatient.Count() > 2 && segmentFrameData.ImageOrientationPatient != null && segmentFrameData.ImageOrientationPatient.Count() > 5) { var imagePositionPatient = new ImagePositionPatient( segmentFrameData.ImagePositionPatient[0], segmentFrameData.ImagePositionPatient[1], segmentFrameData.ImagePositionPatient[2]); var imageOrientationPatient = new ImageOrientationPatient( segmentFrameData.ImageOrientationPatient[0], segmentFrameData.ImageOrientationPatient[1], segmentFrameData.ImageOrientationPatient[2], segmentFrameData.ImageOrientationPatient[3], segmentFrameData.ImageOrientationPatient[4], segmentFrameData.ImageOrientationPatient[5]); IDisplaySet displaySet = presentationImage.ParentDisplaySet; if (segPresentationImage == null) { segPresentationImage = PresentationImageFromPositionOrientation( imagePositionPatient, imageOrientationPatient, displaySet, segImageData.FrameOfReferenceUid); } var imageSop = segPresentationImage as IImageSopProvider; if (imageSop != null) { Vector3D segImageLocation = imageSop.Frame.ImagePlaneHelper.ConvertToImagePlane(new Vector3D( (float)imagePositionPatient.X, (float)imagePositionPatient.Y, (float)imagePositionPatient.Z)); PointF?segPixelLocation = imageSop.Frame.ImagePlaneHelper.ConvertToImage( new PointF(segImageLocation.X, segImageLocation.Y)); if (segPixelLocation.HasValue) { segLocation = segPixelLocation.Value; } } } if (segPresentationImage != null) { SegFrameImageGraphic newGraphic = AddSegFrameImageGraphicToPresentationImage( segPresentationImage, segImageData.Rows, segImageData.Columns, segLocation.X, segLocation.Y, seg.Color, referencedImageFrameNumber, seg.Label, seg.Description, pixelDataGetter.Invoke(segmentFrameData.FrameNumber - 1), new SegmentationDocumentReference(segmentationDocument, seg.SegmentationNumber)); if (newGraphic != null && segPresentationImage == segPresentationImage.ParentDisplaySet.ImageBox.TopLeftPresentationImage) { newGraphic.Draw(); } } else { Platform.Log(LogLevel.Error, "Failed to find Presentation Image to display a segment on"); } } }
public static void CreateSeriesGraphicsForSeg(IPresentationImage presentationImage, Seg seg, SegmentationDocument segmentationDocument, IDicomMessageSopDataSource dicomMessageSopDataSourceSop) { Platform.CheckForNullReference(presentationImage, "presentationImage"); Platform.CheckForNullReference(seg, "seg"); Platform.CheckForNullReference(segmentationDocument, "segmentationDocument"); SegmentImageData segImageData = seg.SegmentImageData; if (segImageData == null) { Platform.Log(LogLevel.Error, "Cannot create segmentation graphics when no segmentation imaging data is provided"); return; } var imageSopProvider = presentationImage as IImageSopProvider; if (imageSopProvider == null) { Platform.Log(LogLevel.Error, "Failed to populate SegFrameGraphics collection. Image is not an ImageSopProvider"); return; } DicomPixelData segmentationPixelData = DicomPixelData.CreateFrom(dicomMessageSopDataSourceSop.SourceMessage); var rawPixelData = (byte[]) dicomMessageSopDataSourceSop.SourceMessage.DataSet.GetAttribute(DicomTags.PixelData).Values; var pixelDataGetter = new Func<int, byte[]>(frameIndex => { if (segImageData.BitsStored == 1) { // Do unpacking int frameLength = segImageData.Rows* segImageData.Columns; var overlayData = new OverlayData(frameIndex*frameLength, segImageData.Rows, segImageData.Columns, false, rawPixelData); return overlayData.Unpack(); } if (segImageData.BitsStored == 8) { return segmentationPixelData.GetFrame(frameIndex); } throw new InvalidDataException( "Segmentation objects need to have BitsStored as either 1 or 8"); }); // NOTE: SegmentFrameData was already sorted foreach (SegmentFrameData segmentFrameData in segImageData.SegmentFrameData) { IPresentationImage segPresentationImage = null; // Get the presentation image if we have an image reference string referencedSopInstanceUid = segmentFrameData.ReferencedSopInstanceUid; int referencedImageFrameNumber = segmentFrameData.ReferencedFrameNumber ?? 1; if (!string.IsNullOrEmpty(referencedSopInstanceUid)) { segPresentationImage = presentationImage.ParentDisplaySet.PresentationImages.OfType<IImageSopProvider>() .FirstOrDefault(curImageSopProvider => curImageSopProvider != null && curImageSopProvider.ImageSop.SopInstanceUid == referencedSopInstanceUid && curImageSopProvider.Frame.FrameNumber == referencedImageFrameNumber) as IPresentationImage; } // Location defaults to 0, 0 unless determined otherwise from image position and image orientation var segLocation = new PointF(); // Get the presentation image from the image position and orientation if (segmentFrameData.ImagePositionPatient != null && segmentFrameData.ImagePositionPatient.Count() > 2 && segmentFrameData.ImageOrientationPatient != null && segmentFrameData.ImageOrientationPatient.Count() > 5) { var imagePositionPatient = new ImagePositionPatient( segmentFrameData.ImagePositionPatient[0], segmentFrameData.ImagePositionPatient[1], segmentFrameData.ImagePositionPatient[2]); var imageOrientationPatient = new ImageOrientationPatient( segmentFrameData.ImageOrientationPatient[0], segmentFrameData.ImageOrientationPatient[1], segmentFrameData.ImageOrientationPatient[2], segmentFrameData.ImageOrientationPatient[3], segmentFrameData.ImageOrientationPatient[4], segmentFrameData.ImageOrientationPatient[5]); IDisplaySet displaySet = presentationImage.ParentDisplaySet; if (segPresentationImage == null) { segPresentationImage = PresentationImageFromPositionOrientation( imagePositionPatient, imageOrientationPatient, displaySet, segImageData.FrameOfReferenceUid); } var imageSop = segPresentationImage as IImageSopProvider; if (imageSop != null) { Vector3D segImageLocation = imageSop.Frame.ImagePlaneHelper.ConvertToImagePlane(new Vector3D( (float) imagePositionPatient.X, (float) imagePositionPatient.Y, (float) imagePositionPatient.Z)); PointF? segPixelLocation = imageSop.Frame.ImagePlaneHelper.ConvertToImage( new PointF(segImageLocation.X, segImageLocation.Y)); if (segPixelLocation.HasValue) segLocation = segPixelLocation.Value; } } if (segPresentationImage != null) { SegFrameImageGraphic newGraphic = AddSegFrameImageGraphicToPresentationImage( segPresentationImage, segImageData.Rows, segImageData.Columns, segLocation.X, segLocation.Y, seg.Color, referencedImageFrameNumber, seg.Label, seg.Description, pixelDataGetter.Invoke(segmentFrameData.FrameNumber - 1), new SegmentationDocumentReference(segmentationDocument, seg.SegmentationNumber)); if (newGraphic != null && segPresentationImage == segPresentationImage.ParentDisplaySet.ImageBox.TopLeftPresentationImage) { newGraphic.Draw(); } } else { Platform.Log(LogLevel.Error, "Failed to find Presentation Image to display a segment on"); } } }
public void TestEdges() { // See ImageOrientationPatient class for an explanation of the logic in the tests. //the fact that the row/column cosines aren't orthogonal doesn't matter here, we're just testing the algorithm. ImageOrientationPatient iop = new ImageOrientationPatient(0, 0, 0, 0, 0, 0); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.None); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.None); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.None); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.None); iop = new ImageOrientationPatient(0.1, 0.2, 0.7, 0.2, 0.3, 0.5); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Head); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Head); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Anterior); iop = new ImageOrientationPatient(0.1, -0.2, -0.7, 0.2, -0.3, -0.5); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Head); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Head); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Posterior); iop = new ImageOrientationPatient(0.7, -0.1, -0.2, 0.5, -0.2, -0.3); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Head); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Foot); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Head); iop = new ImageOrientationPatient(-0.2, -0.7, 0.1, -0.3, -0.5, -0.2); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Left); iop = new ImageOrientationPatient(-0.2, -0.7, 0.1, -0.3, -0.5, -0.2); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Left); iop = new ImageOrientationPatient(-0.2, -0.6, 0.2, -0.4, -0.3, -0.3); Assert.IsTrue(iop.GetPrimaryRowDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetSecondaryRowDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetPrimaryRowDirection(true) == ImageOrientationPatient.Directions.Posterior); Assert.IsTrue(iop.GetSecondaryRowDirection(true) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetPrimaryColumnDirection(false) == ImageOrientationPatient.Directions.Right); Assert.IsTrue(iop.GetSecondaryColumnDirection(false) == ImageOrientationPatient.Directions.Anterior); Assert.IsTrue(iop.GetPrimaryColumnDirection(true) == ImageOrientationPatient.Directions.Left); Assert.IsTrue(iop.GetSecondaryColumnDirection(true) == ImageOrientationPatient.Directions.Posterior); }
/// <summary> /// Validates and prepares the provided frames for the <see cref="VolumeBuilder"/>. /// </summary> /// <exception cref="CreateVolumeException">Thrown if something is wrong with the source frames.</exception> public static void PrepareFrames(List <IFrameReference> _frames) { // ensure we have at least 3 frames if (_frames.Count < 3) { throw new InsufficientFramesException(); } // ensure all frames have are from the same series, and have the same frame of reference string studyInstanceUid = _frames[0].Frame.StudyInstanceUid; string seriesInstanceUid = _frames[0].Frame.SeriesInstanceUid; string frameOfReferenceUid = _frames[0].Frame.FrameOfReferenceUid; if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid)) { throw new NullSourceSeriesException(); } if (string.IsNullOrEmpty(frameOfReferenceUid)) { throw new NullFrameOfReferenceException(); } foreach (IFrameReference frame in _frames) { if (frame.Frame.StudyInstanceUid != studyInstanceUid) { throw new MultipleSourceSeriesException(); } if (frame.Frame.SeriesInstanceUid != seriesInstanceUid) { throw new MultipleSourceSeriesException(); } if (frame.Frame.FrameOfReferenceUid != frameOfReferenceUid) { throw new MultipleFramesOfReferenceException(); } } // ensure all frames are of the same supported format foreach (IFrameReference frame in _frames) { if (frame.Frame.BitsAllocated != 16) { throw new UnsupportedPixelFormatSourceImagesException(); } } // ensure all frames have the same orientation ImageOrientationPatient orient = _frames[0].Frame.ImageOrientationPatient; foreach (IFrameReference frame in _frames) { if (frame.Frame.ImageOrientationPatient.IsNull) { if (frame.ImageSop.NumberOfFrames > 1) { throw new UnsupportedMultiFrameSourceImagesException(new NullImageOrientationException()); } throw new NullImageOrientationException(); } if (!frame.Frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance)) { throw new MultipleImageOrientationsException(); } if (frame.Frame.PixelSpacing.IsNull) { throw new UncalibratedFramesException(); } if (Math.Abs(frame.Frame.PixelSpacing.AspectRatio - 1) > _minimumSliceSpacing) { throw new AnisotropicPixelAspectRatioException(); } } // ensure all frames are sorted by slice location SliceLocationComparer sliceLocationComparer = new SliceLocationComparer(); _frames.Sort(delegate(IFrameReference x, IFrameReference y) { return(sliceLocationComparer.Compare(x.Frame, y.Frame)); }); // ensure all frames are equally spaced float?nominalSpacing = null; for (int i = 1; i < _frames.Count; i++) { float currentSpacing = CalcSpaceBetweenPlanes(_frames[i].Frame, _frames[i - 1].Frame); if (currentSpacing < _minimumSliceSpacing) { if (_frames[i].ImageSop.NumberOfFrames > 1) { throw new UnsupportedMultiFrameSourceImagesException(new UnevenlySpacedFramesException()); } throw new UnevenlySpacedFramesException(); } if (!nominalSpacing.HasValue) { nominalSpacing = currentSpacing; } if (!FloatComparer.AreEqual(currentSpacing, nominalSpacing.Value, _sliceSpacingTolerance)) { throw new UnevenlySpacedFramesException(); } } // ensure frames are not tilted about unsupposed axis combinations (the gantry correction algorithm only supports rotations about X) if (!IsSupportedGantryTilt(_frames)) // suffices to check first one... they're all co-planar now!! { throw new UnsupportedGantryTiltAxisException(); } }
private static Matrix ImageOrientationPatientToMatrix(ImageOrientationPatient orientation) { Vector3D xOrient = new Vector3D((float) orientation.RowX, (float) orientation.RowY, (float) orientation.RowZ); Vector3D yOrient = new Vector3D((float) orientation.ColumnX, (float) orientation.ColumnY, (float) orientation.ColumnZ); Vector3D zOrient = xOrient.Cross(yOrient); Matrix orientationMatrix = Math3D.OrientationMatrixFromVectors(xOrient, yOrient, zOrient); return orientationMatrix; }
/// <summary> /// Called by GetAnnotationText (and also by Unit Test code). Making this function internal simply makes it easier /// to write unit tests for this class (don't have to implement a fake PresentationImage). /// </summary> /// <param name="imageTransform">the image transform</param> /// <param name="imageOrientationPatient">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(SpatialTransform imageTransform, ImageOrientationPatient imageOrientationPatient) { SizeF[] imageEdgeVectors = new SizeF[4]; for (int i = 0; i < 4; ++i) imageEdgeVectors[i] = imageTransform.ConvertToDestination(_edgeVectors[i]); //find out which source image edge got transformed to coincide with this viewport edge. ImageEdge transformedEdge = GetTransformedEdge(imageEdgeVectors); //get the marker for the appropriate (source) image edge. return GetMarker(transformedEdge, imageOrientationPatient); }
/// <summary> /// Determines the (untransformed) marker for a particular image edge. /// </summary> /// <param name="imageEdge">the edge (image coordinates)</param> /// <param name="imageOrientationPatient">the direction cosines of the image</param> /// <returns>a string representation of the direction (a 'marker')</returns> private string GetMarker(ImageEdge imageEdge, ImageOrientationPatient imageOrientationPatient) { bool negativeDirection = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Top); bool rowValues = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Right); string markerText = ""; if (rowValues) { ImageOrientationPatient.Directions primary = imageOrientationPatient.GetPrimaryRowDirection(negativeDirection); ImageOrientationPatient.Directions secondary = imageOrientationPatient.GetSecondaryRowDirection(negativeDirection, 1); markerText += GetMarkerText(primary); markerText += GetMarkerText(secondary); } else { ImageOrientationPatient.Directions primary = imageOrientationPatient.GetPrimaryColumnDirection(negativeDirection); ImageOrientationPatient.Directions secondary = imageOrientationPatient.GetSecondaryColumnDirection(negativeDirection, 1); markerText += GetMarkerText(primary); markerText += GetMarkerText(secondary); } return markerText; }
/// <summary> /// The directional marker annotation items simply calculate /// </summary> private void TestArbitraryImageOrientationPatient ( ImageOrientationPatient iop, string leftLabelNoTransform, string topLabelNoTransform, string rightLabelNoTransform, string bottomLabelNoTransform ) { // For an explanation of why this works see the DirectionalMarkerAnnotationItem class. // Notice how on 90 degree rotations, the labels roll upward (in this editor). That is // the nature of the algorithm and is what we expect to happen. Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); _transform.RotationXY = -90; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); _transform.RotationXY = -180; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); _transform.RotationXY = -270; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); _transform.RotationXY = -0; _transform.FlipY = true; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); _transform.RotationXY = -90; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); _transform.RotationXY = -180; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); _transform.RotationXY = -270; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); }
/// <summary> /// The directional marker annotation items simply calculate /// </summary> private void TestArbitraryImageOrientationPatient (ImageOrientationPatient iop, string leftLabelNoTransform, string topLabelNoTransform, string rightLabelNoTransform, string bottomLabelNoTransform ) { // For an explanation of why this works see the DirectionalMarkerAnnotationItem class. // Notice how on 90 degree rotations, the labels roll upward (in this editor). That is // the nature of the algorithm and is what we expect to happen. Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); _transform.RotationXY = -90; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); _transform.RotationXY = -180; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); _transform.RotationXY = -270; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); _transform.RotationXY = -0; _transform.FlipY = true; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); _transform.RotationXY = -90; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); _transform.RotationXY = -180; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); _transform.RotationXY = -270; Assert.AreEqual(_leftAnnotation.GetAnnotationTextInternal(_transform, iop), bottomLabelNoTransform); Assert.AreEqual(_topAnnotation.GetAnnotationTextInternal(_transform, iop), rightLabelNoTransform); Assert.AreEqual(_rightAnnotation.GetAnnotationTextInternal(_transform, iop), topLabelNoTransform); Assert.AreEqual(_bottomAnnotation.GetAnnotationTextInternal(_transform, iop), leftLabelNoTransform); }
public static IPresentationImage PresentationImageFromPositionOrientation( double[] imagePositionPatientValues, double[] imageOrientationPatientValues, IDisplaySet displaySet, string frameOfReferenceUid) { Platform.CheckForNullReference(displaySet, "displaySet"); if (imagePositionPatientValues != null && imagePositionPatientValues.Length > 2 && imageOrientationPatientValues != null && imageOrientationPatientValues.Length > 5) { var imagePositionPatient = new ImagePositionPatient( imagePositionPatientValues[0], imagePositionPatientValues[1], imagePositionPatientValues[2]); var imageOrientationPatient = new ImageOrientationPatient( imageOrientationPatientValues[0], imageOrientationPatientValues[1], imageOrientationPatientValues[2], imageOrientationPatientValues[3], imageOrientationPatientValues[4], imageOrientationPatientValues[5]); return PresentationImageFromPositionOrientation( imagePositionPatient, imageOrientationPatient, displaySet, frameOfReferenceUid); } return null; }
private static IEnumerable <Frame> FilterSourceFrames(IDisplaySet displaySet, IPresentationImage currentImage) { // this method tries to filter the source display set based on the currently selected image before passing it to MPR // we need this because sometimes MPR-able content is found in a series concatenated with other frames (e.g. 3-plane loc) if (currentImage is IImageSopProvider) { Frame currentFrame = ((IImageSopProvider)currentImage).Frame; string studyInstanceUid = currentFrame.StudyInstanceUid; string seriesInstanceUid = currentFrame.SeriesInstanceUid; string frameOfReferenceUid = currentFrame.FrameOfReferenceUid; ImageOrientationPatient imageOrientationPatient = currentFrame.ImageOrientationPatient; // if the current frame is missing any of the matching parameters, then it is always an error if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid)) { throw new NullSourceSeriesException(); } if (string.IsNullOrEmpty(frameOfReferenceUid)) { throw new NullFrameOfReferenceException(); } if (imageOrientationPatient == null || imageOrientationPatient.IsNull) { if (currentFrame.ParentImageSop.NumberOfFrames > 1) { throw new UnsupportedMultiFrameSourceImagesException(new NullImageOrientationException()); } throw new NullImageOrientationException(); } // if the current frame is not a supported pixel format, then it is always an error if (currentFrame.BitsAllocated != 16) { throw new UnsupportedPixelFormatSourceImagesException(); } // perform a very basic filtering of the selected display set based on the currently selected image var filteredFrames = new List <Frame>(); foreach (IPresentationImage image in displaySet.PresentationImages) { if (image == currentImage) { filteredFrames.Add(currentFrame); } else if (image is IImageSopProvider) { Frame frame = ((IImageSopProvider)image).Frame; if (frame.StudyInstanceUid == studyInstanceUid && frame.SeriesInstanceUid == seriesInstanceUid && frame.FrameOfReferenceUid == frameOfReferenceUid && !frame.ImageOrientationPatient.IsNull && frame.ImageOrientationPatient.EqualsWithinTolerance(imageOrientationPatient, .01f)) { filteredFrames.Add(frame); } } } // if we found at least 3 frames matching the current image, then return those to MPR if (filteredFrames.Count > 3) { return(filteredFrames); } // JY: #6164 - Error message not accurate for MPR with no location information // if we don't find 3 matching frames, then MPR fails on the minimum frames error // which masks the fact that there *were* enough frames, just not enough frames matching some aspect filter criteria // we don't know what was the specific failed criterion, so we'll just pass all frames unfiltered // this lets MPR decide what's wrong with the display set here and throw the correct exception return(CollectionUtils.Map <IPresentationImage, Frame>(displaySet.PresentationImages, img => img is IImageSopProvider ? ((IImageSopProvider)img).Frame : null)); } else { throw new UnsupportedSourceImagesException(); } }
public bool CheckPETFusionSeries(Series series, out string error) { if (!IsValidPETFusionSeries(series)) { error = SR.MessageInvalidSeries; return(false); } var frames = GetFrames(series.Sops); if (!AssertSameSeriesFrameOfReference(frames)) { error = SR.MessageInconsistentFramesOfReference; return(false); } // ensure all frames have the same orientation ImageOrientationPatient orient = frames[0].ImageOrientationPatient; double minColumnSpacing = double.MaxValue, minRowSpacing = double.MaxValue; double maxColumnSpacing = double.MinValue, maxRowSpacing = double.MinValue; foreach (Frame frame in frames) { if (frame.ImageOrientationPatient.IsNull) { error = SR.MessageMissingImageOrientation; return(false); } if (!frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance)) { error = SR.MessageInconsistentImageOrientation; return(false); } PixelSpacing pixelSpacing = frame.NormalizedPixelSpacing; if (pixelSpacing.IsNull) { error = SR.MessageMissingPixelSpacing; return(false); } minColumnSpacing = Math.Min(minColumnSpacing, pixelSpacing.Column); maxColumnSpacing = Math.Max(maxColumnSpacing, pixelSpacing.Column); minRowSpacing = Math.Min(minRowSpacing, pixelSpacing.Row); maxRowSpacing = Math.Max(maxRowSpacing, pixelSpacing.Row); } //Aren't many of these rules taken from MPR? If so, we should create a rule object. // ensure all frames have consistent pixel spacing if (maxColumnSpacing - minColumnSpacing > _sliceSpacingTolerance || maxRowSpacing - minRowSpacing > _sliceSpacingTolerance) { error = SR.MessageInconsistentPixelSpacing; return(false); } // ensure all frames are sorted by slice location frames.Sort(new SliceLocationComparer().Compare); // ensure all frames are equally spaced float?nominalSpacing = null; for (int i = 1; i < frames.Count; i++) { float currentSpacing = CalcSpaceBetweenPlanes(frames[i], frames[i - 1]); if (currentSpacing < _minimumSliceSpacing) { error = SR.MessageInconsistentImageSpacing; return(false); } if (!nominalSpacing.HasValue) { nominalSpacing = currentSpacing; } if (!FloatComparer.AreEqual(currentSpacing, nominalSpacing.Value, _sliceSpacingTolerance)) { error = SR.MessageInconsistentImageSpacing; return(false); } } // ensure frames are not tilted about unsupposed axis combinations (the gantry correction algorithm only supports rotations about X) if (!IsSupportedGantryTilt(frames)) // suffices to check first one... they're all co-planar now!! { error = SR.MessageUnsupportedGantryTilt; return(false); } error = null; return(true); }
/// <summary> /// Gets the unit normal vector describing the specified image plane in patient coordinates. /// </summary> /// <returns>The unit normal vector, or null if the <see cref="Frame"/>'s position information is invalid.</returns> public static Vector3D GetNormalVector(ImageOrientationPatient imageOrientationPatient) { if (imageOrientationPatient.IsNull) return null; var left = new Vector3D((float) imageOrientationPatient.RowX, (float) imageOrientationPatient.RowY, (float) imageOrientationPatient.RowZ); var normal = left.Cross(new Vector3D((float) imageOrientationPatient.ColumnX, (float) imageOrientationPatient.ColumnY, (float) imageOrientationPatient.ColumnZ)); return FloatComparer.AreEqual(normal.Magnitude, 0) ? Vector3D.Null : normal.Normalize(); }
public static IPresentationImage PresentationImageFromPositionOrientation( ImagePositionPatient imagePositionPatient, ImageOrientationPatient imageOrientationPatient, IDisplaySet displaySet, string frameOfReferenceUid) { var point = new Vector3D( (float) imagePositionPatient.X, (float) imagePositionPatient.Y, (float) imagePositionPatient.Z); if (displaySet != null) { var firstSop = displaySet.PresentationImages.OfType<IImageSopProvider>().FirstOrDefault(); // Match Frame of Reference UID, if present if (firstSop == null || string.IsNullOrEmpty(frameOfReferenceUid) || string.IsNullOrEmpty(firstSop.Frame.FrameOfReferenceUid) || frameOfReferenceUid == firstSop.Frame.FrameOfReferenceUid) { foreach (IPresentationImage image in displaySet.PresentationImages) { var sop = image as IImageSopProvider; if (sop != null) { Vector3D planeRow = new Vector3D( (float) sop.Frame.ImageOrientationPatient.RowX, (float) sop.Frame.ImageOrientationPatient.RowY, (float) sop.Frame.ImageOrientationPatient.RowZ).Normalize(); Vector3D planeColumn = new Vector3D( (float) sop.Frame.ImageOrientationPatient.ColumnX, (float) sop.Frame.ImageOrientationPatient.ColumnY, (float) sop.Frame.ImageOrientationPatient.ColumnZ).Normalize(); Vector3D planeNormal = planeRow.Cross(planeColumn); var planePosition = new Vector3D( (float) sop.Frame.ImagePositionPatient.X, (float) sop.Frame.ImagePositionPatient.Y, (float) sop.Frame.ImagePositionPatient.Z); if (PointIsInPlane(point, planeNormal, planePosition)) return image; } } } } return null; }
private static void InitializePlaneOrientationPatientFunctionalGroup(FunctionalGroupsSequenceItem functionalGroupsSequenceItem, ImageOrientationPatient imageOrientationPatient) { if (imageOrientationPatient.IsNull) return; var planeOrientationPatientFunctionalGroup = functionalGroupsSequenceItem.GetFunctionalGroup<PlaneOrientationPatientFunctionalGroup>(); var planeOrientationPatientSequence = planeOrientationPatientFunctionalGroup.CreatePlaneOrientationSequence(); planeOrientationPatientSequence.ImageOrientationPatient = new[] { imageOrientationPatient.RowX, imageOrientationPatient.RowY, imageOrientationPatient.RowZ, imageOrientationPatient.ColumnX, imageOrientationPatient.ColumnY, imageOrientationPatient.ColumnZ }; planeOrientationPatientFunctionalGroup.PlaneOrientationSequence = planeOrientationPatientSequence; }