Yes, ImageTransformations.jl currently just allows you to apply transformations, not fit them - this would be a nice addition to the package. Your function can be sped up with static arrays (and by rewriting the rref to use \
to solve the linear equation):
using StaticArrays
function perspective_transform_SA(
((x1, y1), (x2, y2), (x3, y3), (x4, y4)),
((X1, Y1), (X2, Y2), (X3, Y3), (X4, Y4)))
m = SA_F64[
x1 y1 1 0 0 0 0 0 -X1 0 0 0
x2 y2 1 0 0 0 0 0 0 -X2 0 0
x3 y3 1 0 0 0 0 0 0 0 -X3 0
x4 y4 1 0 0 0 0 0 0 0 0 -X4
0 0 0 x1 y1 1 0 0 -Y1 0 0 0
0 0 0 x2 y2 1 0 0 0 -Y2 0 0
0 0 0 x3 y3 1 0 0 0 0 -Y3 0
0 0 0 x4 y4 1 0 0 0 0 0 -Y4
0 0 0 0 0 0 x1 y1 -1 0 0 0
0 0 0 0 0 0 x2 y2 0 -1 0 0
0 0 0 0 0 0 x3 y3 0 0 -1 0
0 0 0 0 0 0 x4 y4 0 0 0 -1
]
v = SA_F64[0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1]
values = m \ v
SA[
values[1] values[2] values[3]
values[4] values[5] values[6]
values[7] values[8] 1
]
end
julia> @btime perspective_transform(((0, 0), (0, 100), (100, 0), (100, 100)),
((333, 333), (345,600), (555, 346), (610, 600)))
3.288 μs (59 allocations: 7.95 KiB)
3×3 Matrix{Float64}:
2.50406 -0.476459 333.0
0.307087 1.63268 333.0
0.000511811 -0.00172887 1.0
julia> @btime perspective_transform_SA(((0, 0), (0, 100), (100, 0), (100, 100)),
((333, 333), (345,600), (555, 346), (610, 600)))
718.519 ns (0 allocations: 0 bytes)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
2.50406 -0.476459 333.0
0.307087 1.63268 333.0
0.000511811 -0.00172887 1.0
At 718 ns per transform, that’s 1.4 million transforms per second. If you only need 400 transforms per second, this won’t be your limiting factor.