/// <summary> /// Creates a <see cref="SegFrameImageGraphic"/> and adds the graphic to the given <see cref="IPresentationImage"/> /// </summary> /// <param name="presentationImage">The image to add the graphic to</param> /// <param name="rows">Number of rows in the new graphic</param> /// <param name="columns">Number of columns in the new graphic</param> /// <param name="xLocation">X coordinate of the graphic's origin</param> /// <param name="yLocation">Y coordinate of the graphic's origin</param> /// <param name="color">Color of the new graphic</param> /// <param name="frameIndex">Image frame index</param> /// <param name="label">Graphic's label</param> /// <param name="description">Graphic's description</param> /// <param name="segPixelData">8-bit pixel data of the segmentation overlay</param> /// <param name="segmentationDocumentReference">Reference to the Segmentation document this graphic is created for</param> /// <returns></returns> public static SegFrameImageGraphic AddSegFrameImageGraphicToPresentationImage( IPresentationImage presentationImage, int rows, int columns, float xLocation, float yLocation, Color color, int frameIndex, string label, string description, byte[] segPixelData, SegmentationDocumentReference segmentationDocumentReference) { // TODO VK: use IApplicationGraphicsProvider here!!! var overlayGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider == null) { return(null); } var segFrameImageGraphic = new SegFrameImageGraphic(rows, columns, xLocation, yLocation, color, frameIndex, -1, label, description, segPixelData, segmentationDocumentReference); segFrameImageGraphic.Alpha = Seg.DefaultOpacity; var sopProvider = presentationImage as IImageSopProvider; if (sopProvider != null) { segFrameImageGraphic.ImageSopInstanceUid = sopProvider.Sop.SopInstanceUid; segFrameImageGraphic.ImageFrameNumber = sopProvider.Frame.FrameNumber; segFrameImageGraphic.ImageNumber = sopProvider.ImageSop.InstanceNumber; } overlayGraphicsProvider.OverlayGraphics.Add(segFrameImageGraphic); return(segFrameImageGraphic); }
public static SegFrameImageGraphic AddSegFrameImageGraphicToPresentationImage( IPresentationImage presentationImage, Color color, IEnumerable <PointF> vertices) { var image = presentationImage as IImageGraphicProvider; if (image == null) { return(null); } // Get the base image ImageGraphic baseImage = image.ImageGraphic; var segFrameImageGraphic = new SegFrameImageGraphic(baseImage.Rows, baseImage.Columns, color); segFrameImageGraphic.Alpha = Seg.DefaultOpacity; RectangleF boundingBox = RectangleUtilities.ComputeBoundingRectangle(vertices.ToArray()); // Convert vector polygon to raster on a per pixel basis baseImage.PixelData.ForEachPixel( delegate(int i, int x, int y, int pixelIndex) { var point = new PointF(x, y); if (boundingBox.Contains(point)) { if (IsInPolygon(vertices.ToArray(), point)) { segFrameImageGraphic[x, y] = true; } } } ); var overlayGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider != null) { overlayGraphicsProvider.OverlayGraphics.Add(segFrameImageGraphic); } return(segFrameImageGraphic); }
public static SegFrameImageGraphic AddSegFrameImageGraphicToPresentationImage( IPresentationImage presentationImage, Color color, IEnumerable<PointF> vertices) { var image = presentationImage as IImageGraphicProvider; if (image == null) return null; // Get the base image ImageGraphic baseImage = image.ImageGraphic; var segFrameImageGraphic = new SegFrameImageGraphic(baseImage.Rows, baseImage.Columns, color); segFrameImageGraphic.Alpha = Seg.DefaultOpacity; RectangleF boundingBox = RectangleUtilities.ComputeBoundingRectangle(vertices.ToArray()); // Convert vector polygon to raster on a per pixel basis baseImage.PixelData.ForEachPixel( delegate(int i, int x, int y, int pixelIndex) { var point = new PointF(x, y); if (boundingBox.Contains(point)) if (IsInPolygon(vertices.ToArray(), point)) { segFrameImageGraphic[x, y] = true; } } ); var overlayGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider != null) { overlayGraphicsProvider.OverlayGraphics.Add(segFrameImageGraphic); } return segFrameImageGraphic; }
internal static double CalculateStandardDeviationForStack(double mean, List <ImageCalculationInfo> imageCalculationInfoStack) { double sum = 0; int pixelCount = 0; for (int imageCount = 0; imageCount < imageCalculationInfoStack.Count; imageCount++) { PixelData pixelData = imageCalculationInfoStack[imageCount].PixelData; SegFrameImageGraphic segFrameImageGraphic = imageCalculationInfoStack[imageCount].SegFrameImageGraphic; RectangleF roiBoundingBox = imageCalculationInfoStack[imageCount].RoiBoundingBox; IModalityLut modalityLut = imageCalculationInfoStack[imageCount].ModalityLut; Rectangle boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox)); int left = boundingBox.Left; if (left < 0) { left = 0; } if (left >= segFrameImageGraphic.Columns) { left = segFrameImageGraphic.Columns - 1; } int right = boundingBox.Right; if (right < 0) { right = 0; } if (right >= segFrameImageGraphic.Columns) { right = segFrameImageGraphic.Columns - 1; } int top = boundingBox.Top; if (top < 0) { top = 0; } if (top >= segFrameImageGraphic.Rows) { top = segFrameImageGraphic.Rows - 1; } int bottom = boundingBox.Bottom; if (bottom < 0) { bottom = 0; } if (bottom >= segFrameImageGraphic.Rows) { bottom = segFrameImageGraphic.Rows - 1; } pixelData.ForEachPixel( left, top, right, bottom, delegate(int i, int x, int y, int pixelIndex) { if (segFrameImageGraphic[x, y]) { ++pixelCount; int storedValue = pixelData.GetPixel(pixelIndex); double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue; double deviation = realValue - mean; sum += deviation * deviation; } }); } if (pixelCount == 0) { return(0); } return(Math.Sqrt(sum / pixelCount)); }
internal static double CalculateMeanForStack(List <ImageCalculationInfo> imageCalculationInfoStack) { double sum = 0; int pixelCount = 0; for (int imageCount = 0; imageCount < imageCalculationInfoStack.Count; imageCount++) { PixelData pixelData = imageCalculationInfoStack[imageCount].PixelData; SegFrameImageGraphic segFrameImageGraphic = imageCalculationInfoStack[imageCount].SegFrameImageGraphic; RectangleF roiBoundingBox = imageCalculationInfoStack[imageCount].RoiBoundingBox; IModalityLut modalityLut = imageCalculationInfoStack[imageCount].ModalityLut; Rectangle boundingBox = RectangleUtilities.RoundInflate(RectangleUtilities.ConvertToPositiveRectangle(roiBoundingBox)); int left = boundingBox.Left; if (left < 0) { left = 0; } if (left >= segFrameImageGraphic.Columns) { left = segFrameImageGraphic.Columns - 1; } int right = boundingBox.Right; if (right < 0) { right = 0; } if (right >= segFrameImageGraphic.Columns) { right = segFrameImageGraphic.Columns - 1; } int top = boundingBox.Top; if (top < 0) { top = 0; } if (top >= segFrameImageGraphic.Rows) { top = segFrameImageGraphic.Rows - 1; } int bottom = boundingBox.Bottom; if (bottom < 0) { bottom = 0; } if (bottom >= segFrameImageGraphic.Rows) { bottom = segFrameImageGraphic.Rows - 1; } pixelData.ForEachPixel( left, top, right, bottom, delegate(int i, int x, int y, int pixelIndex) { //if (x >= 0 && x < segFrameImageGraphic.Columns && y >= 0 && y < segFrameImageGraphic.Rows) if (segFrameImageGraphic[x, y]) { ++pixelCount; // Make sure we run the raw pixel through the modality LUT // when doing the calculation. Note that the modality LUT // can be something other than a rescale intercept, so we can't // just run the mean through the LUT. int storedValue = pixelData.GetPixel(pixelIndex); double realValue = modalityLut != null ? modalityLut[storedValue] : storedValue; sum += realValue; } }); } if (pixelCount == 0) { return(0); } return(sum / pixelCount); }
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"); } } }
/// <summary> /// Creates a <see cref="SegFrameImageGraphic"/> and adds the graphic to the given <see cref="IPresentationImage"/> /// </summary> /// <param name="presentationImage">The image to add the graphic to</param> /// <param name="rows">Number of rows in the new graphic</param> /// <param name="columns">Number of columns in the new graphic</param> /// <param name="xLocation">X coordinate of the graphic's origin</param> /// <param name="yLocation">Y coordinate of the graphic's origin</param> /// <param name="color">Color of the new graphic</param> /// <param name="frameIndex">Image frame index</param> /// <param name="label">Graphic's label</param> /// <param name="description">Graphic's description</param> /// <param name="segPixelData">8-bit pixel data of the segmentation overlay</param> /// <param name="segmentationDocumentReference">Reference to the Segmentation document this graphic is created for</param> /// <returns></returns> public static SegFrameImageGraphic AddSegFrameImageGraphicToPresentationImage( IPresentationImage presentationImage, int rows, int columns, float xLocation, float yLocation, Color color, int frameIndex, string label, string description, byte[] segPixelData, SegmentationDocumentReference segmentationDocumentReference) { // TODO VK: use IApplicationGraphicsProvider here!!! var overlayGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider == null) return null; var segFrameImageGraphic = new SegFrameImageGraphic(rows, columns, xLocation, yLocation, color, frameIndex, -1, label, description, segPixelData, segmentationDocumentReference); segFrameImageGraphic.Alpha = Seg.DefaultOpacity; var sopProvider = presentationImage as IImageSopProvider; if (sopProvider != null) { segFrameImageGraphic.ImageSopInstanceUid = sopProvider.Sop.SopInstanceUid; segFrameImageGraphic.ImageFrameNumber = sopProvider.Frame.FrameNumber; segFrameImageGraphic.ImageNumber = sopProvider.ImageSop.InstanceNumber; } overlayGraphicsProvider.OverlayGraphics.Add(segFrameImageGraphic); return segFrameImageGraphic; }