Skip to content

Commit

Permalink
Use VConcat to improve performance (#7)
Browse files Browse the repository at this point in the history
* initiate benchmark project

* add image stacking benchmark

* improve benchmark

* add memory diagnoser and multi exporter
add benchmark for Net 8.0
add more test images

* benchmark result

* improve performance greatly (30% ~ 44%)

* update benchmark

* update images and benchmark result

* update StackingVertically and ResizePadding

* fix problems

* add unit test, align code.

* update packages.

* Remove benchmark project since it's too specific.

---------

Co-authored-by: Aven <[email protected]>
  • Loading branch information
sdcb and AvenSun authored Nov 29, 2023
1 parent 9bf945d commit 9c59d5b
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 16 deletions.
4 changes: 2 additions & 2 deletions build/00-common.linq
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ static void Run(string exe, string args, Encoding encoding) => Util.Cmd(exe, arg
static ProjectVersion[] Projects = new[]
{
new ProjectVersion("Sdcb.OpenVINO", "0.6.1"),
new ProjectVersion("Sdcb.OpenVINO.Extensions.OpenCvSharp4", "0.2.0"),
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR", "0.5.1"),
new ProjectVersion("Sdcb.OpenVINO.Extensions.OpenCvSharp4", "0.6.1"),
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR", "0.6.1"),
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR.Models.Online", "0.2.1"),
};

Expand Down
14 changes: 14 additions & 0 deletions projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Tests/OnlineRecTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,18 @@ private void RecAsserts(PaddleOcrRecognizer rec, params Mat[] srcs)
Assert.True(result.Score > 0.9);
}
}

[Theory]
[InlineData(27, 294)]
[InlineData(48, 1024)]
[InlineData(30, 512)]
public void ResizePaddingTests(int srcHeight, int srcWidth)
{
int modelHeight = 48;
int targetWidth = 512;
using Mat src = new(srcHeight, srcWidth, MatType.CV_8UC1);
using Mat res = PaddleOcrRecognizer.ResizePadding(src, modelHeight, targetWidth);
Assert.Equal(targetWidth, res.Width);
Assert.Equal(modelHeight, res.Height);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<ItemGroup>
<ProjectReference Include="..\Sdcb.OpenVINO.PaddleOCR.Models.Online\Sdcb.OpenVINO.PaddleOCR.Models.Online.csproj" />
<ProjectReference Include="..\Sdcb.OpenVINO.PaddleOCR\Sdcb.OpenVINO.PaddleOCR.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private Mat PrepareAndStackImages(Mat[] srcs)
return ResizePadding(channel3, Shape);
})
.ToArray();
using Mat combined = normalizeds.StackingVertically(Shape.Height, Shape.Width);
using Mat combined = normalizeds.StackingVertically();
combined.ConvertTo(final, MatType.CV_32FC3, 2.0 / 255, -1.0);
}
finally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ private static unsafe Mat PrepareAndStackImages(Mat[] srcs, int modelHeight, int
return ResizePadding(channel3, modelHeight, maxWidth);
})
.ToArray();
using Mat combined = normalizeds.StackingVertically(modelHeight, maxWidth);
using Mat combined = normalizeds.StackingVertically();
combined.ConvertTo(final, MatType.CV_32FC3, 2.0 / 255, -1.0);
}
finally
Expand All @@ -246,17 +246,16 @@ internal static Mat ResizePadding(Mat src, int modelHeight, int targetWidth)
// Resize image
Mat resized = new();
Cv2.Resize(src, resized, new Size(), scale, scale);

// Compute padding for height and width
int padTop = Math.Max(0, (modelHeight - resized.Height) / 2);
int padH = modelHeight - resized.Height;
int padRight = targetWidth - resized.Width;

if (padTop > 0)
if (padH > 0 || padRight > 0)
{
// Add padding. If padding needs to be added to top and bottom we divide it equally,
// but if there is an odd number we add the extra pixel to the bottom.
Mat result = new();
int remainder = (modelHeight - resized.Height) % 2;
Cv2.CopyMakeBorder(resized, result, padTop, padTop + remainder, 0, 0, BorderTypes.Constant, Scalar.Black);
int padTop = padH / 2;
int padBottom = padH - padTop;
Cv2.CopyMakeBorder(resized, result, padTop, padBottom, 0, padRight, BorderTypes.Constant, Scalar.Black);
resized.Dispose();
return result;
}
Expand Down
3 changes: 3 additions & 0 deletions projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR/Props/Assembly.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Sdcb.OpenVINO.PaddleOCR.Tests")]
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

<PackageReference Include="Sdcb.OpenVINO" Version="0.5.1" Condition="'$(Configuration)' != 'Debug'" />
<PackageReference Include="Sdcb.OpenVINO.Extensions.OpenCvSharp4" Version="0.2.0" Condition="'$(Configuration)' != 'Debug'"/>
<PackageReference Include="Sdcb.OpenVINO" Version="0.6.1" Condition="'$(Configuration)' != 'Debug'" />
<PackageReference Include="Sdcb.OpenVINO.Extensions.OpenCvSharp4" Version="0.6.1" Condition="'$(Configuration)' != 'Debug'" />

<ProjectReference Include="..\..\..\src\Sdcb.OpenVINO\Sdcb.OpenVINO.csproj" Condition="'$(Configuration)' == 'Debug'" />
<ProjectReference Include="..\..\..\src\Sdcb.OpenVINO.Extensions.OpenCvSharp4\Sdcb.OpenVINO.Extensions.OpenCvSharp4.csproj" Condition="'$(Configuration)' == 'Debug'" />
Expand Down
21 changes: 19 additions & 2 deletions src/Sdcb.OpenVINO.Extensions.OpenCvSharp4/MatExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Text;

namespace Sdcb.OpenVINO.Extensions.OpenCvSharp4;

Expand Down Expand Up @@ -86,6 +84,7 @@ public static Mat Padding(Mat src, int padSize = 32, Scalar? color = default)
/// <remarks>
/// This method utilizes OpenCvSharp4 for operations on Mats. Pay attention to match correctly the type of Mats in the 'srcs' array.
/// </remarks>
[Obsolete("You can use another overloading method for better performance.")]
public static Mat StackingVertically(this Mat[] srcs, int height, int width)
{
MatType matType = srcs[0].Type();
Expand All @@ -98,4 +97,22 @@ public static Mat StackingVertically(this Mat[] srcs, int height, int width)
}
return combinedMat;
}

/// <summary>
/// Stacks an array of Mats into a single Mat by placing them vertically.
/// This version of StackingVertically is optimized for speed and requires the Mats to have the same width.
/// </summary>
/// <param name="srcs">An array of Mats that are to be stacked. All Mats must have the same width and type.</param>
/// <returns>Returns a new Mat that is a vertical stack of all input Mats.</returns>
/// <exception cref="OpenCVException">Thrown when the Mats within srcs have differing widths.</exception>
/// <remarks>
/// This method is an optimized version of vertical stacking where it is assumed that all Mats have the same width.
/// It straightly stacks the Mats in the given order, therefore the widths must be consistent to avoid issues.
/// </remarks>
public static Mat StackingVertically(this Mat[] srcs)
{
Mat combinedMat = new();
Cv2.VConcat(srcs, combinedMat);
return combinedMat;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

<ItemGroup>
<ProjectReference Include="..\Sdcb.OpenVINO\Sdcb.OpenVINO.csproj" Condition="'$(Configuration)' == 'Debug'"/>
<PackageReference Include="Sdcb.OpenVINO" Version="0.5.1" Condition="'$(Configuration)' != 'Debug'" />
<PackageReference Include="Sdcb.OpenVINO" Version="0.6.1" Condition="'$(Configuration)' != 'Debug'" />
</ItemGroup>

</Project>

0 comments on commit 9c59d5b

Please sign in to comment.