ImageSharp icon indicating copy to clipboard operation
ImageSharp copied to clipboard

Add QuadDistortion to ProjectiveTransformBuilder

Open Socolin opened this issue 1 year ago • 12 comments

Prerequisites

  • [x] I have written a descriptive pull-request title
  • [x] I have verified that there are no overlapping pull-requests open
  • [x] I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules :cop:.
  • [x] I have provided test coverage for my change (where applicable)

Description

Add 2 new methods: PrependQuadDistortion and AppendQuadDistortion to ProjectiveTransformBuilder.

Those method allow to apply a distortion on an image by specifying the requested coordinate for each corner.

Example:

using (var img1 = Image.Load("cat-original.png"))
{
	var topLeft = new Point(25, 25);
	var topRight = new Point(200, 75);
	var bottomRight = new Point(225, 175);
	var bottomLeft = new Point(38, 225);

	img1.Mutate(c => c.Transform(new ProjectiveTransformBuilder()
		.AppendQuadDistort(topLeft, topRight, bottomRight, bottomLeft)));
	img1.Save("output-small2.png");
}

Source image Result image

Socolin avatar Jun 08 '24 02:06 Socolin

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Jun 08 '24 02:06 CLAassistant

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

CLAassistant avatar Jun 08 '24 02:06 CLAassistant

Thanks @Socolin for this, it is very interesting! I'll have to put my math's hat on to look at this.

I'm curious. Is this potentially an alternative (better) approach to ProjectiveTransformBuilder.PrependTaper?

JimBobSquarePants avatar Jun 11 '24 04:06 JimBobSquarePants

FYI: The performance test I did

TestPerformanceGaussianElimination.zip

  • Matrix is using MathNet.Numerics Nuget
  • MatrixCustom is the implementation included in this PR
  • MatrixCustomFloat is the same implementation with float instead of a generic
  • Matrix8x8 is using TNumber[,] instead of TNumber[][] with static size of 8x8

BenchmarkDotNet v0.13.12, Ubuntu 22.04.4 LTS (Jammy Jellyfish)
AMD Ryzen 9 7950X, 1 CPU, 32 logical and 16 physical cores
.NET SDK 8.0.302
  [Host]     : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
  DefaultJob : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI


| Method            | Mean     | Error   | StdDev  |
|------------------ |---------:|--------:|--------:|
| Matrix            | 526.6 ns | 1.02 ns | 0.96 ns |
| MatrixCustom      | 237.0 ns | 3.31 ns | 3.09 ns |
| MatrixCustomFloat | 234.1 ns | 4.64 ns | 4.34 ns |
| Matrix8x8         | 293.5 ns | 0.32 ns | 0.28 ns |

Socolin avatar Jul 10 '24 22:07 Socolin

@Socolin I'll see if I can find some time over the next few days to pull down your fork and help reimplement it into the latest codebase. I'm keen to add this functionality.

JimBobSquarePants avatar Jul 31 '24 13:07 JimBobSquarePants

@Socolin I'll see if I can find some time over the next few days to pull down your fork and help reimplement it into the latest codebase. I'm keen to add this functionality.

I finally have some time again. I'll push changes related to the today. If it's easier for you to take over this PR, feel free to do it :)

Socolin avatar Jul 31 '24 17:07 Socolin

I rebased the branch and pushed the changes

Socolin avatar Jul 31 '24 22:07 Socolin

I just saw I'm getting an error because ProjectiveTransformBuilder Append take 2 arguments now, should this be computed twice ? Since this operation is taking some processing time, I'm not sure about what to do here.

Socolin avatar Jul 31 '24 22:07 Socolin

I just saw I'm getting an error because ProjectiveTransformBuilder Append take 2 arguments now, should this be computed twice ? Since this operation is taking some processing time, I'm not sure about what to do here.

The operation takes nanoseconds so I'm not concerned by that.

JimBobSquarePants avatar Aug 01 '24 11:08 JimBobSquarePants

Hi @Socolin would it be possible for you to give me full write access to your fork so I can complete this PR for you?

There's a known issue with Git LFS and GitHub which means I cannot update the reference images without full write access.

Thanks!

JimBobSquarePants avatar Oct 16 '24 11:10 JimBobSquarePants

I did grant you access to the repo, can you confirm it's all right ?

Socolin avatar Oct 16 '24 14:10 Socolin

I did grant you access to the repo, can you confirm it's all right ?

Perfect. Thank you!

JimBobSquarePants avatar Oct 16 '24 21:10 JimBobSquarePants

I think this is good to go now. Thanks @Socolin for submitting the solution for this. It's a fantastic addition to the library!

JimBobSquarePants avatar Oct 21 '24 10:10 JimBobSquarePants