/// <summary>
        /// Creates a radiotherapy structure from a set of contours, including the given rendering
        /// information (name of the contour, color to render in).
        /// </summary>
        /// <param name="contours">The contours and their rendering information.</param>
        /// <param name="dicomIdentifiers">The Dicom identifiers for the scan to which the contours belong.</param>
        /// <param name="volumeTransform">The Dicom-to-data transformation of the scan to which the contours belong.</param>
        /// <returns></returns>
        public static RadiotherapyStruct ContoursToRadiotherapyStruct(IEnumerable <ContourRenderingInformation> contours,
                                                                      IReadOnlyList <DicomIdentifiers> dicomIdentifiers,
                                                                      VolumeTransform volumeTransform)
        {
            var radiotherapyStruct = RadiotherapyStruct.CreateDefault(dicomIdentifiers);

            int roiNumber     = 0;
            var nameConverter = new DicomPersonNameConverter("InnerEye", "CreateDataset", string.Empty, string.Empty, string.Empty);

            foreach (var contour in contours)
            {
                // ROIs need to start at 1 by DICOM spec
                roiNumber++;
                // Create contours - mapping each contour into the volume.
                var radiotherapyContour = RTStructCreator.CreateRadiotherapyContour(
                    contour.Contour,
                    dicomIdentifiers,
                    volumeTransform,
                    contour.Name,
                    (contour.Color.R, contour.Color.G, contour.Color.B),
                    roiNumber.ToString(),
                    nameConverter,
                    ROIInterpretedType.None
                    );
                radiotherapyStruct.Contours.Add(radiotherapyContour);
            }
            return(radiotherapyStruct);
        }
        /// <summary>
        /// Creates a single Dicom file that contains a radiotherapy structure,
        /// derived from a set of contours and rendering information.
        /// </summary>
        /// <param name="contours">The contours and their rendering information.</param>
        /// <param name="dicomIdentifiers">The Dicom identifiers for the scan to which the contours belong.</param>
        /// <param name="volumeTransform">The Dicom-to-data transformation of the scan to which the contours belong.</param>
        /// <returns></returns>
        public static DicomFileAndPath ContoursToDicomRtFile(IEnumerable <ContourRenderingInformation> contours,
                                                             IReadOnlyList <DicomIdentifiers> dicomIdentifiers,
                                                             VolumeTransform volumeTransform)
        {
            var radiotherapyStruct = ContoursToRadiotherapyStruct(contours, dicomIdentifiers, volumeTransform);

            return(new DicomFileAndPath(RtStructWriter.GetRtStructFile(radiotherapyStruct), "RTStruct.dcm"));
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates a new RadiotherapyContour for inclusion in a RadiotherapyStruct ready for serialization
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="axialContours">The contours relative to the given volume you wish to map into the DICOM reference coordinate system</param>
 /// <param name="identifiers"> The DICOM identifiers describing the origin of the volume</param>
 /// <param name="volumeTransform">The volume transform.</param>
 /// <param name="name">The DICOM structure name</param>
 /// <param name="color">The color of this structure</param>
 /// <param name="roiNumber">The roiNumber of this structure</param>
 /// <returns></returns>
 public static RadiotherapyContour CreateRadiotherapyContour(
     ContoursPerSlice axialContours,
     IReadOnlyList <DicomIdentifiers> identifiers,
     VolumeTransform volumeTransform,
     string name,
     (byte R, byte G, byte B) color,
Ejemplo n.º 4
0
        /// <summary>
        /// Converts a set of application contours into DICOM RT objects ready for serialization
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="axialContours">The axial contours you wish to convert</param>
        /// <param name="identifiers">The set of identifiers, 1 for each slice in parentVolume</param>
        /// <param name="volumeTransform">The volume transform.</param>
        /// <returns></returns>
        public static List <DicomRTContourItem> ToDicomRtContours(
            this Microsoft.RTConvert.Contours.ContoursPerSlice axialContours, IReadOnlyList <DicomIdentifiers> identifiers, VolumeTransform volumeTransform)
        {
            if (identifiers == null || identifiers.Count == 0)
            {
                throw new ArgumentException(nameof(identifiers), "The identifiers cannot be null or empty");
            }

            if (volumeTransform == null)
            {
                throw new ArgumentException(nameof(volumeTransform), "The volume cannot be null or empty");
            }

            var resultList = new List <DicomRTContourItem>();

            var tolerance = volumeTransform.SpacingZ / 2;

            // Iterate through the sets of contours per slice
            foreach (var tuple in axialContours)
            {
                // For this slice, compute the z-axis coordinate in the DICOM reference coordinate system
                var z = tuple.Key;
                var zAxisPhysicalCoordinate = (volumeTransform.DataToDicom * new Point3D(0, 0, z)).Z;

                // Locate the DICOM identifier containing this slice. Note that for non-axial volumes this is not the right test
                // but is sufficient for Axial volumes.
                var identifier = identifiers.FirstOrDefault(x => Math.Abs(x.Image.ImagePositionPatient.Z - zAxisPhysicalCoordinate) < tolerance);

                if (identifier == null)
                {
                    throw new Exception("Invalid contour or image identifiers");
                }

                // Reference the slice containing these contours by SopInstance UID
                var sopCommonInstance = identifier.Image.SopCommon;
                var contourImageSeq   = new List <DicomRTContourImageItem>()
                {
                    new DicomRTContourImageItem(sopCommonInstance.SopClassUid, sopCommonInstance.SopInstanceUid)
                };

                // Iterate through the contour objects on this slice.
                foreach (var contour in tuple.Value)
                {
                    // Convert the pixel based contour into the DICOM reference coordinate system and flatten to an arry of doubles.
                    var allpoints = contour.ContourPoints.SelectMany(
                        p => (volumeTransform.DataToDicom * new Point3D(p.X, p.Y, z)).Data).ToArray();

                    resultList.Add(new DicomRTContourItem(
                                       allpoints,
                                       contour.Length,
                                       ClosedPlanarString,
                                       contourImageSeq));
                }
            }

            return(resultList);
        }