Beispiel #1
0
        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();
                }
            }
        }
            /// <summary>
            /// Sets this line segment's end points to be the intersection of the <paramref name="sliceImage"/> on the infinite plane of the <paramref name="referenceImage"/>.
            /// </summary>
            /// <remarks>
            /// In practice, a call to this method should have <paramref name="referenceImage"/> being equal to this line's <see cref="Graphic.ParentPresentationImage"/> or,
            /// if not, then followed by a call to <see cref="ResliceToolGroup.TranslocateGraphic">translocate</see> the line to the <paramref name="referenceImage"/>.
            /// Any other use may constitute a defect involving reference line bounds, and you should thusly inspect your code and explain why this is the case.
            /// </remarks>
            /// <param name="sliceImage">The slice whose position is controlled by this line.</param>
            /// <param name="referenceImage">The image on which the line is (or is to be) defined.</param>
            /// <returns>Returns true if a solution exists and the end points were updated.</returns>
            public bool SetLine(IPresentationImage sliceImage, IPresentationImage referenceImage)
            {
                DicomImagePlane sliceImagePlane     = DicomImagePlane.FromImage(sliceImage);
                DicomImagePlane referenceImagePlane = DicomImagePlane.FromImage(referenceImage);

                if (!sliceImagePlane.IsParallelTo(referenceImagePlane, 1f))
                {
                    Vector3D imagePt1 = referenceImagePlane.ConvertToImagePlane(sliceImagePlane.PositionPatientTopLeft);
                    Vector3D imagePt2 = referenceImagePlane.ConvertToImagePlane(sliceImagePlane.PositionPatientTopRight);

                    this.Points.SuspendEvents();
                    this.Points.Clear();
                    this.Points.Add(referenceImagePlane.ConvertToImage(new PointF(imagePt1.X, imagePt1.Y)));
                    this.Points.Add(referenceImagePlane.ConvertToImage(new PointF(imagePt2.X, imagePt2.Y)));
                    this.Points.ResumeEvents();
                    return(true);
                }
                return(false);
            }
Beispiel #3
0
        private void Probe(Point destinationPoint)
        {
            Point sourcePointRounded = Point.Truncate(_selectedImageGraphic.SpatialTransform.ConvertToSource(destinationPoint));

            bool showPixelValue    = true;
            bool showModalityValue = true;
            bool showVoiValue      = true;

            string probeString       = String.Format(SR.FormatLocation, SR.LabelNotApplicable, SR.LabelNotApplicable, SR.LabelNotApplicable);
            string pixelValueString  = String.Format(SR.FormatPixelValue, SR.LabelNotApplicable);
            string modalityLutString = String.Format(SR.FormatModalityLutValue, SR.LabelNotApplicable);
            string voiLutString      = String.Format(SR.FormatVoiLutValue, SR.LabelNotApplicable);

            try
            {
                DicomImagePlane dip = DicomImagePlane.FromImage(this.SelectedPresentationImage);
                if (_selectedImageGraphic.HitTest(destinationPoint))
                {
                    Vector3D voxelCoordinate = dip.ConvertToPatient(new PointF(sourcePointRounded.X, sourcePointRounded.Y));
                    probeString = String.Format(SR.FormatLocation, voxelCoordinate.X, voxelCoordinate.Y, voxelCoordinate.Z);

                    if (_selectedImageGraphic is GrayscaleImageGraphic)
                    {
                        GrayscaleImageGraphic image = _selectedImageGraphic as GrayscaleImageGraphic;

                        int    pixelValue       = 0;
                        double modalityLutValue = 0;
                        double voiLutValue      = 0;

                        GetPixelValue(image, sourcePointRounded, ref pixelValue, ref pixelValueString);
                        GetModalityLutValue(image, pixelValue, ref modalityLutValue, ref modalityLutString);
                        GetVoiLutValue(image, modalityLutValue, ref voiLutValue, ref voiLutString);
                    }
                    else if (_selectedImageGraphic is ColorImageGraphic)
                    {
                        showModalityValue = false;
                        showVoiValue      = false;

                        ColorImageGraphic image        = _selectedImageGraphic as ColorImageGraphic;
                        Color             color        = image.PixelData.GetPixelAsColor(sourcePointRounded.X, sourcePointRounded.Y);
                        string            rgbFormatted = String.Format(SR.FormatRgb, color.R, color.G, color.B);
                        pixelValueString = String.Format(SR.FormatPixelValue, rgbFormatted);
                    }
                    else
                    {
                        showPixelValue    = false;
                        showModalityValue = false;
                        showVoiValue      = false;
                    }
                }

                if (showPixelValue)
                {
                    probeString += "\n" + pixelValueString;
                }
                if (showModalityValue)
                {
                    probeString += "\n" + modalityLutString;
                }
                if (showVoiValue)
                {
                    probeString += "\n" + voiLutString;
                }
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e);
                probeString = SR.MessageProbeToolError;
            }

            _selectedTile.InformationBox.Update(probeString, destinationPoint);
        }
        private static void TestVolume(bool signed, VolumeFunction f, IEnumerable <IVolumeSlicerParams> slicerParams, string testName, ImageKernelFunction imageKernel, VolumeKernelFunction volumeKernel)
        {
            const int      FULL_SCALE         = 65535;
            VolumeFunction normalizedFunction = f.Normalize(100);

            using (Volumes.Volume volume = normalizedFunction.CreateVolume(100, signed))
            {
                float offset = signed ? -32768 : 0;
                foreach (IVolumeSlicerParams slicing in slicerParams)
                {
                    List <double> list = new List <double>();
                    using (VolumeSlicer slicer = new VolumeSlicer(volume, slicing))
                    {
                        foreach (ISopDataSource slice in slicer.CreateSliceSops())
                        {
                            using (ImageSop imageSop = new ImageSop(slice))
                            {
                                // assert tags inserted by slicer
                                AssertAreEqual("WSD", imageSop.DataSource, DicomTags.ConversionType);
                                AssertAreEqual("ClearCanvas Inc.", imageSop.DataSource, DicomTags.SecondaryCaptureDeviceManufacturer);
                                AssertAreEqual(@"DERIVED\SECONDARY", imageSop.DataSource, DicomTags.ImageType);
                                AssertAreEqual("Multiplanar Reformatting", imageSop.DataSource, DicomTags.DerivationDescription);

                                foreach (IPresentationImage image in PresentationImageFactory.Create(imageSop))
                                {
                                    IImageSopProvider     imageSopProvider     = (IImageSopProvider)image;
                                    IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image;
                                    DicomImagePlane       dip = DicomImagePlane.FromImage(image);

                                    for (int y = 1; y < imageSopProvider.Frame.Rows - 1; y++)
                                    {
                                        for (int x = 1; x < imageSopProvider.Frame.Columns - 1; x++)
                                        {
                                            // pixels on the extreme sides of the volume tend to have more interpolation error due to MPR padding values
                                            Vector3D vector = dip.ConvertToPatient(new PointF(x, y));                                             // +new Vector3D(-0.5f, -0.5f, 0);
                                            if (Between(vector.X, 1, 98) && Between(vector.Y, 1, 98) && Between(vector.Z, 1, 98))
                                            {
                                                float expected = volumeKernel.Invoke(normalizedFunction, vector.X, vector.Y, vector.Z) + offset;
                                                float actual   = imageKernel.Invoke(imageGraphicProvider.ImageGraphic.PixelData, x, y);
                                                list.Add(Math.Abs(expected - actual));
                                            }
                                        }
                                    }

                                    image.Dispose();
                                }
                            }
                            slice.Dispose();
                        }
                    }

                    Statistics stats = new Statistics(list);
                    Trace.WriteLine(string.Format("Testing {0}", testName));
                    Trace.WriteLine(string.Format("\tFunction/Slicing: {0} / {1}", normalizedFunction.Name, slicing.Description));
                    Trace.WriteLine(string.Format("\t       Pixel Rep: {0}", signed ? "signed" : "unsigned"));
                    Trace.WriteLine(string.Format("\t Voxels Compared: {0}", list.Count));
                    Trace.WriteLine(string.Format("\t      Mean Delta: {0:f2} ({1:p2} of full scale)", stats.Mean, stats.Mean / FULL_SCALE));
                    Trace.WriteLine(string.Format("\t    StdDev Delta: {0:f2} ({1:p2} of full scale)", stats.StandardDeviation, stats.StandardDeviation / FULL_SCALE));
                    Assert.Less(stats.Mean, FULL_SCALE * 0.05, "Mean delta exceeds 5% of full scale ({0})", FULL_SCALE);
                    Assert.Less(stats.StandardDeviation, FULL_SCALE * 0.05, "StdDev delta exceeds 5% of full scale ({0})", FULL_SCALE);
                }
            }
        }