mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-09 01:52:32 +02:00
RAM and performance improvements
This commit is contained in:
@@ -210,6 +210,12 @@ namespace UVtools.Core.EmguCV
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if two contours intersects
|
||||
/// </summary>
|
||||
/// <param name="contour1">Contour 1</param>
|
||||
/// <param name="contour2">Contour 2</param>
|
||||
/// <returns></returns>
|
||||
public static bool ContoursIntersect(VectorOfVectorOfPoint contour1, VectorOfVectorOfPoint contour2)
|
||||
{
|
||||
var contour1Rect = CvInvoke.BoundingRectangle(contour1[0]);
|
||||
@@ -228,16 +234,14 @@ namespace UVtools.Core.EmguCV
|
||||
|
||||
using var contour1Mat = EmguExtensions.InitMat(totalRect.Size);
|
||||
using var contour2Mat = EmguExtensions.InitMat(totalRect.Size);
|
||||
using var overlapCheck = EmguExtensions.InitMat(totalRect.Size);
|
||||
|
||||
var inverseOffset = new Point(minX * -1, minY * -1);
|
||||
CvInvoke.DrawContours(contour1Mat, contour1, -1, EmguExtensions.WhiteColor, -1, Emgu.CV.CvEnum.LineType.EightConnected, null, int.MaxValue, inverseOffset);
|
||||
CvInvoke.DrawContours(contour2Mat, contour2, -1, EmguExtensions.WhiteColor, -1, Emgu.CV.CvEnum.LineType.EightConnected, null, int.MaxValue, inverseOffset);
|
||||
|
||||
CvInvoke.BitwiseAnd(contour1Mat, contour2Mat, overlapCheck);
|
||||
|
||||
return CvInvoke.CountNonZero(overlapCheck) > 0;
|
||||
CvInvoke.BitwiseAnd(contour1Mat, contour2Mat, contour1Mat);
|
||||
|
||||
return contour1Mat.FindFirstPositivePixel() != -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,6 +527,114 @@ namespace UVtools.Core.Extensions
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Find methods
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first negative (Black) pixel
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstNegativePixel(this Mat mat)
|
||||
{
|
||||
return mat.FindFirstPixelEqualTo(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first positive pixel
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPositivePixel(this Mat mat)
|
||||
{
|
||||
return mat.FindFirstPixelEqualOrGreaterThan(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first pixel that is <see cref="value"/>
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPixelEqualTo(this Mat mat, byte value)
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] == value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first pixel that is at less than <see cref="value"/>
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPixelLessThan(this Mat mat, byte value)
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] < value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first pixel that is at less or equal than <see cref="value"/>
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPixelEqualOrLessThan(this Mat mat, byte value)
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] <= value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first pixel that is at greater than <see cref="value"/>
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPixelGreaterThan(this Mat mat, byte value)
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] > value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first pixel that is at equal or greater than <see cref="value"/>
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Pixel position in the span, or -1 if not found</returns>
|
||||
public static int FindFirstPixelEqualOrGreaterThan(this Mat mat, byte value)
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] >= value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Transform methods
|
||||
public static void Transform(this Mat src, double xScale, double yScale, double xTrans = 0, double yTrans = 0, Size dstSize = default, Inter interpolation = Inter.Linear)
|
||||
{
|
||||
@@ -1009,7 +1117,7 @@ namespace UVtools.Core.Extensions
|
||||
|
||||
// if there are no more 'white' pixels in the image, then
|
||||
// break from the loop
|
||||
if (CvInvoke.CountNonZero(image) == 0) break;
|
||||
if (image.FindFirstPixelEqualOrGreaterThan(1) == -1) break;
|
||||
}
|
||||
|
||||
return skeleton;
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace UVtools.Core.Extensions
|
||||
{
|
||||
public static double FindLength(Point start, Point end) => Math.Sqrt(Math.Pow(end.Y - start.Y, 2) + Math.Pow(end.X - start.X, 2));
|
||||
|
||||
public static bool IsAnyNegative(this Point point) => point.X < 0 || point.Y < 0;
|
||||
public static bool IsBothNegative(this Point point) => point.X < 0 && point.Y < 0;
|
||||
public static bool IsBothZeroOrPositive(this Point point) => point.X >= 0 && point.Y >= 0;
|
||||
|
||||
|
||||
@@ -606,12 +606,12 @@ namespace UVtools.Core.Managers
|
||||
{
|
||||
if (matCache[layerIndex] is not null) return;
|
||||
int fromLayerIndex = (int)layerIndex;
|
||||
int toLayerIndex = (int)Math.Min(SlicerFile.LayerCount, layerIndex + Environment.ProcessorCount * 10 + 1);
|
||||
int toLayerIndex = (int)Math.Min(SlicerFile.LayerCount, layerIndex + 1 + Environment.ProcessorCount * 5);
|
||||
|
||||
if (!direction)
|
||||
{
|
||||
toLayerIndex = fromLayerIndex + 1;
|
||||
fromLayerIndex = (int)Math.Max(resinTrapConfig.StartLayerIndex, fromLayerIndex - Environment.ProcessorCount * 10);
|
||||
fromLayerIndex = (int)Math.Max(resinTrapConfig.StartLayerIndex, fromLayerIndex - Environment.ProcessorCount * 5);
|
||||
}
|
||||
|
||||
Parallel.For(fromLayerIndex, toLayerIndex,
|
||||
@@ -899,7 +899,6 @@ namespace UVtools.Core.Managers
|
||||
resinTraps[layerIndex] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,9 +1030,8 @@ namespace UVtools.Core.Managers
|
||||
var overlappingGroupIndexes = new List<int>();
|
||||
for (var x = 0; x < suctionGroups.Count; x++)
|
||||
{
|
||||
if (suctionGroups[x].Last().LayerIndex != layerIndex + 1) continue;
|
||||
|
||||
using var vec = new VectorOfVectorOfPoint(suctionGroups[x].Last().Contours);
|
||||
if (suctionGroups[x][^1].LayerIndex != layerIndex + 1) continue;
|
||||
using var vec = new VectorOfVectorOfPoint(suctionGroups[x][^1].Contours);
|
||||
if (EmguContours.ContoursIntersect(trap, vec))
|
||||
{
|
||||
overlappingGroupIndexes.Add(x);
|
||||
@@ -1103,25 +1101,23 @@ namespace UVtools.Core.Managers
|
||||
|
||||
public MainIssue[] DrillSuctionCupsForIssues(IEnumerable<MainIssue> issues, int ventHoleDiameter, OperationProgress progress)
|
||||
{
|
||||
(bool canDrill, Point location) GetDrillLocation(IssueOfContours issue, int diameter)
|
||||
Point GetDrillLocation(IssueOfContours issue, int diameter)
|
||||
{
|
||||
using var vecCentroid = new VectorOfPoint(issue.Contours[0]);
|
||||
var centroid = EmguContour.GetCentroid(vecCentroid);
|
||||
if (centroid.IsAnyNegative()) return centroid;
|
||||
using var circleCheck = EmguExtensions.InitMat(issue.BoundingRectangle.Size);
|
||||
using var contourMat = EmguExtensions.InitMat(issue.BoundingRectangle.Size);
|
||||
using var overlapCheck = EmguExtensions.InitMat(issue.BoundingRectangle.Size);
|
||||
|
||||
var inverseOffset = new Point(issue.BoundingRectangle.X * -1, issue.BoundingRectangle.Y * -1);
|
||||
using var vec = new VectorOfVectorOfPoint(issue.Contours);
|
||||
CvInvoke.DrawContours(contourMat, vec, -1, EmguExtensions.WhiteColor, -1, LineType.EightConnected, null, int.MaxValue, inverseOffset);
|
||||
|
||||
CvInvoke.Circle(circleCheck, new(centroid.X + inverseOffset.X, centroid.Y + inverseOffset.Y), diameter, EmguExtensions.WhiteColor, -1);
|
||||
CvInvoke.BitwiseAnd(circleCheck, contourMat, circleCheck);
|
||||
|
||||
CvInvoke.BitwiseAnd(circleCheck, contourMat, overlapCheck);
|
||||
|
||||
return CvInvoke.CountNonZero(overlapCheck) > 0
|
||||
? (true, centroid) /* 5px centroid is inside layer! drill baby drill */
|
||||
: (false, new Point()); /* centroid is not inside the actual contour, no drill */
|
||||
return circleCheck.FindFirstPositivePixel() != -1
|
||||
? centroid /* 5px centroid is inside layer! drill baby drill */
|
||||
: new Point(-1,-1); /* centroid is not inside the actual contour, no drill */
|
||||
}
|
||||
|
||||
var drillOps = new List<PixelOperation>();
|
||||
@@ -1131,8 +1127,8 @@ namespace UVtools.Core.Managers
|
||||
foreach (var mainIssue in issues)
|
||||
{
|
||||
var drillPoint = GetDrillLocation((IssueOfContours)mainIssue[0], ventHoleDiameter);
|
||||
if (!drillPoint.canDrill) continue;
|
||||
drillOps.Add(new PixelDrainHole(mainIssue.StartLayerIndex, drillPoint.location, (ushort)ventHoleDiameter));
|
||||
if (drillPoint.IsAnyNegative()) continue;
|
||||
drillOps.Add(new PixelDrainHole(mainIssue.StartLayerIndex, drillPoint, (ushort)ventHoleDiameter));
|
||||
drilledIssues.Add(mainIssue);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user