예제 #1
0
        public void FillPolygonTests7()
        {
            var dimX = 5;
            var dimY = 5;

            var expectedArray = new byte[]
            {
                0, 1, 1, 0, 0,
                1, 1, 1, 1, 0,
                1, 1, 1, 1, 1,
                1, 1, 0, 1, 0,
                0, 0, 0, 0, 0,
            };

            var volume2D = new Volume2D <byte>(expectedArray, 5, 5, 1, 1, new Point2D(), new Matrix2());

            var extractContour = ExtractContours.PolygonsFilled(volume2D);

            var output1 = new byte[dimX * dimY];
            var polygon = extractContour.First().Points.Select(x => CreatePoint(x.X + 0.00002, x.Y - 0.00001)).ToArray();

            FillPolygon.Fill(polygon, output1, dimX, dimY, 0, 0, (byte)1);

            for (var i = 0; i < output1.Length; i++)
            {
                Assert.AreEqual(expectedArray[i], output1[i]);
            }
        }
예제 #2
0
        public void FillPolygonTests1()
        {
            // Figure of 8
            var polygon = new[] {
                CreatePoint(2, 1),
                CreatePoint(3, 2),
                CreatePoint(3, 6),
                CreatePoint(3, 6), // Double point - interesting case
                CreatePoint(5, 6),
                CreatePoint(5, 3),
                CreatePoint(2, 4),
                CreatePoint(1, 2),
                CreatePoint(2, 1),
            };

            polygon = polygon.Select(x => CreatePoint(x.X - 0.5, x.Y - 0.5)).ToArray();

            var dimX = 6;
            var dimY = 7;

            var output = new byte[dimX * dimY];

            FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1);

            var resultArray = new byte[]
            {
                0, 0, 0, 0, 0, 0,
                0, 1, 1, 0, 0, 0,
                0, 1, 1, 0, 0, 0,
                0, 0, 1, 1, 1, 0,
                0, 0, 0, 1, 1, 0,
                0, 0, 0, 1, 1, 0,
                0, 0, 0, 0, 0, 0,
            };

            Assert.AreEqual(resultArray.Length, output.Length);

            for (var i = 0; i < output.Length; i++)
            {
                Assert.AreEqual(resultArray[i], output[i]);
            }

            polygon = new[] {
                CreatePoint(0, 0),
                CreatePoint(dimX, 0),
                CreatePoint(dimX, dimY),
                CreatePoint(0, dimY),
                CreatePoint(0, 0),
            };

            polygon = polygon.Select(x => CreatePoint(x.X - 0.5, x.Y - 0.5)).ToArray();

            FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1);

            for (var i = 0; i < output.Length; i++)
            {
                Assert.AreEqual(1, output[i]);
            }
        }
        /// <summary>
        /// Extracts axial contours for the foreground values in the given volume. After extracting the contours,
        /// a check is conducted if the contours truthfully represent the actual volume. This will throw exceptions
        /// for example if the incoming volume has "doughnut shape" structures.
        /// </summary>
        /// <param name="volume">The mask volume to extract contours from.</param>
        /// <param name="maxAbsoluteDifference">The maximum allowed difference in foreground voxels when going
        /// from mask to contours to mask.</param>
        /// <param name="maxRelativeDifference">The maximum allowed relative in foreground voxels (true - rendered)/true
        /// when going from mask to contours to mask.</param>
        /// <returns></returns>
        public static ContoursPerSlice ExtractContoursAndCheck(this Volume3D <byte> volume,
                                                               int?maxAbsoluteDifference    = 10,
                                                               double?maxRelativeDifference = 0.15
                                                               )
        {
            var contours = ExtractContours.ContoursWithHolesPerSlice(
                volume,
                foregroundId: ModelConstants.MaskForegroundIntensity,
                sliceType: SliceType.Axial,
                filterEmptyContours: true,
                regionOfInterest: null,
                axialSmoothingType: ContourSmoothingType.Small);
            var slice = new byte[volume.DimX * volume.DimY];

            void ClearSlice()
            {
                for (var index = 0; index < slice.Length; index++)
                {
                    slice[index] = ModelConstants.MaskBackgroundIntensity;
                }
            }

            foreach (var contourPerSlice in contours)
            {
                var indexZ  = contourPerSlice.Key;
                var offsetZ = indexZ * volume.DimXY;
                ClearSlice();
                foreach (var contour in contourPerSlice.Value)
                {
                    FillPolygon.Fill(contour.ContourPoints, slice,
                                     volume.DimX, volume.DimY, 1, 0, ModelConstants.MaskForegroundIntensity);
                }
                var true1     = 0;
                var rendered1 = 0;
                for (var index = 0; index < slice.Length; index++)
                {
                    if (volume[offsetZ + index] == ModelConstants.MaskForegroundIntensity)
                    {
                        true1++;
                    }
                    if (slice[index] == ModelConstants.MaskForegroundIntensity)
                    {
                        rendered1++;
                    }
                }
                CheckContourRendering(true1, rendered1, maxAbsoluteDifference, maxRelativeDifference, $"Slice z={indexZ}");
            }
            ;

            return(contours);
        }
예제 #4
0
        public void FillPolygonTests2()
        {
            var dimX = 5;
            var dimY = 5;

            var polygon1 = new[] {
                CreatePoint(-0.5, -0.5),
                CreatePoint(dimX + 0.5, -0.5),
                CreatePoint(dimX + 0.5, dimY + 0.5),
                CreatePoint(-0.5, dimY + 0.5)
            };

            var output1 = new byte[dimX * dimY];

            FillPolygon.Fill(polygon1, output1, dimX, dimY, 0, 0, (byte)1);

            for (var i = 0; i < output1.Length; i++)
            {
                Assert.AreEqual(1, output1[i]);
            }

            var polygon = new[] {
                CreatePoint(0.1, 0.1),
                CreatePoint(dimX - 1.1, 0.1),
                CreatePoint(dimX - 1.1, dimY - 1.1),
                CreatePoint(0.1, dimY - 1.1)
            };

            var output = new byte[dimX * dimY];

            FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1);

            for (var y = 0; y < dimY; y++)
            {
                for (var x = 0; x < dimX; x++)
                {
                    Assert.AreEqual(y == 0 || y == dimY - 1 || x == 0 || x == dimX - 1 ? 0 : 1, output[x + y * dimX]);
                }
            }
        }
예제 #5
0
        public void FillPolygonOutsideVolume()
        {
            var dimX = 5;
            var dimY = 5;

            var polygon1 = new[] {
                CreatePoint(-10.5, -10.5), // Check that if a point is outside the volume this code still works
                CreatePoint(dimX + 0.5, -0.5),
                CreatePoint(dimX + 0.5, dimY + 0.5),
                CreatePoint(-0.5, dimY + 0.5)
            };

            var output1 = new byte[dimX * dimY];

            FillPolygon.Fill(polygon1, output1, dimX, dimY, 0, 0, (byte)1);

            for (var i = 0; i < output1.Length; i++)
            {
                Assert.AreEqual(1, output1[i]);
            }

            var polygon = new[] {
                CreatePoint(0.1, 0.1),
                CreatePoint(dimX - 1.1, 0.1),
                CreatePoint(dimX - 1.1, dimY - 1.1),
                CreatePoint(0.1, dimY - 1.1)
            };

            var output = new byte[dimX * dimY];

            FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1);

            for (var y = 0; y < dimY; y++)
            {
                for (var x = 0; x < dimX; x++)
                {
                    Assert.AreEqual(y == 0 || y == dimY - 1 || x == 0 || x == dimX - 1 ? 0 : 1, output[x + y * dimX]);
                }
            }
        }
 /// <summary>
 /// Fills the contour using high accuracy (point in polygon testing).
 /// </summary>
 /// <typeparam name="T">The volume type.</typeparam>
 /// <param name="volume">The volume.</param>
 /// <param name="contourPoints">The points that defines the contour we are filling.</param>
 /// <param name="region">The value we will mark in the volume when a point is within the contour.</param>
 /// <returns>The number of points filled.</returns>
 public static int FillContour <T>(this Volume2D <T> volume, PointF[] contourPoints, T value)
 {
     return(FillPolygon.Fill(contourPoints, volume.Array, volume.DimX, volume.DimY, 0, 0, value));
 }