RAM and performance improvements

This commit is contained in:
Tiago Conceição
2021-09-23 01:21:02 +01:00
parent bfb45a4f00
commit b8a705ce21
4 changed files with 130 additions and 21 deletions
+8 -4
View File
@@ -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;
}
}
}
+109 -1
View File
@@ -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;
+12 -16
View File
@@ -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);
}