public void Execute() { this.OnBeforeExecute(); List <ImageSop> images = new List <ImageSop>(); try { VolumeFunction function = _function.Normalize(100); foreach (ISopDataSource sopDataSource in function.CreateSops(100, 100, 100, false)) { this.InitializeSopDataSource(sopDataSource); images.Add(new ImageSop(sopDataSource)); } MprViewerComponent component = new MprViewerComponent(Volumes.Volume.Create(EnumerateFrames(images))); component.Layout(); LaunchImageViewerArgs args = new LaunchImageViewerArgs(WindowBehaviour.Auto); args.Title = component.Title; MprViewerComponent.Launch(component, args); } catch (Exception ex) { ExceptionHandler.Report(ex, Application.ActiveDesktopWindow); } finally { DisposeAll(images); } this.OnAfterExecute(); }
/// <summary> /// Creates a 100x100x100 volume using the specified volume function using 100 frames of dimensions 100x100. /// </summary> /// <param name="function">The function with which to generate frame data - 0-99 in each dimension.</param> /// <param name="initializer">A delegate to initialize additional SOP attributes for each of the 100 frames.</param> /// <param name="testMethod">A test routine with which to exercise the volume. The volume is disposed automatically afterwards.</param> protected static void TestVolume(VolumeFunction function, InitializeSopDataSourceDelegate initializer, TestVolumeDelegate testMethod) { function = function.Normalize(100); List <ImageSop> images = new List <ImageSop>(); try { foreach (ISopDataSource sopDataSource in function.CreateSops(100, 100, 100, false)) { if (initializer != null) { initializer.Invoke(sopDataSource); } images.Add(new ImageSop(sopDataSource)); } using (Volume volume = Volume.Create(EnumerateFrames(images))) { if (testMethod != null) { testMethod.Invoke(volume); } } } catch (Exception ex) { Trace.WriteLine(string.Format("Thrown: {0}", ex.GetType().Name)); throw; } finally { DisposeAll(images); } }
private static void TestVolume(bool signed, VolumeFunction f, IEnumerable<IVolumeSlicerParams> slicerParams, string testName, ImageKernelFunction imageKernel, VolumeKernelFunction volumeKernel) { const int FULL_SCALE = 65535; VolumeFunction normalizedFunction = f.Normalize(100); using (Volume volume = normalizedFunction.CreateVolume(100, signed)) { float offset = signed ? -32768 : 0; foreach (IVolumeSlicerParams slicing in slicerParams) { List<double> list = new List<double>(); using (VolumeSlicer slicer = new VolumeSlicer(volume, slicing, DicomUid.GenerateUid().UID)) { foreach (ISopDataSource slice in slicer.CreateSlices()) { using (ImageSop imageSop = new ImageSop(slice)) { foreach (IPresentationImage image in PresentationImageFactory.Create(imageSop)) { IImageSopProvider imageSopProvider = (IImageSopProvider) image; IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider) image; DicomImagePlane dip = DicomImagePlane.FromImage(image); for (int y = 1; y < imageSopProvider.Frame.Rows - 1; y++) { for (int x = 1; x < imageSopProvider.Frame.Columns - 1; x++) { // pixels on the extreme sides of the volume tend to have more interpolation error due to MPR padding values Vector3D vector = dip.ConvertToPatient(new PointF(x, y)); // +new Vector3D(-0.5f, -0.5f, 0); if (Between(vector.X, 1, 98) && Between(vector.Y, 1, 98) && Between(vector.Z, 1, 98)) { float expected = volumeKernel.Invoke(normalizedFunction, vector.X, vector.Y, vector.Z) + offset; float actual = imageKernel.Invoke(imageGraphicProvider.ImageGraphic.PixelData, x, y); list.Add(Math.Abs(expected - actual)); } } } image.Dispose(); } } slice.Dispose(); } } Statistics stats = new Statistics(list); Trace.WriteLine(string.Format("Testing {0}", testName)); Trace.WriteLine(string.Format("\tFunction/Slicing: {0} / {1}", normalizedFunction.Name, slicing.Description)); Trace.WriteLine(string.Format("\t Pixel Rep: {0}", signed ? "signed" : "unsigned")); Trace.WriteLine(string.Format("\t Voxels Compared: {0}", list.Count)); Trace.WriteLine(string.Format("\t Mean Delta: {0:f2} ({1:p2} of full scale)", stats.Mean, stats.Mean/FULL_SCALE)); Trace.WriteLine(string.Format("\t StdDev Delta: {0:f2} ({1:p2} of full scale)", stats.StandardDeviation, stats.StandardDeviation/FULL_SCALE)); Assert.Less(stats.Mean, FULL_SCALE*0.05, "Mean delta exceeds 5% of full scale ({0})", FULL_SCALE); Assert.Less(stats.StandardDeviation, FULL_SCALE*0.05, "StdDev delta exceeds 5% of full scale ({0})", FULL_SCALE); } } }
private static void TestVolume(bool signed, VolumeFunction f, IEnumerable <IVolumeSlicerParams> slicerParams, string testName, ImageKernelFunction imageKernel, VolumeKernelFunction volumeKernel) { const int FULL_SCALE = 65535; VolumeFunction normalizedFunction = f.Normalize(100); using (Volume volume = normalizedFunction.CreateVolume(100, signed)) { float offset = signed ? -32768 : 0; foreach (IVolumeSlicerParams slicing in slicerParams) { List <double> list = new List <double>(); using (VolumeSlicer slicer = new VolumeSlicer(volume, slicing, DicomUid.GenerateUid().UID)) { foreach (ISopDataSource slice in slicer.CreateSlices()) { using (ImageSop imageSop = new ImageSop(slice)) { foreach (IPresentationImage image in PresentationImageFactory.Create(imageSop)) { IImageSopProvider imageSopProvider = (IImageSopProvider)image; IImageGraphicProvider imageGraphicProvider = (IImageGraphicProvider)image; DicomImagePlane dip = DicomImagePlane.FromImage(image); for (int y = 1; y < imageSopProvider.Frame.Rows - 1; y++) { for (int x = 1; x < imageSopProvider.Frame.Columns - 1; x++) { // pixels on the extreme sides of the volume tend to have more interpolation error due to MPR padding values Vector3D vector = dip.ConvertToPatient(new PointF(x, y)); // +new Vector3D(-0.5f, -0.5f, 0); if (Between(vector.X, 1, 98) && Between(vector.Y, 1, 98) && Between(vector.Z, 1, 98)) { float expected = volumeKernel.Invoke(normalizedFunction, vector.X, vector.Y, vector.Z) + offset; float actual = imageKernel.Invoke(imageGraphicProvider.ImageGraphic.PixelData, x, y); list.Add(Math.Abs(expected - actual)); } } } image.Dispose(); } } slice.Dispose(); } } Statistics stats = new Statistics(list); Trace.WriteLine(string.Format("Testing {0}", testName)); Trace.WriteLine(string.Format("\tFunction/Slicing: {0} / {1}", normalizedFunction.Name, slicing.Description)); Trace.WriteLine(string.Format("\t Pixel Rep: {0}", signed ? "signed" : "unsigned")); Trace.WriteLine(string.Format("\t Voxels Compared: {0}", list.Count)); Trace.WriteLine(string.Format("\t Mean Delta: {0:f2} ({1:p2} of full scale)", stats.Mean, stats.Mean / FULL_SCALE)); Trace.WriteLine(string.Format("\t StdDev Delta: {0:f2} ({1:p2} of full scale)", stats.StandardDeviation, stats.StandardDeviation / FULL_SCALE)); Assert.Less(stats.Mean, FULL_SCALE * 0.05, "Mean delta exceeds 5% of full scale ({0})", FULL_SCALE); Assert.Less(stats.StandardDeviation, FULL_SCALE * 0.05, "StdDev delta exceeds 5% of full scale ({0})", FULL_SCALE); } } }
public NormalizedVolumeFunction(int width, int height, int depth, VolumeFunction function) : base(function._name, function._function) { float rangeMin = float.MaxValue; float rangeMax = float.MinValue; for (int z = 0; z < depth; z++) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float v = function._function(x, y, z); rangeMin = Math.Min(rangeMin, v); rangeMax = Math.Max(rangeMax, v); } } } _offset = -rangeMin; _scale = 65535 / (rangeMax - rangeMin); }
public void TestInsufficientFramesSource() { // it doesn't really matter what function we use VolumeFunction function = VolumeFunction.Void.Normalize(100); List <ImageSop> images = new List <ImageSop>(); try { // create only 2 slices!! foreach (ISopDataSource sopDataSource in function.CreateSops(100, 100, 2, false)) { images.Add(new ImageSop(sopDataSource)); } // this line *should* throw an exception using (Volume volume = Volume.Create(EnumerateFrames(images))) {} } finally { DisposeAll(images); } }
private static float VolumeKernelFunction3X3X3(VolumeFunction function, float x, float y, float z) { const float side = 0.5f / 26; float weightedMean = 0; weightedMean += side * function.Evaluate(x - 1, y - 1, z - 1); weightedMean += side * function.Evaluate(x - 1, y - 1, z + 0); weightedMean += side * function.Evaluate(x - 1, y - 1, z + 1); weightedMean += side * function.Evaluate(x - 1, y + 0, z - 1); weightedMean += side * function.Evaluate(x - 1, y + 0, z + 0); weightedMean += side * function.Evaluate(x - 1, y + 0, z + 1); weightedMean += side * function.Evaluate(x - 1, y + 1, z - 1); weightedMean += side * function.Evaluate(x - 1, y + 1, z + 0); weightedMean += side * function.Evaluate(x - 1, y + 1, z + 1); weightedMean += side * function.Evaluate(x + 0, y - 1, z - 1); weightedMean += side * function.Evaluate(x + 0, y - 1, z + 0); weightedMean += side * function.Evaluate(x + 0, y - 1, z + 1); weightedMean += side * function.Evaluate(x + 0, y + 0, z - 1); weightedMean += 0.5f * function.Evaluate(x + 0, y + 0, z + 0); weightedMean += side * function.Evaluate(x + 0, y + 0, z + 1); weightedMean += side * function.Evaluate(x + 0, y + 1, z - 1); weightedMean += side * function.Evaluate(x + 0, y + 1, z + 0); weightedMean += side * function.Evaluate(x + 0, y + 1, z + 1); weightedMean += side * function.Evaluate(x + 1, y - 1, z - 1); weightedMean += side * function.Evaluate(x + 1, y - 1, z + 0); weightedMean += side * function.Evaluate(x + 1, y - 1, z + 1); weightedMean += side * function.Evaluate(x + 1, y + 0, z - 1); weightedMean += side * function.Evaluate(x + 1, y + 0, z + 0); weightedMean += side * function.Evaluate(x + 1, y + 0, z + 1); weightedMean += side * function.Evaluate(x + 1, y + 1, z - 1); weightedMean += side * function.Evaluate(x + 1, y + 1, z + 0); weightedMean += side * function.Evaluate(x + 1, y + 1, z + 1); return(weightedMean); }
private static void TestVolume(bool signed, VolumeFunction f, IEnumerable<IVolumeSlicerParams> slicerParams, string testName) { TestVolume(signed, f, slicerParams, testName, (pd, x, y) => pd.GetPixel(x, y), (fx, x, y, z) => fx.Evaluate(x, y, z)); }
private static float VolumeKernelFunction3X3X3(VolumeFunction function, float x, float y, float z) { const float side = 0.5f/26; float weightedMean = 0; weightedMean += side*function.Evaluate(x - 1, y - 1, z - 1); weightedMean += side*function.Evaluate(x - 1, y - 1, z + 0); weightedMean += side*function.Evaluate(x - 1, y - 1, z + 1); weightedMean += side*function.Evaluate(x - 1, y + 0, z - 1); weightedMean += side*function.Evaluate(x - 1, y + 0, z + 0); weightedMean += side*function.Evaluate(x - 1, y + 0, z + 1); weightedMean += side*function.Evaluate(x - 1, y + 1, z - 1); weightedMean += side*function.Evaluate(x - 1, y + 1, z + 0); weightedMean += side*function.Evaluate(x - 1, y + 1, z + 1); weightedMean += side*function.Evaluate(x + 0, y - 1, z - 1); weightedMean += side*function.Evaluate(x + 0, y - 1, z + 0); weightedMean += side*function.Evaluate(x + 0, y - 1, z + 1); weightedMean += side*function.Evaluate(x + 0, y + 0, z - 1); weightedMean += 0.5f*function.Evaluate(x + 0, y + 0, z + 0); weightedMean += side*function.Evaluate(x + 0, y + 0, z + 1); weightedMean += side*function.Evaluate(x + 0, y + 1, z - 1); weightedMean += side*function.Evaluate(x + 0, y + 1, z + 0); weightedMean += side*function.Evaluate(x + 0, y + 1, z + 1); weightedMean += side*function.Evaluate(x + 1, y - 1, z - 1); weightedMean += side*function.Evaluate(x + 1, y - 1, z + 0); weightedMean += side*function.Evaluate(x + 1, y - 1, z + 1); weightedMean += side*function.Evaluate(x + 1, y + 0, z - 1); weightedMean += side*function.Evaluate(x + 1, y + 0, z + 0); weightedMean += side*function.Evaluate(x + 1, y + 0, z + 1); weightedMean += side*function.Evaluate(x + 1, y + 1, z - 1); weightedMean += side*function.Evaluate(x + 1, y + 1, z + 0); weightedMean += side*function.Evaluate(x + 1, y + 1, z + 1); return weightedMean; }
private static void TestVolume(bool signed, VolumeFunction f, IEnumerable <IVolumeSlicerParams> slicerParams, string testName) { TestVolume(signed, f, slicerParams, testName, (pd, x, y) => pd.GetPixel(x, y), (fx, x, y, z) => fx.Evaluate(x, y, z)); }
public TestVolume(VolumeFunction function) { _function = function; }
public XAxialRotationGantryTiledTestVolume(VolumeFunction function, float tiltDegrees) : base(function) { _tiltDegrees = tiltDegrees; _dataSetOrientation = DataSetOrientation.CreateGantryTiltedAboutX(tiltDegrees); }
public NormalizedVolumeFunction(int width, int height, int depth, VolumeFunction function) : base(function._name, function._function) { float rangeMin = float.MaxValue; float rangeMax = float.MinValue; for (int z = 0; z < depth; z++) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float v = function._function(x, y, z); rangeMin = Math.Min(rangeMin, v); rangeMax = Math.Max(rangeMax, v); } } } _offset = -rangeMin; _scale = 65535/(rangeMax - rangeMin); }