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]); } }
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); }
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]); } } }
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)); }