Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'UVtools.Core/Layer/LayerManager.cs')
-rw-r--r--UVtools.Core/Layer/LayerManager.cs224
1 files changed, 119 insertions, 105 deletions
diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs
index 666a7ee..8efaa9e 100644
--- a/UVtools.Core/Layer/LayerManager.cs
+++ b/UVtools.Core/Layer/LayerManager.cs
@@ -684,149 +684,163 @@ namespace UVtools.Core
islandsFinished = true;
return;
}
+
// Detect contours
Parallel.ForEach(this,
//new ParallelOptions{MaxDegreeOfParallelism = 1},
layer =>
{
if (progress.Token.IsCancellationRequested) return;
- using (var image = layer.LayerMat)
+ if (layer.NonZeroPixelCount > 0)
{
- int step = image.Step;
- var span = image.GetPixelSpan<byte>();
-
- // TouchingBounds Checker
- List<Point> pixels = new List<Point>();
- for (int x = 0; x < image.Width; x++) // Check Top and Bottom bounds
+ using (var image = layer.LayerMat)
{
- if (span[x] >= minTouchingBondsPixelColor) // Top
- {
- pixels.Add(new Point(x, 0));
- }
+ int step = image.Step;
+ var span = image.GetPixelSpan<byte>();
- if (span[step * image.Height - step + x] >= minTouchingBondsPixelColor) // Bottom
+ // TouchingBounds Checker
+ List<Point> pixels = new List<Point>();
+ for (int x = 0; x < image.Width; x++) // Check Top and Bottom bounds
{
- pixels.Add(new Point(x, image.Height - 1));
+ if (span[x] >= minTouchingBondsPixelColor) // Top
+ {
+ pixels.Add(new Point(x, 0));
+ }
+
+ if (span[step * image.Height - step + x] >= minTouchingBondsPixelColor) // Bottom
+ {
+ pixels.Add(new Point(x, image.Height - 1));
+ }
}
- }
- for (int y = 0; y < image.Height; y++) // Check Left and Right bounds
- {
- if (span[y * step] >= minTouchingBondsPixelColor) // Left
+ for (int y = 0; y < image.Height; y++) // Check Left and Right bounds
{
- pixels.Add(new Point(0, y));
+ if (span[y * step] >= minTouchingBondsPixelColor) // Left
+ {
+ pixels.Add(new Point(0, y));
+ }
+
+ if (span[y * step + step - 1] >= minTouchingBondsPixelColor) // Right
+ {
+ pixels.Add(new Point(step - 1, y));
+ }
}
- if (span[y * step + step - 1] >= minTouchingBondsPixelColor) // Right
+ if (pixels.Count > 0)
{
- pixels.Add(new Point(step - 1, y));
+ result.TryAdd(layer.Index, new List<LayerIssue>
+ {
+ new LayerIssue(layer, LayerIssue.IssueType.TouchingBound, pixels.ToArray())
+ });
}
- }
- if (pixels.Count > 0)
- {
- result.TryAdd(layer.Index, new List<LayerIssue>
- {
- new LayerIssue(layer, LayerIssue.IssueType.TouchingBound, pixels.ToArray())
- });
- }
+ if (layer.Index == 0) return; // No islands for layer 0
-
- if (layer.Index == 0) return; // No islands for layer 0
+ VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
+ Mat hierarchy = new Mat();
- VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
- Mat hierarchy = new Mat();
-
- if (islandConfig.BinaryThreshold > 0)
- {
- using (var thresholdImage = new Mat())
+ if (islandConfig.BinaryThreshold > 0)
{
- CvInvoke.Threshold(image, thresholdImage, 1, 255, ThresholdType.Binary);
- CvInvoke.FindContours(thresholdImage, contours, hierarchy, RetrType.Ccomp,
- ChainApproxMethod.ChainApproxSimple);
+ using (var thresholdImage = new Mat())
+ {
+ CvInvoke.Threshold(image, thresholdImage, 1, 255, ThresholdType.Binary);
+ CvInvoke.FindContours(thresholdImage, contours, hierarchy, RetrType.Ccomp,
+ ChainApproxMethod.ChainApproxSimple);
+ }
}
- }
- else
- {
- CvInvoke.FindContours(image, contours, hierarchy, RetrType.Ccomp,
- ChainApproxMethod.ChainApproxSimple);
- }
-
- var arr = hierarchy.GetData();
- //
- //hierarchy[i][0]: the index of the next contour of the same level
- //hierarchy[i][1]: the index of the previous contour of the same level
- //hierarchy[i][2]: the index of the first child
- //hierarchy[i][3]: the index of the parent
- //
-
- Mat previousImage = null;
- Span<byte> previousSpan = null;
- for (int i = 0; i < contours.Size; i++)
- {
-
- if ((int) arr.GetValue(0, i, 2) == -1 && (int) arr.GetValue(0, i, 3) != -1) continue;
- var rect = CvInvoke.BoundingRectangle(contours[i]);
- if (rect.GetArea() < islandConfig.RequiredAreaToProcessCheck)
- continue;
-
- if (ReferenceEquals(previousImage, null))
+ else
{
- previousImage = this[layer.Index - 1].LayerMat;
- previousSpan = previousImage.GetPixelSpan<byte>();
+ CvInvoke.FindContours(image, contours, hierarchy, RetrType.Ccomp,
+ ChainApproxMethod.ChainApproxSimple);
}
-
- List<Point> points = new List<Point>();
- uint pixelsSupportingIsland = 0;
- using (Mat contourImage = image.CloneBlank())
+ var arr = hierarchy.GetData();
+ //
+ //hierarchy[i][0]: the index of the next contour of the same level
+ //hierarchy[i][1]: the index of the previous contour of the same level
+ //hierarchy[i][2]: the index of the first child
+ //hierarchy[i][3]: the index of the parent
+ //
+
+ Mat previousImage = null;
+ Span<byte> previousSpan = null;
+ for (int i = 0; i < contours.Size; i++)
{
- CvInvoke.DrawContours(contourImage, contours, i, new MCvScalar(255), -1);
- var contourImageSpan = contourImage.GetPixelSpan<byte>();
- for (int y = rect.Y; y < rect.Bottom; y++)
+ if ((int) arr.GetValue(0, i, 2) == -1 && (int) arr.GetValue(0, i, 3) != -1)
+ continue;
+ var rect = CvInvoke.BoundingRectangle(contours[i]);
+ if (rect.GetArea() < islandConfig.RequiredAreaToProcessCheck)
+ continue;
+
+ if (ReferenceEquals(previousImage, null))
{
- for (int x = rect.X; x < rect.Right; x++)
- {
- int pixel = step * y + x;
- if (span[pixel] < islandConfig.RequiredPixelBrightnessToProcessCheck)
- continue; // Low brightness, ignore
- if (contourImageSpan[pixel] != 255)
- continue; // Not inside contour, ignore
+ previousImage = this[layer.Index - 1].LayerMat;
+ previousSpan = previousImage.GetPixelSpan<byte>();
+ }
- //if (CvInvoke.PointPolygonTest(contours[i], new PointF(x, y), false) < 0) continue; // Out of contour SLOW!
- //Debug.WriteLine($"Layer: {layer.Index}, Coutour: {i}, X:{x} Y:{y}");
- points.Add(new Point(x, y));
+ List<Point> points = new List<Point>();
+ uint pixelsSupportingIsland = 0;
- if (previousSpan[pixel] >= islandConfig.RequiredPixelBrightnessToSupport)
+ using (Mat contourImage = image.CloneBlank())
+ {
+ CvInvoke.DrawContours(contourImage, contours, i, new MCvScalar(255), -1);
+ var contourImageSpan = contourImage.GetPixelSpan<byte>();
+
+ for (int y = rect.Y; y < rect.Bottom; y++)
+ {
+ for (int x = rect.X; x < rect.Right; x++)
{
- pixelsSupportingIsland++;
+ int pixel = step * y + x;
+ if (span[pixel] < islandConfig.RequiredPixelBrightnessToProcessCheck)
+ continue; // Low brightness, ignore
+ if (contourImageSpan[pixel] != 255)
+ continue; // Not inside contour, ignore
+
+ //if (CvInvoke.PointPolygonTest(contours[i], new PointF(x, y), false) < 0) continue; // Out of contour SLOW!
+ //Debug.WriteLine($"Layer: {layer.Index}, Coutour: {i}, X:{x} Y:{y}");
+ points.Add(new Point(x, y));
+
+ if (previousSpan[pixel] >=
+ islandConfig.RequiredPixelBrightnessToSupport)
+ {
+ pixelsSupportingIsland++;
+ }
}
}
}
- }
-
- if (points.Count == 0) continue;
- if (pixelsSupportingIsland >= islandConfig.RequiredPixelsToSupport)
- continue; // Not a island, bounding is strong, i think...
- if (pixelsSupportingIsland > 0 && points.Count < islandConfig.RequiredPixelsToSupport &&
- pixelsSupportingIsland >= Math.Max(1, points.Count / 2))
- continue; // Not a island, but maybe weak bounding...
+ if (points.Count == 0) continue;
+ if (pixelsSupportingIsland >= islandConfig.RequiredPixelsToSupport)
+ continue; // Not a island, bounding is strong, i think...
+ if (pixelsSupportingIsland > 0 &&
+ points.Count < islandConfig.RequiredPixelsToSupport &&
+ pixelsSupportingIsland >= Math.Max(1, points.Count / 2))
+ continue; // Not a island, but maybe weak bounding...
- var issue = new LayerIssue(layer, LayerIssue.IssueType.Island, points.ToArray(), rect);
- result.AddOrUpdate(layer.Index, new List<LayerIssue> {issue},
- (layerIndex, list) =>
- {
- list.Add(issue);
- return list;
- });
- }
- contours.Dispose();
- hierarchy.Dispose();
- previousImage?.Dispose();
+ var issue = new LayerIssue(layer, LayerIssue.IssueType.Island, points.ToArray(),
+ rect);
+ result.AddOrUpdate(layer.Index, new List<LayerIssue> {issue},
+ (layerIndex, list) =>
+ {
+ list.Add(issue);
+ return list;
+ });
+ }
+
+ contours.Dispose();
+ hierarchy.Dispose();
+ previousImage?.Dispose();
+ }
+ }
+ else
+ {
+ result.TryAdd(layer.Index, new List<LayerIssue>
+ {
+ new LayerIssue(layer, LayerIssue.IssueType.EmptyLayer)
+ });
}
lock (progress.Mutex)