CoordinateTransformations.jl icon indicating copy to clipboard operation
CoordinateTransformations.jl copied to clipboard

Help with projective transform

Open yakir12 opened this issue 8 years ago • 11 comments

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.

yakir12 avatar Nov 03 '17 16:11 yakir12

Cool - interesting problem. Sorry I've been too busy to check this out in detail yet.

andyferris avatar Nov 06 '17 06:11 andyferris

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.

yakir12 avatar Nov 06 '17 08:11 yakir12

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.

yakir12 avatar Nov 06 '17 08:11 yakir12

http://users.ics.forth.gr/~lourakis/posest/

TsurHerman avatar Dec 20 '17 09:12 TsurHerman

Wow, cool..! Now all we need to do is convince Manolis Lourakis to contribute to Julia (or use his library).

yakir12 avatar Dec 20 '17 10:12 yakir12

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

TsurHerman avatar Dec 20 '17 12:12 TsurHerman

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..

yakir12 avatar Dec 20 '17 12:12 yakir12

@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 avatar Apr 08 '19 12:04 jw3126

@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 avatar Apr 11 '19 11:04 TsurHerman

@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?

jw3126 avatar Apr 12 '19 19:04 jw3126

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)

TsurHerman avatar Apr 13 '19 06:04 TsurHerman