private static VolumeSlice CreateSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, float thicknessAndSpacing, Vector3D throughPoint) { // compute Rows and Columns to reflect actual output size var frameSize = GetSliceExtent(volumeReference, slicerParams); // compute Pixel Spacing var effectiveSpacing = GetEffectiveSpacing(volumeReference); // compute Image Orientation (Patient) var matrix = new Matrix(slicerParams.SlicingPlaneRotation); matrix[3, 0] = throughPoint.X; matrix[3, 1] = throughPoint.Y; matrix[3, 2] = throughPoint.Z; var resliceAxesPatientOrientation = volumeReference.RotateToPatientOrientation(matrix); // compute Image Position (Patient) var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoint, volumeReference, slicerParams); var args = new VolumeSliceArgs(frameSize.Height, frameSize.Width, effectiveSpacing, effectiveSpacing, new Vector3D(resliceAxesPatientOrientation[0, 0], resliceAxesPatientOrientation[0, 1], resliceAxesPatientOrientation[0, 2]), new Vector3D(resliceAxesPatientOrientation[1, 0], resliceAxesPatientOrientation[1, 1], resliceAxesPatientOrientation[1, 2]), thicknessAndSpacing, Convert(slicerParams.InterpolationMode)); return(new VolumeSlice(volumeReference, true, args, topLeftOfSlicePatient, thicknessAndSpacing)); }
public MprStandardSliceSet(Volumes.Volume volume, IVolumeSlicerParams slicerParams) : base(volume) { Platform.CheckForNullReference(slicerParams, "slicerParams"); _slicerParams = slicerParams; base.Description = slicerParams.Description; this.Reslice(); }
public MprStandardSliceSet(Volume volume, IVolumeSlicerParams slicerParams) : base(volume) { Platform.CheckForNullReference(slicerParams, "slicerParams"); _slicerParams = slicerParams; base.Description = slicerParams.Description; this.Reslice(); }
internal VolumeSliceSopDataSource(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, IList <Vector3D> throughPoints) { Platform.CheckForNullReference(throughPoints, "throughPoints"); Platform.CheckTrue(throughPoints.Count > 0, "At least one through point must be specified."); var volume = volumeReference.Volume; _volumeReference = volumeReference; _slicerParams = slicerParams; _resliceMatrix = new Matrix(slicerParams.SlicingPlaneRotation); _resliceMatrix[3, 0] = throughPoints[0].X; _resliceMatrix[3, 1] = throughPoints[0].Y; _resliceMatrix[3, 2] = throughPoints[0].Z; _throughPoints = new List <Vector3D>(throughPoints).AsReadOnly(); // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management _prototypeDataSet = volume.DataSet; _instanceDataSet = new DicomAttributeCollection(); // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames. // We need to support multi-valued Slice Location in the base viewer first. // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices) // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes. // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size) // assign Rows and Columns to reflect actual output size Size frameSize = GetSliceExtent(volume, slicerParams); _instanceDataSet[DicomTags.Columns].SetInt32(0, frameSize.Width); _instanceDataSet[DicomTags.Rows].SetInt32(0, frameSize.Height); // assign Image Orientation (Patient) Matrix resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(_resliceMatrix); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(0, resliceAxesPatientOrientation[0, 0]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(1, resliceAxesPatientOrientation[0, 1]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(2, resliceAxesPatientOrientation[0, 2]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(3, resliceAxesPatientOrientation[1, 0]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(4, resliceAxesPatientOrientation[1, 1]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(5, resliceAxesPatientOrientation[1, 2]); // assign Image Position (Patient) Vector3D topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoints[0], volume, slicerParams); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(0, topLeftOfSlicePatient.X); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(1, topLeftOfSlicePatient.Y); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(2, topLeftOfSlicePatient.Z); // assign Number of Frames _instanceDataSet[DicomTags.NumberOfFrames].SetInt32(0, throughPoints.Count); // assign a new SOP instance UID _instanceDataSet[DicomTags.SopInstanceUid].SetString(0, DicomUid.GenerateUid().UID); }
public ReadOnlyVolumeSlicerParams(IVolumeSlicerParams source) { if (source.SlicingPlaneRotation != null) _slicingPlaneRotation = new Matrix(source.SlicingPlaneRotation); if (source.SliceThroughPointPatient != null) _sliceThroughPointPatient = new Vector3D(source.SliceThroughPointPatient); _description = source.Description; _interpolationMode = source.InterpolationMode; _sliceExtentXMillimeters = source.SliceExtentXMillimeters; _sliceExtentYMillimeters = source.SliceExtentYMillimeters; _sliceSpacing = source.SliceSpacing; }
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(); } } }
internal VolumeSliceSopDataSource(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, IList<Vector3D> throughPoints) { Platform.CheckForNullReference(throughPoints, "throughPoints"); Platform.CheckTrue(throughPoints.Count > 0, "At least one through point must be specified."); var volume = volumeReference.Volume; _volumeReference = volumeReference; _slicerParams = slicerParams; _resliceMatrix = new Matrix(slicerParams.SlicingPlaneRotation); _resliceMatrix[3, 0] = throughPoints[0].X; _resliceMatrix[3, 1] = throughPoints[0].Y; _resliceMatrix[3, 2] = throughPoints[0].Z; _throughPoints = new List<Vector3D>(throughPoints).AsReadOnly(); // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management _prototypeDataSet = volume.DataSet; _instanceDataSet = new DicomAttributeCollection(); // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames. // We need to support multi-valued Slice Location in the base viewer first. // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices) // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes. // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size) // assign Rows and Columns to reflect actual output size Size frameSize = GetSliceExtent(volume, slicerParams); _instanceDataSet[DicomTags.Columns].SetInt32(0, frameSize.Width); _instanceDataSet[DicomTags.Rows].SetInt32(0, frameSize.Height); // assign Image Orientation (Patient) Matrix resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(_resliceMatrix); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(0, resliceAxesPatientOrientation[0, 0]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(1, resliceAxesPatientOrientation[0, 1]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(2, resliceAxesPatientOrientation[0, 2]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(3, resliceAxesPatientOrientation[1, 0]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(4, resliceAxesPatientOrientation[1, 1]); _instanceDataSet[DicomTags.ImageOrientationPatient].SetFloat32(5, resliceAxesPatientOrientation[1, 2]); // assign Image Position (Patient) Vector3D topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoints[0], volume, slicerParams); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(0, topLeftOfSlicePatient.X); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(1, topLeftOfSlicePatient.Y); _instanceDataSet[DicomTags.ImagePositionPatient].SetFloat32(2, topLeftOfSlicePatient.Z); // assign Number of Frames _instanceDataSet[DicomTags.NumberOfFrames].SetInt32(0, throughPoints.Count); // assign a new SOP instance UID _instanceDataSet[DicomTags.SopInstanceUid].SetString(0, DicomUid.GenerateUid().UID); }
internal VolumeSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, Vector3D throughPoint) { Platform.CheckForNullReference(throughPoint, "throughPoint"); var volume = volumeReference.Volume; _volumeReference = volumeReference; _slicerParams = slicerParams; _throughPoint = throughPoint; // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management _prototypeDataSet = volume.DataSet; // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames. // We need to support multi-valued Slice Location in the base viewer first. // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices) // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes. // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size) // compute Rows and Columns to reflect actual output size var frameSize = GetSliceExtent(volume, slicerParams); Colums = frameSize.Width; Rows = frameSize.Height; // compute Image Orientation (Patient) var matrix = new Matrix(slicerParams.SlicingPlaneRotation); matrix[3, 0] = _throughPoint.X; matrix[3, 1] = _throughPoint.Y; matrix[3, 2] = _throughPoint.Z; var resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(matrix); var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient); orientation.SetFloat32(0, resliceAxesPatientOrientation[0, 0]); orientation.SetFloat32(1, resliceAxesPatientOrientation[0, 1]); orientation.SetFloat32(2, resliceAxesPatientOrientation[0, 2]); orientation.SetFloat32(3, resliceAxesPatientOrientation[1, 0]); orientation.SetFloat32(4, resliceAxesPatientOrientation[1, 1]); orientation.SetFloat32(5, resliceAxesPatientOrientation[1, 2]); ImageOrientationPatient = orientation.ToString(); // compute Image Position (Patient) var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, _throughPoint, volume, slicerParams); var position = new DicomAttributeDS(DicomTags.ImagePositionPatient); position.SetFloat32(0, topLeftOfSlicePatient.X); position.SetFloat32(1, topLeftOfSlicePatient.Y); position.SetFloat32(2, topLeftOfSlicePatient.Z); ImagePositionPatient = position.ToString(); }
public MprDisplaySetMemento(MprDisplaySet mprDisplaySet, object displaySetMemento) { if (mprDisplaySet.ImageBox != null) { this.SliceIndex = mprDisplaySet.ImageBox.TopLeftPresentationImageIndex; } if (mprDisplaySet.SliceSet is IMprStandardSliceSet) { this.SlicerParams = ((IMprStandardSliceSet)mprDisplaySet.SliceSet).SlicerParams; } this.DisplaySetMemento = displaySetMemento; }
public ReadOnlyVolumeSlicerParams(IVolumeSlicerParams source) { if (source.SlicingPlaneRotation != null) { _slicingPlaneRotation = new Matrix(source.SlicingPlaneRotation); } if (source.SliceThroughPointPatient != null) { _sliceThroughPointPatient = new Vector3D(source.SliceThroughPointPatient); } _description = source.Description; _interpolationMode = source.InterpolationMode; _sliceExtentXMillimeters = source.SliceExtentXMillimeters; _sliceExtentYMillimeters = source.SliceExtentYMillimeters; _sliceSpacing = source.SliceSpacing; }
protected void Dispose(bool disposing) { if (!disposing) { return; } if (_volumeReference != null) { _volumeReference.Dispose(); _volumeReference = null; } _prototypeDataSet = null; _slicerParams = null; _throughPoint = null; }
// Derived frome either a specified extent in millimeters or from the volume dimensions (default) private static Size GetSliceExtent(Volume volume, IVolumeSlicerParams slicerParams) { int rows, columns; float effectiveSpacing = GetEffectiveSpacing(volume); float longOutputDimension = volume.LongAxisMagnitude / effectiveSpacing; float shortOutputDimenstion = volume.ShortAxisMagnitude / effectiveSpacing; rows = columns = (int)Math.Sqrt(longOutputDimension * longOutputDimension + shortOutputDimenstion * shortOutputDimenstion); if (slicerParams.SliceExtentXMillimeters != 0f) { columns = (int)(slicerParams.SliceExtentXMillimeters / effectiveSpacing + 0.5f); } if (slicerParams.SliceExtentYMillimeters != 0f) { rows = (int)(slicerParams.SliceExtentYMillimeters / effectiveSpacing + 0.5f); } return(new Size(columns, rows)); }
// Derived from either a specified extent in millimeters or from the volume dimensions (default) private static Size GetSliceExtent(IVolumeHeader volume, IVolumeSlicerParams slicerParams) { var effectiveSpacing = GetEffectiveSpacing(volume); var longOutputDimension = volume.GetLongAxisMagnitude() / effectiveSpacing; var shortOutputDimenstion = volume.GetShortAxisMagnitude() / effectiveSpacing; var diagonalDimension = (int)Math.Sqrt(longOutputDimension * longOutputDimension + shortOutputDimenstion * shortOutputDimenstion); var columns = diagonalDimension; if (!FloatComparer.AreEqual(slicerParams.SliceExtentXMillimeters, 0f)) { columns = (int)(slicerParams.SliceExtentXMillimeters / effectiveSpacing + 0.5f); } var rows = diagonalDimension; if (!FloatComparer.AreEqual(slicerParams.SliceExtentYMillimeters, 0f)) { rows = (int)(slicerParams.SliceExtentYMillimeters / effectiveSpacing + 0.5f); } return(new Size(columns, rows)); }
public void TestShells() { IVolumeSlicerParams[] slicerParams = new IVolumeSlicerParams[] {new VolumeSlicerParams(32, -62, 69)}; TestVolume(true, VolumeFunction.Shells, slicerParams, ""); TestVolume(false, VolumeFunction.Shells, slicerParams, ""); }
public VolumeSlicer(Volumes.Volume volume, IVolumeSlicerParams slicerParams) { _volume = volume.CreateReference(); _slicerParams = slicerParams; }
public VolumeSlice(Volume volume, IVolumeSlicerParams slicerParams, Vector3D throughPoint) : this(volume.CreateTransientReference(), slicerParams, throughPoint) {}
// Derived from either a specified extent in millimeters or from the volume dimensions (default) private static Size GetSliceExtent(Volume volume, IVolumeSlicerParams slicerParams) { var effectiveSpacing = GetEffectiveSpacing(volume); var longOutputDimension = volume.LongAxisMagnitude/effectiveSpacing; var shortOutputDimenstion = volume.ShortAxisMagnitude/effectiveSpacing; var diagonalDimension = (int) Math.Sqrt(longOutputDimension*longOutputDimension + shortOutputDimenstion*shortOutputDimenstion); var columns = diagonalDimension; if (!FloatComparer.AreEqual(slicerParams.SliceExtentXMillimeters, 0f)) columns = (int) (slicerParams.SliceExtentXMillimeters/effectiveSpacing + 0.5f); var rows = diagonalDimension; if (!FloatComparer.AreEqual(slicerParams.SliceExtentYMillimeters, 0f)) rows = (int) (slicerParams.SliceExtentYMillimeters/effectiveSpacing + 0.5f); return new Size(columns, rows); }
public VolumeSlicer(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams) { _volume = volumeReference.Clone(); _slicerParams = slicerParams; }
public void TestStripes() { IVolumeSlicerParams[] slicerParams = new IVolumeSlicerParams[] { new VolumeSlicerParams(32, -62, 69) }; TestVolume(true, VolumeFunction.Stripes, slicerParams, "", ImageKernelFunction3X3, VolumeKernelFunction3X3X3); TestVolume(false, VolumeFunction.Stripes, slicerParams, "", ImageKernelFunction3X3, VolumeKernelFunction3X3X3); }
public VolumeSlicer(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, string seriesInstanceUid) { _volume = volumeReference.Clone(); _slicerParams = slicerParams; _seriesInstanceUid = seriesInstanceUid; }
public void TestStripes() { IVolumeSlicerParams[] slicerParams = new IVolumeSlicerParams[] {new VolumeSlicerParams(32, -62, 69)}; TestVolume(true, VolumeFunction.Stripes, slicerParams, "", ImageKernelFunction3X3, VolumeKernelFunction3X3X3); TestVolume(false, VolumeFunction.Stripes, slicerParams, "", ImageKernelFunction3X3, VolumeKernelFunction3X3X3); }
public VolumeSlice(Volume volume, IVolumeSlicerParams slicerParams, Vector3D throughPoint) : this(volume.CreateTransientReference(), slicerParams, throughPoint) { }
public VolumeSliceSopDataSource(Volume volume, IVolumeSlicerParams slicerParams, IList <Vector3D> throughPoints) : this(volume.CreateTransientReference(), slicerParams, throughPoints) { }
//TODO (cr Oct 2009): pass in a Slice, generated by slicer, then can just call GetPixelData() on the slice. public VolumeSliceSopDataSource(Volume volume, IVolumeSlicerParams slicerParams, Vector3D throughPoint) : this(volume, slicerParams, new[] { throughPoint }) { }
public void TestShells() { IVolumeSlicerParams[] slicerParams = new IVolumeSlicerParams[] { new VolumeSlicerParams(32, -62, 69) }; TestVolume(true, VolumeFunction.Shells, slicerParams, ""); TestVolume(false, VolumeFunction.Shells, slicerParams, ""); }
public MprDisplaySetMemento(MprDisplaySet mprDisplaySet, object displaySetMemento) { if (mprDisplaySet.ImageBox != null) this.SliceIndex = mprDisplaySet.ImageBox.TopLeftPresentationImageIndex; if (mprDisplaySet.SliceSet is IMprStandardSliceSet) this.SlicerParams = ((IMprStandardSliceSet) mprDisplaySet.SliceSet).SlicerParams; this.DisplaySetMemento = displaySetMemento; }
public VolumeSlicer(Volume vol, IVolumeSlicerParams slicerParams, string seriesInstanceUid) { _volume = vol.CreateTransientReference(); _slicerParams = slicerParams; _seriesInstanceUid = seriesInstanceUid; }
// Derived frome either a specified extent in millimeters or from the volume dimensions (default) private static Size GetSliceExtent(Volume volume, IVolumeSlicerParams slicerParams) { int rows, columns; float effectiveSpacing = GetEffectiveSpacing(volume); float longOutputDimension = volume.LongAxisMagnitude/effectiveSpacing; float shortOutputDimenstion = volume.ShortAxisMagnitude/effectiveSpacing; rows = columns = (int) Math.Sqrt(longOutputDimension*longOutputDimension + shortOutputDimenstion*shortOutputDimenstion); if (slicerParams.SliceExtentXMillimeters != 0f) columns = (int) (slicerParams.SliceExtentXMillimeters/effectiveSpacing + 0.5f); if (slicerParams.SliceExtentYMillimeters != 0f) rows = (int) (slicerParams.SliceExtentYMillimeters/effectiveSpacing + 0.5f); return new Size(columns, rows); }
public VolumeSlicer(Volume volume, IVolumeSlicerParams slicerParams) { _volume = volume.CreateTransientReference(); _slicerParams = slicerParams; }
protected static void ValidateVolumeSlicePoints(Volumes.Volume volume, IVolumeSlicerParams slicerParams, IList<KnownSample> expectedPoints) { ValidateVolumeSlicePoints(volume, slicerParams, expectedPoints, 0, 0, false); }
private static VolumeSlice CreateSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, float thicknessAndSpacing, Vector3D throughPoint) { // compute Rows and Columns to reflect actual output size var frameSize = GetSliceExtent(volumeReference, slicerParams); // compute Pixel Spacing var effectiveSpacing = GetEffectiveSpacing(volumeReference); // compute Image Orientation (Patient) var matrix = new Matrix(slicerParams.SlicingPlaneRotation); matrix[3, 0] = throughPoint.X; matrix[3, 1] = throughPoint.Y; matrix[3, 2] = throughPoint.Z; var resliceAxesPatientOrientation = volumeReference.RotateToPatientOrientation(matrix); // compute Image Position (Patient) var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, throughPoint, volumeReference, slicerParams); var args = new VolumeSliceArgs(frameSize.Height, frameSize.Width, effectiveSpacing, effectiveSpacing, new Vector3D(resliceAxesPatientOrientation[0, 0], resliceAxesPatientOrientation[0, 1], resliceAxesPatientOrientation[0, 2]), new Vector3D(resliceAxesPatientOrientation[1, 0], resliceAxesPatientOrientation[1, 1], resliceAxesPatientOrientation[1, 2]), thicknessAndSpacing, Convert(slicerParams.InterpolationMode)); return new VolumeSlice(volumeReference, true, args, topLeftOfSlicePatient, thicknessAndSpacing); }
protected static void ValidateVolumeSlicePoints(Volumes.Volume volume, IVolumeSlicerParams slicerParams, IList <KnownSample> expectedPoints) { ValidateVolumeSlicePoints(volume, slicerParams, expectedPoints, 0, 0, false); }
// VTK treats the reslice point as the center of the output image. Given the plane orientation // and size of the output image, we can derive the top left of the output image in patient space private static Vector3D GetTopLeftOfSlicePatient(Size frameSize, Vector3D throughPoint, IVolumeHeader volume, IVolumeSlicerParams slicerParams) { // This is the center of the output image var centerImageCoord = new PointF(frameSize.Width / 2f, frameSize.Height / 2f); // These offsets define the x and y vector magnitudes to arrive at our point var effectiveSpacing = GetEffectiveSpacing(volume); var offsetX = centerImageCoord.X * effectiveSpacing; var offsetY = centerImageCoord.Y * effectiveSpacing; // To determine top left of slice in volume, subtract offset vectors along x and y // // Our reslice plane x and y vectors var resliceAxes = slicerParams.SlicingPlaneRotation; var xVec = new Vector3D(resliceAxes[0, 0], resliceAxes[0, 1], resliceAxes[0, 2]); var yVec = new Vector3D(resliceAxes[1, 0], resliceAxes[1, 1], resliceAxes[1, 2]); // Offset along x and y from reslicePoint var topLeftOfSliceVolume = throughPoint - (offsetX * xVec + offsetY * yVec); // Convert volume point to patient space return(volume.ConvertToPatient(topLeftOfSliceVolume)); }
//TODO (cr Oct 2009): can be factored out into Slice class. // VTK treats the reslice point as the center of the output image. Given the plane orientation // and size of the output image, we can derive the top left of the output image in patient space private static Vector3D GetTopLeftOfSlicePatient(Size frameSize, Vector3D throughPoint, Volume volume, IVolumeSlicerParams slicerParams) { // This is the center of the output image PointF centerImageCoord = new PointF(frameSize.Width/2f, frameSize.Height/2f); // These offsets define the x and y vector magnitudes to arrive at our point float effectiveSpacing = GetEffectiveSpacing(volume); float offsetX = centerImageCoord.X*effectiveSpacing; float offsetY = centerImageCoord.Y*effectiveSpacing; // To determine top left of slice in volume, subtract offset vectors along x and y // // Our reslice place x and y vectors Matrix resliceAxes = slicerParams.SlicingPlaneRotation; Vector3D xVec = new Vector3D(resliceAxes[0, 0], resliceAxes[0, 1], resliceAxes[0, 2]); Vector3D yVec = new Vector3D(resliceAxes[1, 0], resliceAxes[1, 1], resliceAxes[1, 2]); // Offset along x and y from reslicePoint Vector3D topLeftOfSliceVolume = throughPoint - (offsetX*xVec + offsetY*yVec); // Convert volume point to patient space return volume.ConvertToPatient(topLeftOfSliceVolume); }
protected void Dispose(bool disposing) { if (!disposing) return; if (_volumeReference != null) { _volumeReference.Dispose(); _volumeReference = null; } _prototypeDataSet = null; _slicerParams = null; _throughPoint = null; }
//TODO (cr Oct 2009): pass in a Slice, generated by slicer, then can just call GetPixelData() on the slice. public VolumeSliceSopDataSource(Volume volume, IVolumeSlicerParams slicerParams, Vector3D throughPoint) : this(volume, slicerParams, new Vector3D[] {throughPoint}) {}
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(); } } }
public VolumeSliceSopDataSource(Volume volume, IVolumeSlicerParams slicerParams, IList<Vector3D> throughPoints) : this(volume.CreateTransientReference(), slicerParams, throughPoints) {}