CoordinateTransformations.jl
CoordinateTransformations.jl copied to clipboard
Help with projective transform
Hi! I'm trying to implement a function that will calculate the projective transformation from a bunch of projected coordinates and their corresponding real world values. This is just another (equally relevant) way of creating a projective transformation (other than with the cam_rotation and cam_position).
The following has been inspired by matlab's version for the same task (nothing revolutionary):
function findProjectiveTransform(uv::Vector{T},xy::Vector{T}) where T <: AbstractArray
M = length(xy)
@assert length(uv) == M "same number of coordinates needed"
@assert M > 3 "at least 4 coordinates required"
X = zeros(2M,8)
for i = 1:M
X[i,1:2] .= xy[i]
X[i,3] = 1
X[i,7:8] .= -first(uv[i])*xy[i]
end
for i = 1:M
X[i+M,4:5] .= xy[i]
X[i+M,6] = 1
X[i+M,7:8] .= -last(uv[i])*xy[i]
end
U = vec(cat(2, uv...)')
Tvec = X\U
push!(Tvec, 1)
return LinearMap(reshape(Tvec, 3, 3))
end
Can you guys help me understand what I'm doing wrong with that final step? I think this could be a great addition to this package.
Cool - interesting problem. Sorry I've been too busy to check this out in detail yet.
No worries!
Yea, there's tons to be found in Peter Kovesi's ImageProjectiveGeometry.jl and Matlab. Feels though that this functionality, while probably most useful in image calibration, fits here, at least the coordinates part (leaving any actual image registration and warping to Images.jl.
I think a good place to start (other than the code in the beginning of this feature-request issue, is line 972 in ImageProjectiveGeometry.jl.
http://users.ics.forth.gr/~lourakis/posest/
Wow, cool..! Now all we need to do is convince Manolis Lourakis to contribute to Julia (or use his library).
I think Lourakis work is excellent .. I would love to see lev-mar sba and pose-est wrappers for Julia, I don't think it is necessary to port it.
Specifically for pose-est we use it directly using ccall
using StaticArrays,Rotations
Libdl.dlopen("PoseEst.dll")
const POSEST_REPR_ERR_NO_NLN_REFINE = 0 # reprojection error without non-linear refinement */
const POSEST_REPR_ERR_NLN_REFINE = 1 # reprojection error with non-linear refinement */
const POSEST_REPR_ERR_NLN_MLSL_REFINE = 2 # reprojection error with non-linear refinement & multistart scheme */
const POSEST_OBJSPC_ERR_LHM = 3
const d2 = SVector{2,Float64}
const d3 = SVector{3,Float64}
function pose_est(pts2D::Vector{d2}, pts3D::Vector{d3}, K::SMatrix{3,3,Float64})
nmatches = length(pts2D);
inlPcent=0.8
pp = zeros(6)
npp = 6
NLrefine = POSEST_REPR_ERR_NLN_REFINE
idxOutliers = Vector{Int32}(nmatches)
nbOutliers = Ref{Int32}(0)
verbose = 0
Ktag = Matrix{Float64}(K') # C is row_major
ret = ccall( (:posest,:PoseEst) , Int32,(Ptr{d2},Ptr{d3},Int32,Float64,Ptr{Float64},
Ptr{Float64},Int32,Int32,Ptr{Int32},Ref{Int32},Int32),
pts2D,pts3D,nmatches,inlPcent,Ktag,pp,npp,NLrefine,
idxOutliers,nbOutliers,verbose )
R = RodriguesVec(pp[1],pp[2],pp[3])
T = SVector{3}(pp[4],pp[5],pp[6])
return SMatrix{4,4,Float32,16}([R T;[0 0 0 1]])
end
export pose_est
Fantastic! I wish I could improve my wrapping skills, especially now with the holiday season 😉
Not sure how the maintainers of CoordinateTransformations.jl would feel about wrappers of these functionalities in their package..
@TsurHerman sorry for necroposting. I just discovered this thread. Can you explain how you obtained a shared library version of posest? My C compiling skills are a little rusty and it seems posest produces statically linked output by default.
@jw3126 download the source file from the author web site put all relevant files in the same directory ( don't bother compiling the Matlab interface part) and just call gcc with the list of .c files ( I think you can skip mlsl) and add the -shared flag to the compile command.
It will still complain abut missing symbols , you need to have openBLAS or MKL installed somewhere and you'll need to specify it on the command line using -lopenblas or -lmkl
@TsurHerman thanks! It mostly worked, I needed to omit all the *_core.c files and include a couple of headers as well. The error messages were good enough to figure this out. There is still some problem with missing _gemm probably I did not link openblas correctly?
Yes you are probably correct , you did not link openblas correctly. Try removing the -lopenblas and see if there are more missing symbols(if yes then it will indicate that actually you did link properly but maybe a weird version)