diff --git a/.travis.yml b/.travis.yml index 94fafb7..9f71b63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ notifications: email: false script: - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi + - julia -e 'Pkg.clone("https://github.com/wildart/FLANN.jl"); Pkg.build("FLANN")' - julia -e 'Pkg.clone(pwd()); Pkg.build("ImageFeatures")' # used in tests and Documentation (just install once) - julia -e 'Pkg.add("TestImages")' diff --git a/REQUIRE b/REQUIRE index 58e10fa..18f973d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -4,3 +4,5 @@ Images 0.6 Distributions 0.12 FixedPointNumbers 0.3 Compat 0.17 +FLANN +Distances diff --git a/appveyor.yml b/appveyor.yml index a939d2c..04ca762 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,6 +28,7 @@ build_script: # Need to convert from shallow to complete for Pkg.clone to work - IF EXIST .git\shallow (git fetch --unshallow) - C:\projects\julia\bin\julia -e "versioninfo(); + Pkg.clone("https://github.com/wildart/FLANN.jl"); Pkg.build("FLANN"); Pkg.clone(pwd(), \"ImageFeatures\"); Pkg.build(\"ImageFeatures\")" test_script: diff --git a/src/ImageFeatures.jl b/src/ImageFeatures.jl index 8063d9a..267eaf9 100644 --- a/src/ImageFeatures.jl +++ b/src/ImageFeatures.jl @@ -5,6 +5,9 @@ module ImageFeatures # package code goes here using Images, ColorTypes, FixedPointNumbers, Distributions using Compat +if !is_windows() || Sys.WORD_SIZE!=32 + using FLANN, Distances +end include("core.jl") include("const.jl") diff --git a/src/core.jl b/src/core.jl index b991ac7..618175a 100644 --- a/src/core.jl +++ b/src/core.jl @@ -87,6 +87,7 @@ function match_keypoints(keypoints_1::Keypoints, keypoints_2::Keypoints, desc_1, s_key = keypoints_1 l_key = keypoints_2 order = false + if length(desc_1) > length(desc_2) smaller = desc_2 larger = desc_1 @@ -94,15 +95,44 @@ function match_keypoints(keypoints_1::Keypoints, keypoints_2::Keypoints, desc_1, l_key = keypoints_1 order = true end - hamming_distances = [hamming_distance(s, l) for s in smaller, l in larger] + matches = Keypoints[] - for i in 1:length(smaller) - if any(hamming_distances[i, :] .< threshold) - id_min = indmin(hamming_distances[i, :]) - push!(matches, order ? [l_key[id_min], s_key[i]] : [s_key[i], l_key[id_min]]) - hamming_distances[:, id_min] = 1.0 + + if is_windows() && Sys.WORD_SIZE==32 + hamming_distances = [hamming_distance(s, l) for s in smaller, l in larger] + for i in 1:length(smaller) + if any(hamming_distances[i, :] .< threshold) + id_min = indmin(hamming_distances[i, :]) + push!(matches, order ? [l_key[id_min], s_key[i]] : [s_key[i], l_key[id_min]]) + hamming_distances[:, id_min] = 1.0 + end + end + else + ndims=length(larger[1]) + n_large=length(larger) + n_small=length(smaller) + data=Matrix{Float64}(ndims, n_large); + for i in 1:ndims + for j in 1:n_large + data[i,j]=larger[j][i]?1:0 + end + end + + tree = flann(data, FLANNParameters(), Cityblock()) + matched = zeros(Bool, n_large) + for i in 1:n_small + idx = inrange(tree, Vector{Float64}(smaller[i]), threshold*ndims) + for j in idx[1] + if !matched[j] + id_min = j + push!(matches, order ? [l_key[id_min], s_key[i]] : [s_key[i], l_key[id_min]]) + matched[j] = true + break + end + end end end + matches end