示例#1
0
        public static SliceContourMeta FindZeroLevelContours(this Mat mat, Func <Vector3, Vector3> imageToPatientFunc, int z)
        {
            var zPos  = imageToPatientFunc(new Vector3(0, 0, z)).Z;
            var meta  = new SliceContourMeta();
            var child = new SliceContourMeta();
            var level = new IsodoseLevel()
            {
                Value = 0, Color = new Scalar(255)
            };

            Point[][]        ctrs;
            HierarchyIndex[] hi;
            var thresh = mat.Threshold(level.Value, 255, ThresholdTypes.Binary);

            thresh = thresh.WindowAndLevel(128, 256);
            thresh.FindContours(out ctrs, out hi, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);
            for (int i = 0; i < hi.Length; i++)
            {
                var contour = ctrs[i];
                if (hi[i].Parent == -1)
                {
                    contour.ToList().ForEach(c =>
                    {
                        var pos = imageToPatientFunc(new Vector3(c.X, c.Y, 1));
                        pos.Z   = zPos;
                        meta.AddPoint(new Point3f((float)pos.X, (float)pos.Y, (float)pos.Z));
                    });
                }
                if (hi[i].Parent != -1)
                {
                    contour.ToList().ForEach(c =>
                    {
                        var pos = imageToPatientFunc(new Vector3(c.X, c.Y, 1));
                        pos.Z   = zPos;
                        child.AddPoint(new Point3f((float)pos.X, (float)pos.Y, (float)pos.Z));
                    });
                }
            }
            if (child.ContourPoints.Any())
            {
                meta.Children.Add(child);
            }
            thresh.Dispose();
            return(meta);
        }
示例#2
0
        /// <summary>
        /// Finds contours on StructureMeta model (1 inside, -1 outsize, 0 boundry)
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public static SliceContourMeta FindStructureContour(this Matrix model, double zPos)
        {
            var contourSlice = model.GetZPlane(zPos);
            var meta         = new SliceContourMeta();
            var child        = new SliceContourMeta();

            Point[][]        ctrs;
            HierarchyIndex[] hi;
            var thresh = contourSlice.Threshold(0, 255, ThresholdTypes.Binary).WindowAndLevel(128, 255);

            //Cv2.ImShow("Threshold", thresh);
            //Cv2.WaitKey();
            thresh.FindContours(out ctrs, out hi, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
            for (int i = 0; i < hi.Length; i++)
            {
                var contour = ctrs[i];
                if (hi[i].Parent == -1)
                {
                    contour.ToList().ForEach(c =>
                    {
                        var pos = model.ImageToPatientTx(new Vector3(c.X, c.Y, 1));
                        pos.Z   = zPos;
                        meta.AddPoint(new Point3f((float)pos.X, (float)pos.Y, (float)pos.Z));
                    });
                }
                if (hi[i].Parent != -1)
                {
                    contour.ToList().ForEach(c =>
                    {
                        var pos = model.ImageToPatientTx(new Vector3(c.X, c.Y, 1));
                        pos.Z   = zPos;
                        child.AddPoint(new Point3f((float)pos.X, (float)pos.Y, (float)pos.Z));
                    });
                }
            }
            if (child.ContourPoints.Any())
            {
                meta.Children.Add(child);
            }
            contourSlice.Dispose();
            thresh.Dispose();
            return(meta);
        }
示例#3
0
        public static StructureSetMeta ParseDICOM(string file)
        {
            var sm  = new StructureSetMeta();
            var dcm = DICOMObject.Read(file);
            var sel = dcm.GetSelector();

            var metas = sel.StructureSetROISequence.Items.Select(i =>
            {
                var meta         = new StructureMeta();
                meta.StructureId = i.GetSelector().ROIName?.Data;
                meta.ROINumber   = i.GetSelector().ROINumber.Data;
                return(meta);
            });

            foreach (var meta in metas)
            {
                try
                {
                    var comatch = sel.ROIContourSequence.Items.FirstOrDefault(i => i.GetSelector().ReferencedROINumber.Data == meta.ROINumber);
                    var romatch = sel.RTROIObservationsSequence.Items.FirstOrDefault(i => i.GetSelector().ReferencedROINumber.Data == meta.ROINumber);

                    var colorValues = comatch.GetSelector().ROIDisplayColor.Data_;
                    var color       = new Vec3b((byte)colorValues[0], (byte)colorValues[1], (byte)colorValues[2]);
                    var dicomType   = romatch.GetSelector().RTROIInterpretedType.Data;
                    var name        = romatch.GetSelector().ROIObservationLabel.Data;
                    meta.StructureName = name;
                    meta.Color         = new Scalar(colorValues[0], colorValues[1], colorValues[2]);

                    var hasContours = comatch.GetSelector().ContourSequence != null;
                    if (!hasContours)
                    {
                        continue;
                    }

                    //HAS CONTOURS - SET COLOR BYTES IN MATRIX
                    foreach (var slice in comatch.GetSelector().ContourSequence.Items)
                    {
                        var contours = slice.GetSelector().ContourData.Data_;
                        if (contours.Count % 3 != 0)
                        {
                            _logger.LogWarning($"Slice for structure {meta.StructureId} has {contours.Count} contour points. Not divisible by 3! Can't process."); continue;
                        }
                        try
                        {
                            var contour = new SliceContourMeta();
                            for (int i = 0; i < contours.Count; i += 3)
                            {
                                var contourPt = new OpenCvSharp.Point3f((float)contours[i + 0], (float)contours[i + 1], (float)contours[i + 2]);
                                contour.AddPoint(contourPt);
                            }
                            meta.SliceContours.Add(contour);
                            meta.DICOMType = dicomType;
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(e.ToString());
                        }
                    }

                    //OrganizeContours - contours containing other contours (holes and fills) will be organized
                    //into children. All other contours are outermost contours and not children of any other
                    var slices = meta.SliceContours.GroupBy(s => s.Z).ToList();
                    foreach (var slice in slices)
                    {
                        var sliceContours = slice.OrderByDescending(s => s.CalculateArea()).ToList();
                        ContourHelper.OrganizeIntoChildren(sliceContours[0], sliceContours.Skip(1));
                    }
                    sm.Structures.Add(meta.StructureId, meta);
                }
                catch (Exception e)
                {
                    _logger.LogError(e, $"Could not add structure {meta.StructureId}");
                }
            }
            return(sm);
        }