void IProbe.Probe(PointF coordinate, CoordinateSystem coordinateSystem) { if (Context.Viewer.SelectedTile == null) { throw new InvalidOperationException("No tile selected."); } if (SelectedPresentationImage == null) { throw new InvalidOperationException("No image selected."); } if (SelectedSpatialTransformProvider == null) { throw new InvalidOperationException("Unsupported image type selected."); } if (coordinateSystem == CoordinateSystem.Destination) { coordinate = SelectedSpatialTransformProvider.SpatialTransform.ConvertToSource(coordinate); } _selectedTile = (Tile)Context.Viewer.SelectedTile; _selectedTile.InformationBox = new InformationBox(); _selectedImageGraphic = SelectedImageGraphicProvider != null ? SelectedImageGraphicProvider.ImageGraphic : null; _selectedSpatialTransform = SelectedSpatialTransformProvider.SpatialTransform; _selectedFrame = ((IImageSopProvider)SelectedPresentationImage).Frame; _selectedCoordinateMapping = SelectedPresentationImage is IPatientCoordinateMappingProvider ? ((IPatientCoordinateMappingProvider)SelectedPresentationImage).PatientCoordinateMapping : null; Probe(Point.Truncate(coordinate), true, true); }
public void Apply(IPresentationImage image) { ISpatialTransform transform = (ISpatialTransform)_operation.GetOriginator(image); transform.TranslationX = this.SelectedSpatialTransformProvider.SpatialTransform.TranslationX; transform.TranslationY = this.SelectedSpatialTransformProvider.SpatialTransform.TranslationY; }
public static DicomImagePlane FromImage(IPresentationImage sourceImage) { if (sourceImage == null) { return(null); } Frame frame = GetFrame(sourceImage); ISpatialTransform transform = GetSpatialTransform(sourceImage); if (transform == null || frame == null) { return(null); } if (String.IsNullOrEmpty(frame.FrameOfReferenceUid) || String.IsNullOrEmpty(frame.ParentImageSop.StudyInstanceUid)) { return(null); } if (!frame.ImagePlaneHelper.IsValid) { return(null); } return(new DicomImagePlane(sourceImage, transform, frame)); }
/// <summary> /// Performs validation on the specified <see cref="ISpatialTransform"/>. /// </summary> /// <param name="transform"></param> /// <remarks> /// At present, validation amounts to ensuring the rotation is always zero. /// <see cref="RoiGraphic"/>s are prohibited from being rotated /// because calculation of ROI related statistics, such as mean and standard deviation, /// currently only work with unrotated ROIs. /// </remarks> public override void Validate(ISpatialTransform transform) { if (transform.RotationXY != 0) { throw new ArgumentException("ROIs cannot be rotated."); } }
public PatientOrientationHelper(ISpatialTransform imageTransform, PatientOrientation patientOrientation) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(patientOrientation, "patientOrientation"); _imageTransform = imageTransform; _patientOrientation = patientOrientation; AngleTolerance = 1; }
public PatientOrientationHelper(ISpatialTransform imageTransform, ImageOrientationPatient imageOrientationPatient) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(imageOrientationPatient, "imageOrientationPatient"); _imageTransform = imageTransform; _imageOrientationPatient = imageOrientationPatient; AngleTolerance = 1; }
/// <summary> /// Performs validation on the specified <see cref="ISpatialTransform"/>. /// </summary> /// <param name="transform"></param> /// <remarks> /// At present, validation amounts to ensuring that rotations are /// only in increments of 90 degrees. /// </remarks> public override void Validate(ISpatialTransform transform) { PointF xVector = new PointF(100, 0); SizeF xVectorTransformed = ((SpatialTransform)transform).ConvertToDestination(new SizeF(xVector)); //figure out where the source x-axis went in destination int rotation = (int) Math.Round(Vector.SubtendedAngle(xVectorTransformed.ToPointF(), PointF.Empty, xVector)); if (rotation < 0) rotation += 360; if ((rotation % 90) != 0) throw new ArgumentException("Images can only be rotated by multiples of 90 degrees."); }
private void IncrementPan(int xIncrement, int yIncrement) { if (!CanPan()) { return; } ISpatialTransform transform = _operation.GetOriginator(SelectedPresentationImage); transform.Translate(xIncrement, yIncrement); SelectedPresentationImage.Draw(); }
protected void SerializeSpatialTransform(SpatialTransformModuleIod spatialTransformModule, DicomPresentationImageCollection <T> images) { foreach (T image in images) { // spatial transform defines rotation in cartesian space - dicom module defines rotation as clockwise in image space // spatial transform defines both horizontal and vertical flip - dicom module defines horizontal flip only (vertical flip is 180 rotation plus horizontal flip) ISpatialTransform spatialTransform = image.SpatialTransform; int rotationBy90 = (((spatialTransform.RotationXY % 360) + 360) % 360) / 90; int flipState = (spatialTransform.FlipX ? 2 : 0) + (spatialTransform.FlipY ? 1 : 0); spatialTransformModule.ImageRotation = _spatialTransformRotationTranslation[rotationBy90 + 4 * flipState]; spatialTransformModule.ImageHorizontalFlip = spatialTransform.FlipY ^ spatialTransform.FlipX ? ImageHorizontalFlip.Y : ImageHorizontalFlip.N; break; } }
/// <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="patientOrientation">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(ISpatialTransform imageTransform, PatientOrientation patientOrientation) { 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, patientOrientation)); }
protected void SerializeDisplayedArea(DisplayedAreaModuleIod displayedAreaModule, DicomPresentationImageCollection <T> images) { displayedAreaModule.InitializeAttributes(); List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem> displayedAreas = new List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem>(); foreach (T image in images) { DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem displayedArea = new DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem(); displayedArea.InitializeAttributes(); displayedArea.ReferencedImageSequence = new[] { CreateImageSopInstanceReference(image.Frame) }; ImageGraphic imageGraphic = ((IImageGraphicProvider)image).ImageGraphic; Size imageSize = new Size(imageGraphic.Columns, imageGraphic.Rows); // compute the visible area of the image as a rectangle oriented positively in screen space RectangleF visibleImageArea = imageGraphic.SpatialTransform.ConvertToSource(image.ClientRectangle); visibleImageArea = RectangleUtilities.ConvertToPositiveRectangle(visibleImageArea); visibleImageArea = RectangleUtilities.RoundInflate(visibleImageArea); visibleImageArea = RectangleUtilities.Intersect(visibleImageArea, new Rectangle(new Point(0, 0), imageSize)); // compute the pixel addresses of the visible area by intersecting area with actual pixel addresses available Rectangle visiblePixels = ConvertToPixelAddressRectangle(Rectangle.Truncate(visibleImageArea)); displayedArea.DisplayedAreaTopLeftHandCorner = visiblePixels.Location; displayedArea.DisplayedAreaBottomRightHandCorner = visiblePixels.Location + visiblePixels.Size; ISpatialTransform spatialTransform = image.SpatialTransform; switch (_displayAreaSerializationOption) { case DisplayAreaSerializationOption.SerializeAsMagnification: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.Magnify; displayedArea.PresentationPixelMagnificationRatio = spatialTransform.Scale; break; case DisplayAreaSerializationOption.SerializeAsTrueSize: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.TrueSize; displayedArea.PresentationPixelSpacing = image.Frame.NormalizedPixelSpacing; break; case DisplayAreaSerializationOption.SerializeAsDisplayedArea: default: displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.ScaleToFit; break; } displayedArea.PresentationPixelAspectRatio = PixelAspectRatio.FromString(image.Frame.NormalizedPixelSpacing.GetPixelAspectRatioString()); displayedAreas.Add(displayedArea); } displayedAreaModule.DisplayedAreaSelectionSequence = displayedAreas.ToArray(); }
public override void Cancel() { if (_selectedTile == null || _selectedSpatialTransform == null) { return; } _selectedImageGraphic = null; _selectedSpatialTransform = null; _selectedFrame = null; _selectedCoordinateMapping = null; _selectedTile.InformationBox.Visible = false; _selectedTile.InformationBox = null; _selectedTile = null; }
public void Apply(IPresentationImage image) { ISpatialTransform transform = (ISpatialTransform)_operation.GetOriginator(image); // Do the transform if (transform.RotationXY == 0 || transform.RotationXY == 180) { transform.FlipX = !transform.FlipX; } // If image is rotated 90 or 270, then a vertical flip is really a horizontal flip else { transform.FlipY = !transform.FlipY; } }
/// <summary> /// Performs validation on the specified <see cref="ISpatialTransform"/>. /// </summary> /// <param name="transform"></param> /// <remarks> /// At present, validation amounts to ensuring that rotations are /// only in increments of 90 degrees. /// </remarks> public override void Validate(ISpatialTransform transform) { PointF xVector = new PointF(100, 0); SizeF xVectorTransformed = ((SpatialTransform)transform).ConvertToDestination(new SizeF(xVector)); //figure out where the source x-axis went in destination int rotation = (int)Math.Round(Vector.SubtendedAngle(xVectorTransformed.ToPointF(), PointF.Empty, xVector)); if (rotation < 0) { rotation += 360; } if ((rotation % 90) != 0) { throw new ArgumentException("Images can only be rotated by multiples of 90 degrees."); } }
private static SizeF GetPresentationImageSizeF(ISelectPresentationsInformation selectPresentation, int size) { //1英寸等于25.4毫米 float num = 25.4f / ((float)size); IPresentationImage image1 = selectPresentation.Image; Frame frame = ((IImageSopProvider)image1).Frame; switch (selectPresentation.PresentationMode) { case PresentationMode.Wysiwyg: { Rectangle rectangle = selectPresentation.DisplayRectangle; int width = rectangle.Width; Rectangle rectangle2 = selectPresentation.DisplayRectangle; int height = rectangle2.Height; return(new SizeF(width * num, height * num)); } case PresentationMode.CompleteImage: { int columns = frame.Columns; return(new SizeF(columns * num, frame.Rows * num)); } case PresentationMode.TrueSize: { int num1 = frame.Columns; NormalizedPixelSpacing normalizedPixelSpacing = frame.NormalizedPixelSpacing; int rows = frame.Rows; NormalizedPixelSpacing spacing2 = frame.NormalizedPixelSpacing; double row = spacing2.Row; SizeF ef = new SizeF((float)(num1 * normalizedPixelSpacing.Column), (float)(rows * row)); IPresentationImage image2 = selectPresentation.Image; ISpatialTransform spatialTransform = ((ISpatialTransformProvider)image2).SpatialTransform; if (((spatialTransform.RotationXY / 90) % 2) == 1) { float single1 = ef.Height; ef = new SizeF(single1, ef.Width); } return(ef); } } return(SizeF.Empty); }
private void IncrementPan(int xIncrement, int yIncrement) { if (!CanPan()) { return; } ISpatialTransform transform = _operation.GetOriginator(this.SelectedPresentationImage); // Because the pan increment is in destination coordinates, we have to convert // them to source coordinates, since the transform translation is in source coordinates. // This will allow the pan to work properly irrespective of the zoom, flip and rotation. SizeF sourceIncrement = transform.ConvertToSource(new SizeF(xIncrement, yIncrement)); transform.TranslationX += sourceIncrement.Width; transform.TranslationY += sourceIncrement.Height; this.SelectedPresentationImage.Draw(); }
public override bool Start(IMouseInformation mouseInformation) { if (SelectedSpatialTransformProvider == null || SelectedImageSopProvider == null) { return(false); } _selectedTile = mouseInformation.Tile as Tile; if (_selectedTile == null) { return(false); // if it's not Tile, then we can't do anything } _selectedTile.InformationBox = new InformationBox(); _selectedImageGraphic = SelectedImageGraphicProvider != null ? SelectedImageGraphicProvider.ImageGraphic : null; _selectedFrame = ((IImageSopProvider)SelectedPresentationImage).Frame; _selectedCoordinateMapping = SelectedPresentationImage is IPatientCoordinateMappingProvider ? ((IPatientCoordinateMappingProvider)SelectedPresentationImage).PatientCoordinateMapping : null; _selectedSpatialTransform = SelectedSpatialTransformProvider.SpatialTransform; Probe(mouseInformation.Location); return(true); }
protected void DeserializeSpatialTransform(SpatialTransformModuleIod module, T image) { ISpatialTransform spatialTransform = image.SpatialTransform; if (spatialTransform is IImageSpatialTransform) { IImageSpatialTransform iist = (IImageSpatialTransform)spatialTransform; iist.ScaleToFit = false; } if (module.ImageHorizontalFlip == ImageHorizontalFlip.Y) { spatialTransform.FlipX = false; spatialTransform.FlipY = true; spatialTransform.RotationXY = (360 - module.ImageRotation) % 360; } else { spatialTransform.FlipX = false; spatialTransform.FlipY = false; spatialTransform.RotationXY = module.ImageRotation; } }
/// <summary> /// Performs validation on the specified <see cref="ISpatialTransform"/>. /// </summary> /// <param name="transform"></param> /// <remarks> /// Implementors should throw an <see cref="ArgumentException"/> if validation fails. /// </remarks> public abstract void Validate(ISpatialTransform transform);
/// <summary> /// Performs validation on the specified <see cref="ISpatialTransform"/>. /// </summary> /// <param name="transform"></param> /// <remarks> /// At present, validation amounts to ensuring the rotation is always zero. /// <see cref="RoiGraphic"/>s are prohibited from being rotated /// because calculation of ROI related statistics, such as mean and standard deviation, /// currently only work with unrotated ROIs. /// </remarks> public override void Validate(ISpatialTransform transform) { if (transform.RotationXY != 0) throw new ArgumentException("ROIs cannot be rotated."); }
public void Apply(IPresentationImage image) { ISpatialTransform transform = (ISpatialTransform)_operation.GetOriginator(image); transform.FlipVertical(); }
public void Apply(IPresentationImage image) { ISpatialTransform transform = (ISpatialTransform)_operation.GetOriginator(image); transform.RotationXY += 90; }
private DicomImagePlane(IPresentationImage sourceImage, ISpatialTransform sourceImageTransform, Frame sourceFrame) { _sourceImage = sourceImage; _sourceImageTransform = sourceImageTransform; _sourceFrame = sourceFrame; }
protected void DeserializeDisplayedArea(DisplayedAreaModuleIod dispAreaMod, out RectangleF displayedArea, T image) { ISpatialTransform spatialTransform = image.SpatialTransform; foreach (DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem item in dispAreaMod.DisplayedAreaSelectionSequence) { var dictionary = !DeserializeIgnoreImageRelationship ? new ImageSopInstanceReferenceDictionary(item.ReferencedImageSequence, true) : null; if (dictionary == null || dictionary.ReferencesFrame(image.Frame.SopInstanceUid, image.Frame.FrameNumber)) { // get the displayed area of the image in source coordinates (stored values do not have sub-pixel accuracy) var displayRect = RectangleF.FromLTRB(item.DisplayedAreaTopLeftHandCorner.X, item.DisplayedAreaTopLeftHandCorner.Y, item.DisplayedAreaBottomRightHandCorner.X, item.DisplayedAreaBottomRightHandCorner.Y); displayRect = RectangleUtilities.ConvertToPositiveRectangle(displayRect); displayRect.Location = displayRect.Location - new SizeF(1, 1); displayRect.Size = displayRect.Size + new SizeF(1, 1); var centerDisplay = true; switch (item.PresentationSizeMode) { case DisplayedAreaModuleIod.PresentationSizeMode.Magnify: // displays selected area at specified magnification factor spatialTransform.Scale = (float)item.PresentationPixelMagnificationRatio.GetValueOrDefault(1); break; case DisplayedAreaModuleIod.PresentationSizeMode.TrueSize: // currently no support for determining true size, so default to scale area to fit case DisplayedAreaModuleIod.PresentationSizeMode.ScaleToFit: case DisplayedAreaModuleIod.PresentationSizeMode.None: default: if (spatialTransform is IImageSpatialTransform && displayRect.Location == new PointF(0, 0) && displayRect.Size == new SizeF(image.ImageGraphic.Columns, image.ImageGraphic.Rows)) { // if the display rect is the whole image, then take advantage of the built-in scale image to fit functionality IImageSpatialTransform iist = (IImageSpatialTransform)spatialTransform; iist.ScaleToFit = true; centerDisplay = false; // when ScaleToFit is true, the image will automatically be positioned correctly in the client area } else { var clientArea = image.ClientRectangle.Size; var displaySize = displayRect.Size; // if image is rotated 90 or 270, transpose width/height if (Math.Abs(Math.Round(Math.Sin(spatialTransform.RotationXY * Math.PI / 180))) > 0) { displaySize = new SizeF(displaySize.Height, displaySize.Width); } // compute the maximum magnification that allows the entire displayRect to be visible spatialTransform.Scale = Math.Min(clientArea.Width / displaySize.Width, clientArea.Height / displaySize.Height); } break; } if (centerDisplay) { // compute translation so that the displayRect is centered in the clientRect var displayCentre = GetRectangleCenter(displayRect); var clientCentre = spatialTransform.ConvertToSource(GetRectangleCenter(image.ClientRectangle)); spatialTransform.TranslationX = clientCentre.X - displayCentre.X; spatialTransform.TranslationY = clientCentre.Y - displayCentre.Y; } displayedArea = displayRect; return; } } displayedArea = new RectangleF(0, 0, image.ImageGraphic.Columns, image.ImageGraphic.Rows); }
/// <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="patientOrientation">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(ISpatialTransform imageTransform, PatientOrientation patientOrientation) { 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, patientOrientation); }